c# – 通用静态类 – 在运行时检索对象类型
发布时间:2020-12-16 01:46:05 所属栏目:百科 来源:网络整理
导读:我有一个X类型的对象,我可以(显然)在运行时检索. var type = myObject.GetType(); 我有一个通用的静态类. public static class MyStaticClassT{ public static void DoStuff(T something) { // bla bla }} 我想做的是: MyStaticClassmyObject.GetType().DoS
我有一个X类型的对象,我可以(显然)在运行时检索.
var type = myObject.GetType(); 我有一个通用的静态类. public static class MyStaticClass<T> { public static void DoStuff(T something) { // bla bla } } 我想做的是: MyStaticClass<myObject.GetType()>.DoStuff(myObject); 但我不能. 实际上,MyStaticClass只有几种类型可以运行,它们共享多个接口.一个解决方法是写: if (myObject.GetType() == typeof(X)) { MyStaticClass<X>.DoStuff(myObject as X); } if (myObject.GetType() == typeof(Y)) { MyStaticClass<Y>.DoStuff(myObject as Y); } 但它很冗长,到处写的都很难看 – 我觉得我不应该这样做,但我也不应该这样做. 我无法相信没有解决方案.或者至少有任何整洁的解决方法?或者我的方法开始时是错误的(如果是这样的替代方案)?我应该为X,Y,Z创建一些(抽象?)基类吗? 解决方法
您可以使用Type.MakeGenericType通过反射执行此操作 – 但是您还需要使用反射来调用该方法.虽然这有点痛苦.
如果你使用的是C#4,你可以使用动态类型和类型推断 – 虽然这只适用于泛型方法而不是泛型类型,所以你需要使用: public void DoStuffDynamic(dynamic item) { DoStuffHelper(item); } private static void DoStuffHelper<T>(T item) { MyClass<T>.DoStuff(item); } 编辑:为了表现,你可以避免做太多的实际反思.您可以对每个项目类型执行一次反射,创建Action< object>形式的委托,并将其缓存在字典中.这比在每次执行时执行反射要快得多. 这是一个简短但完整的样本: using System; using System.Collections.Generic; using System.Reflection; public static class MyStaticClass { private static readonly object mapLock = new object(); private static readonly Dictionary<Type,Action<object>> typeActionMap = new Dictionary<Type,Action<object>>(); private static readonly MethodInfo helperMethod = typeof(MyStaticClass).GetMethod("ActionHelper",BindingFlags.Static | BindingFlags.NonPublic); public static void DoStuffDynamic(object item) { if (item == null) { throw new ArgumentNullException("item"); } Type type = item.GetType(); Action<object> action; lock (mapLock) { if (!typeActionMap.TryGetValue(type,out action)) { action = BuildAction(type); typeActionMap[type] = action; } } action(item); } private static Action<object> BuildAction(Type type) { MethodInfo generic = helperMethod.MakeGenericMethod(type); Delegate d = Delegate.CreateDelegate(typeof(Action<object>),generic); return (Action<object>) d; } private static void ActionHelper<T>(object item) { MyStaticClass<T>.DoStuff((T) item); } } public static class MyStaticClass<T> { public static void DoStuff(T something) { Console.WriteLine("DoStuff in MyStaticClass<{0}>",typeof(T)); } } public class Test { static void Main() { MyStaticClass.DoStuffDynamic("Hello"); MyStaticClass.DoStuffDynamic(10); } } 我必须使用这种东西,但偶尔也没有任何明智的选择. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |