C#显式运算符和对象
题
请先查看代码. 这是我的自定义类: public class float2D { public float X { get; private set; } public float Y { get; private set; } public float2D(float x,float y) { this.X = x; this.Y = y; } public static explicit operator Point(float2D x) { return new Point((int)x.X,(int)x.Y); } ... } 这是我写的测试代码: private void TEST() { float2D V = new float2D(1,1); Point P = Point.Empty; P = (Point)V; // Works P = (Point)(V as object); // Specified cast is not valid. } 正如您所看到的,当值类型未知时,它无法转换该值.我相信这是因为它在Object类中搜索操作数而不是实际类型.我怎么解决这个问题? 我有一个代码,其中一切都是对象,它必须处理这些对话. 如果您有任何想法,请告诉我. 避免动态 好吧,让我们改变样本的方式,你可以看到我到底想做什么,以及我的情况. 这是我的课程: class TEST { dynamic OBJECT; public void STORE<T>(ref T V) { this.OBJECT = V; } public T CONVERT<T>() { return (T)this.OBJECT; } } 这是测试代码: float2D V = new float2D(1,1); TEST t = new TEST(); t.STORE(ref V); Point P = t.CONVERT<Point>(); 我有没有办法从课堂上放下动力并保持工作?我真的想避免使用.Net4 / 4.5 解决方法
正如其他答案所述,您无法执行此操作,因为您尝试将运行时强制转换应用于编译时间转换操作.
如果您想避免使用动态因为您不想使用.NET 4.0的DLR,则可以使用反射来自行查找转换运算符.但是,无法评论您的特定应用程序的性能: public static TOutgoing Convert<TOutgoing>(object obj) { Type incomingType = obj.GetType(); MethodInfo conversionOperator = null; foreach(var method in incomingType.GetMethods(BindingFlags.Static | BindingFlags.Public)) { if ( method.Name == "op_Explicit" && //explicit converter method.ReturnType == typeof(TOutgoing) && //returns your outgoing ("Point") type method.GetParameters().Length == 1 && //only has 1 input parameter method.GetParameters()[0].ParameterType == incomingType //parameter type matches your incoming ("float2D") type ) { conversionOperator = method; break; } } if (conversionOperator != null) return (TOutgoing)conversionOperator.Invoke(null,new object[]{obj}); throw new Exception("No conversion operator found"); } 或者对于带有LINQ的.NET 3.5: public static TOutgoing Convert<TOutgoing>(object obj) { Type incomingType = obj.GetType(); var conversionOperator = incomingType.GetMethods(BindingFlags.Static | BindingFlags.Public) .Where(m => m.Name == "op_Explicit") .Where(m => m.ReturnType == typeof(TOutgoing)) .Where(m => m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == incomingType) .FirstOrDefault(); if (conversionOperator != null) return (TOutgoing)conversionOperator.Invoke(null,new object[]{obj}); throw new Exception("No conversion operator found"); } 用法: float2D V = new float2D(1,1); Point P = Point.Empty; P = Convert<Point>(V); //passes P = Convert<Point>((V as object)); //passes 如果您希望通过隐式运算符进行转换,也可以添加“op_Implicit”. 如果要避免反射,另一个选项是预先注册转换函数,某些转换和类型查找以确定要使用的转换运算符. 只是一个警告,这里的解决方案有几个问题(线程安全,假设转换函数存在,注册碰撞/重复转换函数会引发错误)所以使用风险或使用它作为指导修改,因为它适合您的需要. 基本要点是定义一个简单的转换器来包装转换函数本身: public interface IConverter { object Convert(object incomingObject); } public class Converter<TIncoming,TOutgoing> : IConverter { private Func<TIncoming,TOutgoing> ConversionFunction; public Converter(Func<TIncoming,TOutgoing> conversionFunction) { this.ConversionFunction = conversionFunction; } public object Convert(object incomingObject) { TIncoming typedIncomingObject = (TIncoming)incomingObject; return ConversionFunction(typedIncomingObject); } } 然后,您可以使用以下命令注册这些转换的实用程序: public static class ConversionUtility { private static Dictionary<Type,Dictionary<Type,IConverter>> Converters = new Dictionary<Type,IConverter>>(); public static void RegisterConversion<TIncoming,TOutgoing>(Func<TIncoming,TOutgoing> conversionFunction) { if (!Converters.ContainsKey(typeof(TIncoming))) { Converters[typeof(TIncoming)] = new Dictionary<Type,IConverter>(); } Converters[typeof(TIncoming)].Add(typeof(TOutgoing),new Converter<TIncoming,TOutgoing>(conversionFunction)); } public static TOutgoing Convert<TOutgoing>(object obj) { Type incomingType = obj.GetType(); IConverter converter = Converters[incomingType][typeof(TOutgoing)]; return (TOutgoing)converter.Convert(obj); } } 对于使用,首先必须注册您希望在应用程序中使用的转换函数(理想情况下,在应用程序启动时执行注册以避免线程问题): ConversionUtility.RegisterConversion((float2D obj) => (Point)obj); 然后你的转换用法: float2D V = new float2D(1,1); Point P = Point.Empty; P = ConversionUtility.Convert<Point>(V); //passes P = ConversionUtility.Convert<Point>((V as object)); //passes 对于您的特定应用程序使用情况,不确定其中一个的性能.第一个示例更灵活,因为它在运行时执行检查,您不必预先注册您希望使用的转换.第二个可能会更稳定,因为您只注册了您期望使用的转换,并且没有反射,只有转换和字典查找. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |