具有推断泛型参数的通用方法

3
我有以下代码,用于创建访问类属性的函数表达式。
public static Expression<Func<TObj, TProperty>> BuildGet<TObj, TProperty>(PropertyInfo property)
{
    Type type = typeof(TObj);
    ParameterExpression arg = Expression.Parameter(type, "x");
    var prop = Expression.Property(arg, property);

    return Expression.Lambda<Func<TObj, TProperty>>(prop, arg);
}

问题在于,即使已知(在PropertyInfo类的属性.DeclaringType.PropertyType中),我仍然必须传递TObjTProperty

有没有方法可以避免显式地传递它们?

返回类型必须保持为Expression<Func<TObj,TProperty>>


问问自己为什么要将PropertyInfo作为参数... - Stefan Steinegger
因为它来自需要插入到某些现有功能中的一些反射(需要Expression<Func<TObj,TProperty>>)。我知道这不是什么大问题,只是想知道是否有一些我不知道的高级泛型技术。 - Andrew Bullock
2个回答

3
如果返回类型必须保持为Func<TObj, TProperty>,那么该方法必须保持通用。您必须在编译时指定类型。这就是问题所在 - 虽然PropertyInfo知道类型,但该信息仅在执行时间可用,而编译器需要知道类型信息以检查您是否正确使用了值等。它不可能知道属性的执行时间值是什么。
如果您可以将返回类型更改为Expression,则可以创建一个带有执行时适当类型的Expression<Func<TObj,TProperty>>,但只需将其作为Expression返回即可。您将无法在编译时以类型安全的方式使用返回值而无需转换,但这可能会有所帮助...

是的,我认为那是我的唯一选择。无法决定是要转换表达式还是传递Ts。谢谢 :) - Andrew Bullock

1
编译器应该如何推断TObj的类型?你没有向函数传递任何属于该类型的参数。
你可以尝试像这样做:
public static Expression<Func<TObj, TProperty>> BuildGet<TObj, TProperty>
    (TObj obj, TProperty property) { ... }

这将允许编译器推断出TObjTProperty的类型,但这意味着您必须重构您的方法,因为您当前正在使用PropertyInfo参数。


是的,我知道这是个问题,我正在寻找解决方案 :) 意思是没有解决方案吗 :( - Andrew Bullock
你无法传递 TProperty,它要求你拥有一个实例。 - Stefan Steinegger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接