通用类型作为变量

Man*_*kar 5 c#

我有一个接受Generic T类的方法

  public void CreateTables<T>()
   {
    string name = typeof(T).Name;

    var fields = typeof(T).GetProperties().Select(t => new { key = 
    t.Name.ToLower(CultureInfo.InvariantCulture), value = 
    SqLiteUtility.GetSQLiteTypeString(t.PropertyType) })
      .ToDictionary(t => t.key, t => 
          t.value);

    CreateTable(name, fields);
    }

   and 

    public void PushData<T>() where T : EntityData
   {
    var data = _context.Set<T>().Where(p => p.Deleted == false).ToList();
   }
Run Code Online (Sandbox Code Playgroud)

我有50多种类型需要调用此方法

CreateTables<Class1>();
PushData<Class1>();
Run Code Online (Sandbox Code Playgroud)

虽然我可以这样做,但我更喜欢创建类型数组并使用for循环来调用此方法

像这样的东西

   Type[] types=new Types[]{typeof(Class1),typeof(Class2)}

   foreach(var type in types)
   {
    //call create table method
      CreateTables<type>(); - - this doesnt work as "type" is a variable 
                                used as a type 

   }
Run Code Online (Sandbox Code Playgroud)

有没有解决的办法?这也可以为我节省大量代码并有效地重构事物?

EDIT1:

从答案来看,确实像CreateTables(Type T)这样的参数可以工作,但是对于上面的第二种方法,还有可能吗?

在第二个中,重要的是提到类型为EntityData的T,因为方法中的代码依赖于它.

ang*_*son 9

从本质上讲,你试图从反思到泛型,再到反思.

由于所讨论的方法只是回到反射,更好的方法是创建一个类型的重载,如下所示:

public void CreateTables<T>()
{
    CreateTables(typeof(T));
}

public void CreateTables(Type tableType)
{
    string name = tableType.Name;

    var fields = tableType.GetProperties().Select(t => new
        {
            key = t.Name.ToLower(CultureInfo.InvariantCulture),
            value = SqLiteUtility.GetSQLiteTypeString(t.PropertyType)
        })
        .ToDictionary(
            t => t.key,
            t => t.value);

    CreateTable(name, fields);
}
Run Code Online (Sandbox Code Playgroud)

这样你仍然可以使用特定类型(泛型)调用它,或者只需传递类型对象就可以从循环中调用它.


说了这么多,如果你不能改变获取Type对象的方法,那么你需要使用反射来调用它:

var m = GetType().GetMethod("CreateTables").MakeGenericMethod(new Type[] { type });
m.Invoke(this, null);
Run Code Online (Sandbox Code Playgroud)

注意!这假设您只有一种可用的方法,它是公共的,等等.


Jcl*_*Jcl 7

你可以做这样的事情:

public void CreateTables<T>()
{
  CreateTables(typeof(T));
}

public void CreateTables(Type type)
{
  string name = type.Name;

  var fields = type.GetProperties().Select(
      t => new { 
         key = t.Name.ToLower(CultureInfo.InvariantCulture), 
         value = SqLiteUtility.GetSQLiteTypeString(t.PropertyType) 
      }).ToDictionary(
         t => t.key, 
         t => t.value);

  CreateTable(name, fields);
}
Run Code Online (Sandbox Code Playgroud)

然后:

Type[] types=new Types[]{typeof(Class1),typeof(Class2)}

foreach(var type in types)
{
    CreateTables(type);
}
Run Code Online (Sandbox Code Playgroud)

如果您在循环中使用该方法,则可以删除通用版本,根本不需要它