创建泛型类型的实例

Mis*_*832 1 c#

我想构建一个通用的Observable Collection,它将数据库中的值加载到其项目中.为了将值分配给项的属性,我想创建对象的实例.但是,我收到Activator.CreateInstance命令的错误:"'T'是一种类型,在给定的上下文中无效"

public class ListBase<T> : ObservableCollection<T>
{
    private DbTable tab;


    public ListBase()
    {
        tab = DbCatalog.Tables.Where(x => x.ModelObjectType == typeof(T).Name).First();

        LoadValues();
    }

    private void LoadValues()
    {

        foreach (DataRow r in tab.GetValues.Rows)
        {
            T o = (T)Activator.CreateInstance(T); //<-- The (T) at the end throws the error

            var p = o.GetType().GetProperty("xyz_property");

            if (p.PropertyType == typeof(int))
            {
                p.SetValue(o, Convert.ToInt32(r["xyz_fromDB"]));
            }

        }
    }

}
Run Code Online (Sandbox Code Playgroud)

Dav*_*idG 7

没有必要使用Activator.CreateInstance,正确的方法是new像对待任何对象一样 - 但这需要一个new约束:

public class ListBase<T> : ObservableCollection<T> where T : new()
{

}
Run Code Online (Sandbox Code Playgroud)

现在你可以简单地这样做:

T o = new T();
Run Code Online (Sandbox Code Playgroud)

  • 首先,您一眼就能看出您正在创建一个新对象,而不是稍微晦涩难懂的“CreateInstance”。此外,它强制新的约束,这意味着“T”需要无参数构造函数,否则将无法编译。使用前面的方法,您很容易受到运行时错误的影响。 (2认同)

GWi*_*Wam 5

您应该使用:CreateInstance(typeof(T)),返回一个可以工作的typeof类的对象。System.Type

在 C# 中,“通用”类型TSystem.Type. Activator.CreateInstance 需要后者。


编辑:你通常应该使用DavidG的方法,它更干净。您可以使用以下Activator时间:

  • 由于某种原因,您无法添加通用约束。
  • 您想将参数传递给构造函数。(new()约束意味着无参数构造函数,Activator可以传递参数。)