T类型的动态通用声明 [英] Dynamic Generic declaration of type T

查看:150
本文介绍了T类型的动态通用声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个存储类型字典的数组:

I have an array which stores a dictionary of Types:

//The dictionary:
Dictionary<CacheKey,Type> TypeLookup;

//This is the enum:
public enum CacheKey
{
    UserProfile,
    CustomerQuickSearch,
    CommissionConfiguration
}

我想用这个Dictionary来声明一个类型为T的变量

I would like to use this Dictionary to declare a variable of type T

        //instead of 
        T myvar;

        //I want to dynamically declare myvar as:
        //1)get the type for the cacheKey from the dictionary:
        Type type = TypeLookup[cacheKey];
        //2)declare myvar as the corresponding Type:
        type myvar;

背景是我构建了分布式缓存基础结构。我有一个很棒的小CachingProvider,它允许你更新缓存中的项目。

The background is that I am building a Distributed Caching infrastructure. I have a great little CachingProvider that allows you to update an item in the cache.

我想将此方法公开为web服务,以便我的服务器场中的所有服务器可以更新其缓存。但我想只有一个方法暴露为web服务,然后更新缓存中的相应项目。

I would like to expose this method as a webservice so that all the servers in my farm can have their cache updated. But I would like to have only one method exposed as a webservice which then updates the corresponding item in cache.

这是我试图公开的方法: p>

This is the method I'm trying to expose:

   public static void UpdateCacheEntryItem<T>(CacheKey cacheKey, int id)
    {
        //look up the cacheEntry in cache which is a dictionary.
        Dictionary<int, T> cacheEntry = (Dictionary<int, T>) CacheRef[cacheKey.ToString()];

        //call the corresponding method which knows how to hydrate that item and pass in the id.
        cacheEntry[id] = (T)HydrateCacheEntryItemMethods[cacheKey].Invoke(id);
    }

我试过的东西:
1)方法直接作为WCF服务,但当然由于该方法而不起作用。
2)我试着把字典找出来,因为我不需要用返回值做同步处理,我只需要更新缓存中的项目。但是那也行不通。我得到的错误:无法投射类型为'System.Collections.Generic.Dictionary 2 [System.Int32,CachingPrototype.CustomerQuickSearch]'的对象来键入'System.Collections.Generic.Dictionary 2 [System.Int32,System.Object]'。

Things I've tried: 1) I tried exposing the method directly as a WCF service but of course that doesn't work because of the on the method. 2) I tried casting the Dictionary which would be find because I don't need to do anthing with the return value, I just need to update the item in cache. But that didn't work either. Error that I get: Unable to cast object of type 'System.Collections.Generic.Dictionary2[System.Int32,CachingPrototype.CustomerQuickSearch]' to type 'System.Collections.Generic.Dictionary2[System.Int32,System.Object]'.

您的评论非常有帮助,并帮助我回答我的问题。我想出的解决方案是简单地将我的WCF服务方法包装在switch语句中,以便我可以用正确类型的T来调用UpdateCacheEntryItem方法。由于没有办法将Type从Type转换为T,所以唯一的选择。由于我在Cache中没有那么多类型,所以这个工作非常好。 (另一种解决方案是使用如下所述的接口,但不会像我想的那样输入强类型。)

Your comments were very helpful and helped me to answer my question. The solution I came up with is to simply wrap my WCF service method in a switch statement so that I could call the UpdateCacheEntryItem method with the correct type of T. Since there is no way to convert from Type to the generic T operator, this is the only option. Since I don't have that many types in Cache, this works pretty well. (The other solution would be to use an interface as stated below but that would not be as strongly typed as I would like.)

    [OperationContract]
    public void UpdateCacheEntryItem(CacheKey cacheKey, int id)
    {
        switch (cacheKey)
        {
            case CacheKey.UserProfile:
                CacheProvider.UpdateCacheEntryItem<UserProfile>(cacheKey, id);
                break;
            case CacheKey.CommissionConfig:
                CacheProvider.UpdateCacheEntryItem<CommissionConfig>(cacheKey, id);
                break;
            case CacheKey.CustomerQuickSearch:
                CacheProvider.UpdateCacheEntryItem<CustomerQuickSearch>(cacheKey, id);
                break;
            default:
                throw new Exception("Invalid CacheKey");
        }

感谢大家的帮助,您真是太棒了!

Thanks everyone for your help, you are brilliant!

推荐答案

动态声明变量的想法与作为变量声明一部分的类型的整体相反。这个想法是,你可以告诉编译器的类型,以便它可以检查你在做什么。在这种情况下,你根本没有表达过关于类型的任何信息。你可能只需将 myVar 声明为 object ;这基本上与我几乎不知道 myVar 的价值,除了它是一个引用。

The idea of "dynamically declaring a variable" is contrary to the whole point of there being a type as part of the declaration of a variable. The idea is that you can tell the compiler the type, so that it can check what you're doing. In this case you haven't expressed any information about the type at all. You might as well just declare myVar as being of type object; that's basically the same as saying "I know pretty much nothing about the value of myVar, except that it's a reference."

当然,如果你有一个通用的接口,那就太好了 - 然后你可以安全地使用那个接口的成员(当然在创建/获取适当的实例之后)。但除此之外,除非您在编译时知道关于类型的东西,否则实际上您可以做的事情不多。

If you've got a common interface of course, that would be great - and then you could use the members of that interface safely (after creating/fetching an appropriate instance, of course). But otherwise, there's really not a lot you can do unless you know something about the type at compile time.

在C#4中,您可以声明变量应该是 dynamic 类型的变量,它可以使所有的绑定变为动态的 - 基本上你可以完成你喜欢的任何操作,并且它将在执行时解决。我建议尽可能使用静态类型,以便在编译时捕获错误。

In C# 4 you could declare the variable to be of type dynamic which would make all the binding dynamic - basically you can do pretty much what you like with it, and it will all be resolved at execution time. I'd advise using static typing wherever you can though, so that errors can be caught at compile time instead.

这篇关于T类型的动态通用声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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