我有一个类层次结构,看起来类似于这样:
public class Base
{
private List<string> attributes = new List<string>();
public T WithAttributes<T>(params string[] attributes)
where T : Base
{
this.attributes.AddRange(attributes);
return this as T;
}
}
public class Derived : Base
{
}
我希望您能使用流畅API语法从派生类中调用
Base.WithAttributes
方法,并返回派生实例,就像下面的示例一样。void Main()
{
Derived d = new Derived();
// CS0411 The type arguments for method 'UserQuery.Base.WithAttributes<T>(params string[])' cannot be inferred from the usage.
d.WithAttributes("one", "two");
// Works, but type arguments must be explicity specified.
d.WithAttributes<Derived>("one", "two");
// Works without explicitly specifying, but no access to private members!
d.WithAttributesEx("one", "two");
}
public static class Extensions
{
public static T WithAttributesEx<T>(this T obj, params string[] attributes)
where T : Base
{
// No access to private members, argh!
// obj.attributes.AddRange(attributes);
return obj as T;
}
}
- 为什么编译器不能在第一个示例中推断类型参数?
- 使用扩展方法调用时为什么会起作用?
- 有没有办法在基类上将其作为实例方法工作而不显式指定类型参数?
Base<T>
中的T
和WithAttributes<T>
中的T
之间没有链接。尝试将标识符更改为Base<F>
,它将正常工作。您没有在扩展方法中使用通用的Base
。 - Heretic MonkeyBase<T>
,它也无法正常工作。Base<T>
和WithAttributes<T>
中的T
之间不应该有链接。我已经更新了示例以删除它。 - tbridgeDerived.WithAttributes<T>
推断类型参数的方式是什么呢?因为T
可以是任何继承自Base
或Base
本身的东西,包括不是Derived
或Base
的东西。 - Heretic Monkeythis
使得这两者不等价。在实例方法中,T 是任何继承自Base
的 T。在扩展方法中,T 是调用该方法的实例的类型。 - Orphid