所以这是简化的类:
// base class for all object
public class TrainingClass
{
public double NetSurface { get; set; } = 0;
}
// one sample object
public class Blank : TrainingClass
{
public double Height { get; set; } = 0;
public double Width { get; set; } = 0;
}
// the handling class
public class RegModel<T> where T : TrainingClass
{
// empty constructor
public RegModel() { }
// 2 methods that use data of type T
public void Train(List<T> datas) {}
public void Solve(T data) {}
}
通常我可以很容易地一个接一个地打电话给他们,但是由于上课的数量超过了3,000个,我不想让这个电话成为通用的电话。我所取得的成就如下:
// create the data type the generic need to be of
//(this is parameter in the real code)
Type dataType = typeof(Blank);
// create a dummy list of data (this is actually a property in the
// class in the real code it's of TrainingClass type to allow for generic)
var datas = new List<TrainingClass>();
// create the generic base type
Type genericClass = typeof(RegModel<>);
// create the generic type
Type constructedClass = genericClass.MakeGenericType(dataType);
// create the class
var rm = Activator.CreateInstance(constructedClass);
// get the train method
var trainMethod = constructedClass.GetMethod("Train");
// invoke the train method passing the List<TrainingData>
trainMethod.Invoke(rm, new[] { datas });
train方法使我抛出类型异常
类型'System.Collections.Generic.List'1 [ConsoleApp2334.TrainingClass]'的对象不能转换为类型'System.Collections.Generic.List`1
我也尝试像这样对Train
方法进行泛型调用,并收到一条错误消息,指出它不是泛型
var trainMethodGeneric = trainMethod.MakeGenericMethod(typeof(Blank));
,错误是
Train(System.Collections.Generic.List`1 [ConsoleApp2334.Blank])不是GenericMethodDefinition。只能在MethodBase.IsGenericMethodDefinition为true的方法上调用MakeGenericMethod。
因此,在第一个王牌中,它抱怨错误的通用参数,在第二个王牌中,它抱怨不通用或不“定义”为一个通用参数。我在做什么错了?
答案 0 :(得分:2)
您已经创建了RegModel<Blank>
,并尝试使用Train
来调用List<TrainingClass>
。这将不起作用,因为在Train
上调用的RegModel<Blank>
仅接受List<Blank>
。
您需要一种将List<TrainingClass>
转换为List<Blank>
的方法。或更一般而言,给定Type
和List<TrainingClass>
,将列表转换为该Type
的列表。一种方法是使用此方法:
// Note that although it says IList here, this method actually returns a List<T> at runtime
// We don't know the actual type of the list at compile time. The best we know
// is that it is some kind of a list.
static System.Collections.IList ConvertListToType<T>(Type type, List<T> list) {
Type constructedListType = typeof(List<>).MakeGenericType(type);
var newList = (System.Collections.IList)Activator.CreateInstance(constructedListType);
list.ForEach(x => newList.Add(x));
return newList;
}
您可以调用此方法将datas
转换为所需的类型,然后再将其传递给Train
。