我有我的BusinessObject类的扩展方法:
public static class Extensions { public static T Clone<T>(this T obj) where T: BusinessObject<T>,new() { T newObj = new T(); var props = newObj.Properties; foreach (var p in props) newObj.Properties[p.Name].SetValue(newObj,obj.Properties[p.Name].GetValue(obj)); return newObj; } }
该方法的内容很有用,但我有一个非泛型的BusinessObject类和一个通用的对应类.我的很多代码都在非泛型变量中传递了对象的泛型版本的实例(请不要问我20个关于原因的问题).我到目前为止没有遇到过问题,因为当我调用这个扩展方法时,它需要一个通用版本.
调用Clone方法的代码使用包含BusinessObject变量实例的BusinessObject变量.如何将变量转换为实际变量?换一种说法:
Customer cust = new Customer(); // Customer derives from BusinessObject<Customer> var CustomerClone = cust.Clone(); // This works BusinessObject obj = cust; var clone = obj.Clone(); // This doesn't work
现在当然在这个例子中我知道’obj’是一个Customer,但在我的实际方法中,我不知道它可能是任意数量的派生类型.通过简单地使用GetType(),我可以很容易地找出派生类型是什么,但是如何在运行时将变量转换为该类型?
解决方法
在你的情况下,我会说“失去T” – 你没有用于任何其他方面无法做到的重要事情(例如Activator.CreateInstance).您可以提供两个API – 一个是通用的,一个是非泛型的,以便于方便的转换.例如:
BusinessObject newObj = (BusinessObject)Activator.CreateInstance(obj.GetType());
它也很关键,因为你想要的T实际上不是声明T,而是具体的T.意思是:如果你有一个SuperCustomer:Customer,但是把它放在Customer变量中,然后调用Clone,你想获得一个新的SuperCustomer.然而,T将是客户.使用GetType()会更可靠.
另一个有用的技巧是动态,这是一种从非泛型转向泛型的偷偷摸摸的方式.考虑:
dynamic foo = 123; Bar(foo); void Bar<T>(T bar) { Console.WriteLine(typeof(T)); }
将编写system.int32.尽管只是真正了解编译器中的对象(动态主要是作为对象实现,但有一些奇特的位),它已经动态转换为正确的T.
但是,要强调 – 我不会在这里使用它:我只会:
public static BusinessObject Clone(this BusinessObject obj) { BusinessObject newObj = (BusinessObject) Activator.CreateInstance(obj.GetType()); var props = newObj.Properties; foreach (var p in props) newObj.Properties[p.Name].SetValue(newObj,obj.Properties[p.Name].GetValue(obj)); return newObj; }
如果我真的需要泛型,那么动态作为我的后备策略.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。