基于自定义属性的通用类型比较,分配和返回

时间:2013-12-10 19:45:32

标签: c#

不知道为什么我无法弄明白......

我正在使用一种比较方法,它采用两种类型,循环遍历它们,并使用反射构建一个字段差异的报告。这或多或少是这两种类型的详细比较。类型具有相同的属性。在进行比较时,每个字段都有一个与之关联的自定义属性。在下面,差异对象存储名称以及与比较操作相关的其他属性。

为了进行比较,我使用以下内容:

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 ,原因很明显......所以我无法弄清楚如何,或多或少,映射基于读取自定义属性的属性值。

1 个答案:

答案 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));