不知道为什么我无法弄明白......
我正在使用一种比较方法,它采用两种类型,循环遍历它们,并使用反射构建一个字段差异的报告。这或多或少是这两种类型的详细比较。类型具有相同的属性。在进行比较时,每个字段都有一个与之关联的自定义属性。在下面,差异对象存储名称以及与比较操作相关的其他属性。
为了进行比较,我使用以下内容:
public static List<Difference<T>> Detailed Difference <T>(this T val1, T val2)
{
List< Difference <T>> differences = new List< Difference <T>>();
FieldInfo[] fi = val1.GetType().GetFields();
foreach (FieldInfo f in fi)
{
Difference <T> v = new Difference <T>();
v.Prop = f.Name;
v.ValA = f.GetValue(val1);
v.ValB = f.GetValue(val2);
v.ObjectA = val1;
v.ObjectB = val2;
v.MyCustomAttribute = (MyCustomAttribute Attribute) Attribute.GetCustomAttribute(f, typeof (MyCustomAttribute Attribute));
differences.Add(v)
}
return differences;
}
MyCustomAttribute是一个包含FooA和FooB的枚举。
如果 MyCustomAttribute 等于 FooA ,则应使用 ValA 的值来构建 T 类型的返回值添加到方法列表返回。如果 MyCustomAttribute 等于 FooB ,则在构建新类型时应使用 ValB 的值。我遇到的问题是泛型不允许我实例化一种新类型的 T ,原因很明显......所以我无法弄清楚如何,或多或少,映射基于读取自定义属性的属性值。
答案 0 :(得分:1)
如果您加入new
constraint,那么new T()
就可以了。然后,您可以使用FieldInfo.SetValue
设置其中的值。
public static List<Difference<T>> Detailed Difference<T>(this T val1, T val2)
where T : new()
{
T newValue = new T();
// later...
v.MyCustomAttribute = // whatever it is
if (v.MyCustomAttribute == MyCustomAttribute.FooA)
f.SetValue(newValue, v.ValA);
else if (v.MyCustomAttribute == MyCustomAttribute.FooB)
f.SetValue(newValue, v.ValB);
differences.Add(v);
// other stuff...
}
如果这不适用于您的类型,则需要将某些内容传递给您的方法。由于您显然只需要一个新对象,并且始终只需要一个对象,因此您可以选择另一个T
:
public static List<Difference<T>> Detailed Difference<T>(this T val1, T val2,
T newValue)
{
// call like
var diff = myClass1.Difference(myClass2, new MyClass(someParam));
对于更高级的方案,请选择Func<T>
,以便您可以在需要时调用它:
public static List<Difference<T>> Detailed Difference<T>(this T val1, T val2,
Func<T> getNewValue)
{
T newValue = getNewValue();
// call like
var diff = myClass1.Difference(myClass2, () => new MyClass(someParam));