通用静态类 - 在运行时检索对象类型

2023-12-11

我有一个类型的对象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);
}

但它很冗长,而且到处写起来真的很难看——我觉得我不应该这样做,但我也不应该这样做have要做到这一点。

我不敢相信没有解决办法。或者至少有更简洁的解决方法?或者我的方法一开始就是错误的(如果是的话,有什么替代方案)?我应该为 X、Y、Z 创建一些(抽象?)基类吗?


您可以通过反射来做到这一点,使用Type.MakeGenericType- 但然后你就会also需要使用反射来调用该方法。不过这有点痛苦。

如果您使用 C# 4,您可以使用动态类型和类型推断 - 尽管这只适用于泛型methods而不是通用的types,所以你需要使用:

public void DoStuffDynamic(dynamic item)
{
    DoStuffHelper(item);
}

private static void DoStuffHelper<T>(T item)
{
    MyClass<T>.DoStuff(item);
}

编辑:为了性能,您可以避免进行过多的实际反射。您可以进行反射once每个项目类型,创建一个表单的委托Action<object>,并将其缓存在字典中。这可以是far比在每次执行时执行反射更快。

这是一个简短但完整的示例:

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);        
    }
}

我只在我使用这种东西的时候have,但有时确实没有任何明智的选择。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通用静态类 - 在运行时检索对象类型 的相关文章

随机推荐