c# - 从 3 个通用类型中推断出 2 个

标签 c# generics reflection expression

我已经构建了一个方法,如果在属性上找到它,它会返回一个属性实例:

public static U GetPropertyAttribute<T, TProperty, U>(this T instance, Expression<Func<T, TProperty>> propertySelector, U attribute) where U : Attribute
{
   return Attribute.GetCustomAttribute(instance.GetType().GetProperty((propertySelector.Body as MemberExpression).Member.Name), typeof(U), true) as U;
}

为了获取实例,我必须调用:

var cc = new CustomClass();
cc.GetPropertyAttribute(x => x.Name, new NullableAttribute())

它工作正常,我得到了属性类的确切实例。

但是,我不喜欢必须使用 new NullableAttribute() 作为参数,我希望调用看起来像这样:

cc.GetPropertyAttribute<NullableAttribute>(x => x.Name)

然而,这不起作用,因为一旦我删除第二个参数并在方法名称中添加 1 个泛型类型,它就开始需要另外两个。有没有办法强制该方法从 3 个通用参数中推断出 2 个? IE。我想指定属性类,但不想指定类名和属性名。

更新:

这是实现的代码,感谢 Jon,还有字符串解决方案的代码。我决定嵌套类,这样如果我为其他一些扩展类引入相同的方法,就不会污染命名空间。

public static class AttributeExtensions
{
    public static ObjectProperty<T, TProperty> From<T, TProperty>(this T instance, Expression<Func<T, TProperty>> propertySelector)
    {
        return new ObjectProperty<T, TProperty>(instance, propertySelector);
    }

    public class ObjectProperty<T, TProperty>
    {
        private readonly T instance;
        private readonly Expression<Func<T, TProperty>> propertySelector;

        public ObjectProperty(T instance, Expression<Func<T, TProperty>> propertySelector)
        {
            this.instance = instance;
            this.propertySelector = propertySelector;
        }

        public U GetAttribute<U>() where U : Attribute
        {
            return Attribute.GetCustomAttribute(instance.GetType().GetProperty((propertySelector.Body as MemberExpression).Member.Name), typeof(U), true) as U;
        }
    }

    public static T GetPropertyAttribute<T>(this object instance, string propertyName) where T : Attribute
    {
        return Attribute.GetCustomAttribute(instance.GetType().GetProperty(propertyName), typeof(T), true) as T;
    }
}

所以现在调用是这样的:

var cc = new CustomClass();
var attr = cc.From(x => x.Name).GetAttribute<NullableAttribute>();

最佳答案

Is there a way to force the method to infer 2 out of 3 generic parameters?

一种常见的方法是使用具有这两个类型参数的中间类型,然后在该类型中使用泛型方法以允许您提供最后一个:

public static AttributeFetcher<T, TProperty> FetchFrom<T, TProperty>
    (this T instance, Expression<Func<T, TProperty>> propertySelector)
{
    return new AttributeFetcher<T, TProperty>(instance, propertySelector);     
}

public class AttributeFetcher<T, TProperty>
{
    private readonly T instance;
    private readonly Expression<Func<T, TProperty>> propertySelector;

    // Add obvious constructor

    public U Attribute<U>() where U : Attribute
    {
        // Code as before
    }
}

然后你可以这样写:

cc.FetchFrom(x => x.Name).Attribute<NullableAttribte>();

您实际上可以使 AttributeFetcher 成为非泛型,因为据我所知您实际上只需要 PropertyInfo。上面的代码适用于更一般的情况。

关于c# - 从 3 个通用类型中推断出 2 个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13073262/

相关文章:

c# - 在 C# 的通用列表中合并具有相同类型的项目的最有效方法是什么?

c# - 具有异步等待和 GetType().IsValueType 的可移植类库

Java 8 map 签名 : public<U> Optional<U> map(Function<? super T, ? extends U> mapper)--为什么有两个U?

java - 在 Java 泛型方法中使用正则表达式

.net - 紧凑框架的 Reflection.Emit 替代方案

c# - 如何在 C# 中获取下一个(或上一个)枚举值

javascript - 从动态创建的控件中进行 ajax 调用

swift - 通过 Swift 中的另一个类用对象的新值设置未确定的属性

java - 在界面上查找注释

c# - 在 C# 中引用另一个应用程序提供的外部 .NET DLL