无法从用法中推断出方法的类型参数

Ben*_*Ben 50 c# type-inference

也许我工作过度,但这不是编译(CS0411).为什么?

interface ISignatur<T>
{
    Type Type { get; }
}

interface IAccess<S, T> where S : ISignatur<T>
{
    S Signature { get; }    
    T Value { get; set; }
}

class Signatur : ISignatur<bool>
{
    public Type Type
    {
        get { return typeof(bool); }
    }
}

class ServiceGate
{
    public IAccess<S, T> Get<S, T>(S sig) where S : ISignatur<T>
    {
        throw new NotImplementedException();
    }
}

static class Test
{
    static void Main()
    {
        ServiceGate service = new ServiceGate();
        var access = service.Get(new Signatur()); // CS4011 error
    }
}
Run Code Online (Sandbox Code Playgroud)

任何人都知道为什么不呢?或者如何解决?

Kir*_*oll 64

Get<S, T>采用两种类型的参数.当你打电话时service.Get(new Signatur());编译器怎么知道是什么T?您必须明确地传递它或更改有关您的类型层次结构的其他内容.明确地传递它看起来像:

service.Get<Signatur, bool>(new Signatur());
Run Code Online (Sandbox Code Playgroud)

  • 我不知道它是如何知道/不知道的,但可以推断出“T”,因此错误消息具有误导性,表明您犯了一些逻辑错误。`S` 是 `Signature` 并且它实现了 `ISignatur&lt;bool&gt;`,所以在这种情况下,`T` 不能是 `bool` 之外的其他类型,并且这两种类型都是已知的。错误应该是“编译器不能......”而不是“它不能......” (2认同)

Dan*_*Tao 11

柯克的回答是正确的.作为一项规则,你不会有当你的方法签名具有较少的类型推断任何侥幸类型的参数比它的泛型类型参数.

在您的特定情况下,似乎你可以有可能的移动T类型参数类级别,然后在你拿到类型推断Get的方法:

class ServiceGate<T>
{
    public IAccess<S, T> Get<S>(S sig) where S : ISignatur<T>
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您使用CS0411错误发布的代码可以重写为:

static void Main()
{
    // Notice: a bit more cumbersome to write here...
    ServiceGate<SomeType> service = new ServiceGate<SomeType>();

    // ...but at least you get type inference here.
    IAccess<Signatur, SomeType> access = service.Get(new Signatur());
}
Run Code Online (Sandbox Code Playgroud)