【问题标题】:Calling a generic extension method with reflection使用反射调用通用扩展方法
【发布时间】:2013-04-22 13:31:24
【问题描述】:

我正在尝试调用具有动态类型的通用扩展方法,但我不断收到错误。

GenericArguments[0], 'DifferenceConsole.Name', on 'DifferenceConsole.Difference'1[T] GetDifferences[T](T, T)' violates the constraint of type 'T'.

在下面的代码中,我尝试注释掉动态类型并仅硬编码一个应该工作的类型(名称),但我得到了同样的错误。我不明白为什么我会收到错误。有什么建议吗?

public static class IDifferenceExtensions
{
    public static Difference<T> GetDifferences<T>(this T sourceItem, T targetItem) where T : IDifference, new()
    {
        Type itemType = sourceItem.GetType();

        foreach (PropertyInfo prop in itemType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            DifferenceAttribute diffAttribute = prop.GetCustomAttributes(typeof(DifferenceAttribute), false).FirstOrDefault() as DifferenceAttribute;

            if (diffAttribute != null)
            {
                if (prop.PropertyType.GetInterfaces().Contains(typeof(IDifference)))
                {
                    object sourceValue = prop.GetValue(sourceItem, null);
                    object targetValue = prop.GetValue(targetItem, null);

                    MethodInfo mi = typeof(IDifferenceExtensions)
                        .GetMethod("GetDifferences")
                        .MakeGenericMethod(typeof(Name));  // <-- Error occurs here
                        //.MakeGenericMethod(prop.PropertyType);

                    // Invoke and other stuff


                }
                else
                {
                    // Other stuff
                }
            }
        }

        //return diff;
    }
}

public class Name : IDifference
{
    [Difference]
    public String FirstName { get; set; }

    [Difference]
    public String LastName { get; set; }

    public Name(string firstName, string lastName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }
}

public interface IDifference
{

}

public class Difference<T> where T: IDifference, new()
{
    public T Item { get; set; }

    public Difference()
    {
        Item = new T();
    }
}

【问题讨论】:

    标签: c# generics reflection extension-methods


    【解决方案1】:

    Name 没有公共的无参数构造函数。
    但是,您将 T 限制为 IDifference, new(),这意味着用作泛型参数的每个类型都必须实现 IDifference 并且必须具有公共的无参数构造函数。

    顺便说一句:IDifferenceExtensions 是一个非常糟糕的静态类名称。 I 前缀通常是为接口保留的。

    【讨论】:

    • 噢!在我的脑海中,它确实有一个无参数的构造函数。我对此非常肯定,我从不费心去看。也感谢您的命名建议!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多