相关疑难解决方法(0)

为什么C#不推断我的泛型类型?

我使用泛型方法有很多Funcy乐趣(有趣).在大多数情况下,C#类型推断足够聪明,可以找出它必须在我的泛型方法上使用的泛型参数,但现在我有一个C#编译器不成功的设计,而我相信它可以成功找到正确的类型.

在这种情况下,有人能告诉我编译器是否有点愚蠢,还是有一个非常清楚的原因导致它无法推断我的泛型参数?

这是代码:

类和接口定义:

interface IQuery<TResult> { }

interface IQueryProcessor
{
    TResult Process<TQuery, TResult>(TQuery query)
        where TQuery : IQuery<TResult>;
}

class SomeQuery : IQuery<string>
{
}
Run Code Online (Sandbox Code Playgroud)

一些不编译的代码:

class Test
{
    void Test(IQueryProcessor p)
    {
        var query = new SomeQuery();

        // Does not compile :-(
        p.Process(query);

        // Must explicitly write all arguments
        p.Process<SomeQuery, string>(query);
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么是这样?我在这里错过了什么?

这是编译器错误消息(它不会给我们留下太多想象):

无法从用法中推断出方法IQueryProcessor.Process(TQuery)的类型参数.尝试显式指定类型参数.

我认为C#应该能够推断它的原因是由于以下原因:

  1. 我提供了一个实现的对象IQuery<TResult>.
  2. 只有IQuery<TResult>类型实现的版本才是IQuery<string>TResult必须的string.
  3. 有了这些信息,编译器就有了TResult和TQuery.

对我来说,最好的解决方案是更改IQueryProcessor界面并在实现中使用动态类型:

public interface IQueryProcessor
{
    TResult Process<TResult>(IQuery<TResult> …
Run Code Online (Sandbox Code Playgroud)

.net c# type-inference c#-4.0

64
推荐指数
6
解决办法
2万
查看次数

这是C#4中的协方差错误吗?

在下面的代码我希望能够隐式地从投elementsbaseElements因为TBase可以隐式转换IBase.

public interface IBase { }
public interface IDerived : IBase { }
public class VarianceBug
{
    public void Foo<TBase>() where TBase : IBase
    {
        IEnumerable<TBase> elements = null;
        IEnumerable<IDerived> derivedElements = null;
        IEnumerable<IBase> baseElements;

        // works fine
        baseElements = derivedElements;

        // error CS0266: Cannot implicitly convert type 
        //   'System.Collections.Generic.IEnumerable<TBase>' to 
        //   'System.Collections.Generic.IEnumerable<IBase>'. 
        //   An explicit conversion exists (are you missing a cast?)
        baseElements = elements;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我收到了评论中提到的错误.

引用规范:

A型T<A1, …

c# generics covariance

37
推荐指数
2
解决办法
1659
查看次数

为什么协方差不适用于泛型方法

假设我有接口和类:

public interface ITree {}
public class Tree : ITree {}
Run Code Online (Sandbox Code Playgroud)

由于IEnumerable<T>协变,下面的代码行成功编译:

IEnumerable<ITree> trees = new List<Tree>();
Run Code Online (Sandbox Code Playgroud)

但是当我把它放入通用方法时:

public void Do<T>() where T : ITree
{
     IEnumerable<ITree> trees = new List<T>();
}
Run Code Online (Sandbox Code Playgroud)

我从编译器得到编译错误:

错误1无法将类型'System.Collections.Generic.List'隐式转换为'System.Collections.Generic.IEnumerable'.存在显式转换(您是否缺少演员?)D:\ lab\Lab.General\Lab.General\Program.cs 83 40 Lab.General

为什么协方差在这种情况下不起作用?

c# covariance contravariance c#-4.0

23
推荐指数
1
解决办法
1987
查看次数