C# 无法从Foo转换<;F>;到F?

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

我在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 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);

  }