我有一个接受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,因为方法中的代码依赖于它.
从本质上讲,你试图从反思到泛型,再到反思.
由于所讨论的方法只是回到反射,更好的方法是创建一个类型的重载,如下所示:
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)
注意!这假设您只有一种可用的方法,它是公共的,等等.
你可以做这样的事情:
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)
如果您只在循环中使用该方法,则可以删除通用版本,根本不需要它