我有一个接受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();
}
我有超过50种需要调用此方法的类型
CreateTables<Class1>();
PushData<Class1>();
虽然我可以这样做,但我更喜欢创建类型数组并使用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
}
有解决方法吗?还能为我节省大量代码并有效地重构内容吗?
EDIT1:
从答案中,确实像CreateTables(Type T)这样的参数可以工作,但是对于上面的第二种方法,是否还有可能?
在第二个中,提到类型为EntityData是很重要的,因为方法中的代码依赖于它。
答案 0 :(得分: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);
}
通过这种方式,您仍然可以使用特定类型(泛型)调用它,或者只需传递类型对象即可从循环中调用它。
说了这么多,如果你不能改变方法来获取Type
对象,那么你需要使用反射来调用它:
var m = GetType().GetMethod("CreateTables").MakeGenericMethod(new Type[] { type });
m.Invoke(this, null);
注意!这假设您只有一种可用的方法,它是公开的等等。
答案 1 :(得分: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);
}
然后:
Type[] types=new Types[]{typeof(Class1),typeof(Class2)}
foreach(var type in types)
{
CreateTables(type);
}
如果仅在循环中使用该方法,则可以删除通用版本,根本不需要它
答案 2 :(得分:4)
试试这个:
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);
}
甚至这个:
public void CreateTables(IEnumerable<Type> types) {
if(types != null) {
foreach(Type type in types) {
CreateTables(type);
}
}
}