C# 无法从Foo转换<;F>;到F?
我在C#中使用了CRTP样式的generic构造,并拥有以下类:C# 无法从Foo转换<;F>;到F?,c#,generics,C#,Generics,我在C#中使用了CRTP样式的generic构造,并拥有以下类: public abstract class Foo<F> where F : Foo<F> { public abstract Bar<F> Bar { get; } public void Baz() { return this.Bar.Qux(this); //Error is here: "Argument 1: Cannot convert f
public abstract class Foo<F> where F : Foo<F>
{
public abstract Bar<F> Bar { get; }
public void Baz()
{
return this.Bar.Qux(this); //Error is here: "Argument 1: Cannot convert from 'Foo<F>' to 'F'
}
}
public abstract class Bar<F> where F : Foo<F>
{
public abstract void Qux(F foo);
}
公共抽象类Foo,其中F:Foo
{
公共抽象条{get;}
公共图书馆
{
返回this.Bar.Qux(this);//此处有错误:“参数1:无法从'Foo'转换为'F'
}
}
公共抽象类栏,其中F:Foo
{
公开摘要void Qux(F foo);
}
考虑到
This
应该始终是一个Foo,这对我来说似乎很奇怪,对吧?在这种情况下,This
是一个Foo
。Qux的参数声明为F
。它需要更改为Foo
:
公共抽象类Foo,其中F:Foo{
公共抽象条{get;}
公共图书馆{
Bar.Qux(本);
}
}
公共抽象类栏,其中F:Foo{
公开摘要void-Qux(Foo-Foo);
}
在该上下文中,这是一个Foo
。Qux的参数声明为F
。它需要更改为Foo
:
公共抽象类Foo,其中F:Foo{
公共抽象条{get;}
公共图书馆{
Bar.Qux(本);
}
}
公共抽象类栏,其中F:Foo{
公开摘要void-Qux(Foo-Foo);
}
“this”是Foo的一个实例,您尝试将其传递给Qux,它应该接受F。因此消息是绝对正确的。您尝试做的是将List强制转换为string(例如)编译器不会单独接受this
,因为它不能确定它是否为F
类型。这是因为提供的泛型约束强制F
成为Foo
的子类,但不是相反;因此,您可以声明任何类子类Foo
,但指定不同的类s作为泛型参数,如类X:Foo{}类G:Foo{}
其中G
是Foo
,但不是X
。我已经向Roslyn编译器团队提交了一个建议问题,以添加一个F-Bound/CRTP泛型类型约束。如果您有兴趣看到此功能添加到语言中,请对此问题发表评论。以下链接:非常好,@tyree-jackson'this'是一个inst输入Foo,然后尝试将其传递给Qux,Qux应该接受F。所以消息是绝对正确的。您尝试做的是将List强制转换为string(例如)编译器不会单独接受this
,因为它不能确定它是否为F
类型。这是因为提供的泛型约束强制F
成为Foo
的子类,但不是相反;因此,您可以声明任何类子类Foo
,但指定不同的类s作为泛型参数,如类X:Foo{}类G:Foo{}
其中G
是Foo
,但不是X
。我已经向Roslyn编译器团队提交了一个建议问题,以添加一个F-Bound/CRTP泛型类型约束。如果您有兴趣看到此功能添加到语言中,请对此问题发表评论。这是链接:非常好,@tyree jacksonAh,我明白了。th是吗我的逻辑有缺陷的一个原因是它可以找出这个
是F
,或者编译器只是不尝试?这个
是类的一个实例。这个类是Foo
,而不是F
。啊,我明白了。我的逻辑有缺陷的原因是它可以找出这个
>是一个F
,还是编译器只是不尝试?这是该类的一个实例。该类是Foo
,而不是F
。
public abstract class Foo<F> where F : Foo<F> {
public abstract Bar<F> Bar { get; }
public void Baz() {
Bar.Qux(this);
}
}
public abstract class Bar<F> where F : Foo<F> {
public abstract void Qux(Foo<F> foo);
}