通用静态类 - 在运行时检索对象类型 [英] Generic static class - retrieving object type in run-time

查看:116
本文介绍了通用静态类 - 在运行时检索对象类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有类型的对象的 X 后,我可以(显然)在运行时检索。

I have an object of type X, which I can (obviously) retrieve in runtime.

var type = myObject.GetType();

和我有一个通用的静态类。

And I have a generic static class.

public static class MyStaticClass<T>
{
    public static void DoStuff(T something)
    {
        // bla bla
    }
}

我想要做的是:

MyStaticClass<myObject.GetType()>.DoStuff(myObject);



但我不能。

But I can't.

事实上,仅仅是上MyStaticClass将经营几类,和他们分享几个接口。一个解决办法是写:

In fact, there is just a few types on which MyStaticClass would operate, and they share several interfaces. One workaround is to write:

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?

I can't believe there is no solution. Or any neater workaround at least? Or is my approach wrong to start with (what's the alternative if so)? Should I create some (abstract?) base class for X, Y, Z?

推荐答案

您可以用反射做到这一点,使用 Type.MakeGenericType - 但是你的的需要使用反射来调用方法。这是一个有点痛,虽然

You can do this with reflection, using Type.MakeGenericType - but then you'll also need to use reflection to invoke the method. That's a bit of a pain though.

如果您正在使用C#4你可以使用动态类型和类型推断 - 虽然这仅适用于普通的方法的而不是一般的类型的,所以你需要使用:

If you're using C# 4 you could use dynamic typing and type inference - although that only works for generic methods rather than generic types, so you'd need to use:

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

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



编辑:出于性能考虑,你能避免做过多的实际反映。您可以执行反射的一次的每个产品类型,创建表单行动℃的代表;对象> ,并在字典中进行缓存。这可能是的的不是在每次执行的执行反映速度更快

For performance, you can avoid doing too much actual reflection. You can perform reflection once per item type, create a delegate of the form Action<object>, and cache it in a dictionary. This can be far faster than performing reflection on every execution.

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

Here's a short but complete sample:

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

在我的有无的,但偶尔也有真的没有任何明智的选择。

I only use this sort of thing when I have to, but occasionally there really isn't any sensible alternative.

这篇关于通用静态类 - 在运行时检索对象类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆