调用泛型类构造函数的困境 [英] Dilemma in calling constructor of generic class

查看:185
本文介绍了调用泛型类构造函数的困境的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public class Cache< T> 
{
private Dictionary< Guid,T> cachedBlocks;

//构造函数和东西,提到这是一个单例

public T GetCache(Guid id)
{
if(!cachedBlocks.ContainsKey (id))
cachedBlocks.Add(id,LoadFromSharePoint(id))
return cachedBlocks [id];
}

public T LoadFromSharePoint(Guid id)
{
return new T(id)//这是问题所在。


错误信息是:


无法创建类型T的实例,因为它没有new()约束。


我必须指出,我必须传递 id 参数,并且没有其他方法可以这样做。任何有关如何解决这个问题的想法都将得到高度赞赏。

转换为具有默认构造函数并调用它的类型。然后,您必须添加一个方法或属性才能为实例提供 id 的值。



< pre其中T:new()//< - 约束具有默认构造函数的类型
{pre $ public static T LoadFromSharePoint< T>(Guid id)
T value = new T();
value.ID = id;
返回值;
}






或者,因为您指定通过构造函数提供 id 参数,所以可以使用反射调用参数化的构造函数。 您必须确定类型定义了您要调用的构造函数。您不能将泛型类型 T 约束为具有特定构造函数而非默认构造函数的类型。 (例如其中T:new(Guid)不起作用。)

例如,我知道在 List< T> 上有一个构造函数 new List< string>(int capacity),可以像这样调用:

  var type = typeof(List< String>); 
object list = Activator.CreateInstance(type,/ * capacity * / 20);

当然,您可能想要进行一些转换( T )。


I have this generic singleton that looks like this:

public class Cache<T>
{
    private Dictionary<Guid, T> cachedBlocks;

    // Constructors and stuff, to mention this is a singleton

    public T GetCache(Guid id)
    {
        if (!cachedBlocks.ContainsKey(id))
            cachedBlocks.Add(id, LoadFromSharePoint(id))
        return cachedBlocks[id];
    }

    public T LoadFromSharePoint(Guid id)
    {
        return new T(id)    // Here is the problem.
    }
}

The error message is:

Cannot create an instance of type T because it does not have the new() constraint.

I have to mention that I must pass that id parameter, and there is no other way to do so. Any ideas on how to solve this would be highly appreciated.

解决方案

Normally you would constrain the type T to a type that has a default constructor and call that. Then you'd have to add a method or property to be able to provide the value of id to the instance.

public static T LoadFromSharePoint<T>(Guid id)
    where T : new()     // <-- Constrain to types with a default constructor
{
    T value = new T();
    value.ID = id;
    return value;
}


Alternatively since you specify that you have to provide the id parameter through the constructor, you can invoke a parameterized constructor using reflection. You must be sure the type defines the constructor you want to invoke. You cannot constrain the generic type T to types that have a particular constructor other than the default constructor. (E.g. where T : new(Guid) does not work.)

For example, I know there is a constructor new List<string>(int capacity) on List<T>, which can be invoked like this:

var type = typeof(List<String>);
object list = Activator.CreateInstance(type, /* capacity */ 20);

Of course, you might want to do some casting (to T) afterwards.

这篇关于调用泛型类构造函数的困境的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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