我创建了一个通用类来将一些数据解析为另一个类的实例(MyClass1
)。由于MyClass1
只有内置的C#类型,因此GenericMethod
工作正常。当MyClass1
具有另一个MyClass2
属性并且我仍然想要调用我的GenericMethod
来解析我的数据时,问题开始增长。
我无法在其范围内触发我的Generic Class方法,因为我需要更改T
的类型。有没有办法解决这个问题?
public class MyClass1
{
public int MyIntProperty { get; set; }
public string MyStringProperty { get; set; }
public MyClass2 MyClass2Property { get; set; }
}
public class MyClass2
{
public int MyOtherIntProperty { get; set; }
public string MyOtherStringProperty { get; set; }
public bool MyOtherBoolProperty { get; set; }
}
public class MyGenericClass<T> where T : class
{
public static T MyGenericMethod()
{
T o = (T)Activator.CreateInstance(typeof(T));
PropertyInfo[] pi = typeof(T).GetProperties();
for(int i = 0; i < pi.Count(); i++)
{
if(pi[i].Name == "MyClass2Property")
{
//How to proceed ?
MyGenericClass<???>.MyGenericMethod();
}
else
{
pi[i].SetValue(o, Convert.ChangeType(someValue, pi[i].PropertyType), null);
}
}
}
}
public static void Main(string[] args)
{
MyClass1 mc1 = MyGenericClass<MyClass1>.MyGenericMethod();
//Do something with mc1
}
答案 0 :(得分:5)
您可以查看this post
也许可以尝试这样的事情
public static class MyGenericClass<T> where T : class
{
public static T MyGenericMethod()
{
T o = (T)Activator.CreateInstance(typeof(T));
PropertyInfo[] pi = typeof(T).GetProperties();
for(int i = 0; i < pi.Count(); i++)
{
if(pi[i].Name == "MyClass2Property")
{
//How to proceed ?
Type t = typeof (MyGenericClass<>);
Type genericType = t.MakeGenericType(new System.Type[] { pi[i].PropertyType });
var c = Activator.CreateInstance(genericType);
dynamic mgm = Convert.ChangeType(c, genericType);
mgm.MyGenericMethod();
}
else
{
pi[i].SetValue(o, Convert.ChangeType(someValue, pi[i].PropertyType), null);
}
}
}
答案 1 :(得分:1)
根据您的需要,您还可以定义一些有关该属性的其他元信息,指明如果找到您想要对其执行的操作。
以他人为基础&#39;评论和答案,这是我想出的内容,包括允许您动态构建对象的属性修饰,并具有以下增强功能:
MyGenericMethod
方法进行更改。using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Dynamic;
public class MyClass1 {
public int MyIntProperty { get; set; }
public string MyStringProperty { get; set; }
[MyCustom()]
public MyClass2 MyClass2Property { get; set; }
}
public class MyClass2 {
public int MyOtherIntProperty { get; set; }
public string MyOtherStringProperty { get { return "oooh, fancy"; } set {} }
public bool MyOtherBoolProperty { get; set; }
}
public static class MyGenericClass<T> where T : class {
public static T MyGenericMethod() {
T o = (T)Activator.CreateInstance(typeof(T));
PropertyInfo[] pi = typeof(T).GetProperties();
for (int i = 0; i < pi.Count(); i++) {
if (pi[i].GetCustomAttributes(true).Any() && pi[i].GetCustomAttributes(true).Where((x) => x is MyCustomAttribute).Any()) {
//How to proceed ?
var c = Activator.CreateInstance(pi[i].PropertyType);
Type t = typeof(MyGenericClass<>);
Type genericType = t.MakeGenericType(new System.Type[] { pi[i].PropertyType });
MethodInfo m = genericType.GetMethod(MethodInfo.GetCurrentMethod().Name);
c = m.Invoke(null, null);
pi[i].SetValue(o, c, null);
} else {
//Normal property assignment.
}
}
return o;
}
}
public class Program {
public static void Main(string[] args) {
MyClass1 mc1 = MyGenericClass<MyClass1>.MyGenericMethod();
//Do something with mc1
Console.WriteLine(mc1.MyClass2Property.MyOtherStringProperty);
Console.ReadLine();
}
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple=false)]
public class MyCustomAttribute : Attribute {
}
我调整了它,因此可以按原样运行。
修改强>
我还更改了代码以调用自身被调用的方法以避免使用&#34;魔术字符串&#34;。