调用泛型扩展方法而不指定任意类型

Dan*_*son 5 c# lambda extension-methods

这是我用于测试Type扩展方法的类的片段:

class Something
{
  [StringLength(100, MinimumLength = 1, ErrorMessage = "Must have between 1 and 100 characters")]
  public string SomePublicString { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我有以下扩展方法:

public static class TypeExtensions
{
  public static TAttributeType GetCustomAttribute<T, TAttributeType, TProperty>(this T value, Expression<Func<T, TProperty>> propertyLambda, bool inherit = false)
  {
    var type = typeof(T);
    var member = (MemberExpression)propertyLambda.Body;
    var propertyInfo = (PropertyInfo)member.Member;
    var customAttributes = propertyInfo.GetCustomAttributes(typeof(TAttributeType), inherit);

    return customAttributes.OfType<TAttributeType>().FirstOrDefault();
  }
}
Run Code Online (Sandbox Code Playgroud)

用于单元测试:

1:  var something = new Something();
2:  var actual = something.GetCustomAttribute<Something, StringLengthAttribute, string>(x => x.SomePublicString);

3:  actual.MinimumLength.Should().Be(1);
4:  actual.MaximumLength.Should().Be(100);
5:  actual.ErrorMessage.Should().Be("Must have between 1 and 100 characters");
Run Code Online (Sandbox Code Playgroud)

这将返回通过测试(使用FluentAssertions).

但是,我想在第2行中获取对GetCustomAttribute()的方法调用,直到下面的内容:

var actual = something.GetCustomAttribute<StringLengthAttribute>(x => x.SomePublicString);
Run Code Online (Sandbox Code Playgroud)

这可能吗?我错过了什么吗?也许我正在喝咖啡因.:(

Jon*_*eet 7

不,您要么必须指定所有类型参数,要么不指定它们.没有"部分"类型推断.

但是,有时可以避免这种情况的一种方法是使用一个带有单一类型参数的泛型方法,该方法返回泛型类的实例,然后对其进行类型推断以完成其余操作 - 反之亦然.在这种情况下,实际上最好将属性提取与其余部分分开:

something.GetPropertyAttributes(x => x.SomePublicString)
         .FirstAttribute<StringLengthAttribute>();
Run Code Online (Sandbox Code Playgroud)

在这里,第一个方法调用推断TTProperty-和方法会返回一个IEnumerable<Attribute>FirstAttribute只想做OfType/ FirstOrDefault电话.(你甚至可能认为你不需要FirstAttribute,因为打电话OfTypeFirstOrDefault你自己都很简单.)