Mar*_*ser 13 c# generics reflection casting
我有一个通用类型如下
public class TestGeneric<T>
{
public T Data { get; set; }
public TestGeneric(T data)
{
this.Data = data;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我现在有一个对象(来自某个外部源)我知道它的类型是一些封闭的TestGeneric <>,但我不知道TypeParameter T.现在我需要访问我的对象的数据.问题是我无法强制转换对象,因为我不确切知道哪个封闭的TestGeneric.
我用
// thx to http://stackoverflow.com/questions/457676/c-reflection-check-if-a-class-is-derived-from-a-generic-class
private static bool IsSubclassOfRawGeneric(Type rawGeneric, Type subclass)
{
while (subclass != typeof(object))
{
var cur = subclass.IsGenericType ? subclass.GetGenericTypeDefinition() : subclass;
if (rawGeneric == cur)
{
return true;
}
subclass = subclass.BaseType;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
为了确保,我的对象是泛型类型.有问题的代码如下:
public static void Main()
{
object myObject = new TestGeneric<string>("test"); // or from another source
if (IsSubclassOfRawGeneric(typeof(TestGeneric<>), myObject.GetType()))
{
// the following gives an InvalidCastException
// var data = ((TestGeneric<object>)myObject).Data;
// if i try to access the property with reflection
// i get an InvalidOperationException
var dataProperty = typeof(TestGeneric<>).GetProperty("Data");
object data = dataProperty.GetValue(myObject, new object[] { });
}
}
Run Code Online (Sandbox Code Playgroud)
我需要Data而不管它的类型(好吧,如果我可以使用GetType()来询问它的类型会很好,但不是必需的)因为我只想使用ToString()将其转储到xml中.
有什么建议?感谢名单.
Mar*_*ser 28
哦,堆叠......为什么没有人指出我的dynamic类型?这是一个完美的用法示例,它使代码更具可读性:
dynamic dynObject = myObject;
object data = dynObject.Data;
Run Code Online (Sandbox Code Playgroud)
Pau*_*ner 12
在访问其泛型成员之前,您需要知道泛型类的封闭类型.使用TestGeneric<>为您提供了开放类型定义,如果不指定泛型参数,则无法调用该定义.
获取属性值的最简单方法是直接反映使用中的封闭类型:
public static void Main()
{
object myObject = new TestGeneric<string>("test"); // or from another source
var type = myObject.GetType();
if (IsSubclassOfRawGeneric(typeof(TestGeneric<>), type))
{
var dataProperty = type.GetProperty("Data");
object data = dataProperty.GetValue(myObject, new object[] { });
}
}
Run Code Online (Sandbox Code Playgroud)