将动态类型的实例传递给泛型 class 中的泛型方法
Passing an instance of a dynamic type to a generic method in a generic class
我有一个公开通用方法的通用 class。此方法接收通用对象的实例作为参数并修改此实例。
示例class:
public class GenericClass<T>
{
public T GenericMethod(T obj)
{
// modify the object in some (arbitrary) way
IEnumerable<FieldInfo> fields = obj.GetType().GetRuntimeFields();
foreach (FieldInfo field in fields)
{
if (field.FieldType == typeof(string))
{
field.SetValue(obj, "This field's string value was modified");
}
}
return obj;
}
}
如果我有类型 (abc):
public class abc
{
public string a;
public string b;
public int c;
}
我可以按如下方式调用此方法:
GenericClass<abc> myGeneric = new GenericClass<abc>();
var myObject = myGeneric.GenericMethod(new abc());
//Confirm success by printing one of the fields
Console.Writeline(((abc)myObject).a);
现在,我的实际问题是:
我如何使用仅在 运行 时间已知的类型(与上面的类型 abc 相反)调用相同的通用方法。我还想在将它传递给 GenericMethod 时实例化它,就像我在上面对 abc 所做的那样。
例如(我知道这是完全错误的)
Type MyType;
GenericClass<MyType> myGeneric = new GenericClass<MyType>();
var myObject = myGeneric.GenericMethod(new MyType());
由于未知类型无法通过打印可能不存在的字段"a"来确认成功,我可以打印所有字符串字段的值,但这超出了范围问题。
回答你的问题:
var type = typeof(abc);
object instanceToModify = new abc();
var typeToCreate = typeof(GenericClass<>).MakeGenericType(type);
var methodToCall = typeToCreate.GetMethod("GenericMethod");
var genericClassInstance = Activator.CreateInstance(typeToCreate);
methodToCall.Invoke(genericClassInstance, new[] { instanceToModify });
但是:
如果您的类型仅在运行时已知,则您的实例必须在声明为 object
或 dynamic
的变量中处理。在这种情况下,您可以将方法签名更改为:
public object GenericMethod(object obj)
{
// modify the object in some (arbitrary) way
IEnumerable<FieldInfo> fields = obj.GetType().GetRuntimeFields();
foreach (var field in fields)
{
if (field.FieldType == typeof(string))
{
field.SetValue(obj, "This field's string value was modified");
}
}
return obj;
}
不需要通用 class/method。
我有一个公开通用方法的通用 class。此方法接收通用对象的实例作为参数并修改此实例。
示例class:
public class GenericClass<T>
{
public T GenericMethod(T obj)
{
// modify the object in some (arbitrary) way
IEnumerable<FieldInfo> fields = obj.GetType().GetRuntimeFields();
foreach (FieldInfo field in fields)
{
if (field.FieldType == typeof(string))
{
field.SetValue(obj, "This field's string value was modified");
}
}
return obj;
}
}
如果我有类型 (abc):
public class abc
{
public string a;
public string b;
public int c;
}
我可以按如下方式调用此方法:
GenericClass<abc> myGeneric = new GenericClass<abc>();
var myObject = myGeneric.GenericMethod(new abc());
//Confirm success by printing one of the fields
Console.Writeline(((abc)myObject).a);
现在,我的实际问题是:
我如何使用仅在 运行 时间已知的类型(与上面的类型 abc 相反)调用相同的通用方法。我还想在将它传递给 GenericMethod 时实例化它,就像我在上面对 abc 所做的那样。
例如(我知道这是完全错误的)
Type MyType;
GenericClass<MyType> myGeneric = new GenericClass<MyType>();
var myObject = myGeneric.GenericMethod(new MyType());
由于未知类型无法通过打印可能不存在的字段"a"来确认成功,我可以打印所有字符串字段的值,但这超出了范围问题。
回答你的问题:
var type = typeof(abc);
object instanceToModify = new abc();
var typeToCreate = typeof(GenericClass<>).MakeGenericType(type);
var methodToCall = typeToCreate.GetMethod("GenericMethod");
var genericClassInstance = Activator.CreateInstance(typeToCreate);
methodToCall.Invoke(genericClassInstance, new[] { instanceToModify });
但是:
如果您的类型仅在运行时已知,则您的实例必须在声明为 object
或 dynamic
的变量中处理。在这种情况下,您可以将方法签名更改为:
public object GenericMethod(object obj)
{
// modify the object in some (arbitrary) way
IEnumerable<FieldInfo> fields = obj.GetType().GetRuntimeFields();
foreach (var field in fields)
{
if (field.FieldType == typeof(string))
{
field.SetValue(obj, "This field's string value was modified");
}
}
return obj;
}
不需要通用 class/method。