【问题标题】:C# generic interface type inference questionC#泛型接口类型推断题
【发布时间】:2011-06-07 17:27:24
【问题描述】:

我不知道如何简洁地表达这个问题而不只是给出例子,所以这里是:

public interface IThing<T>
{
    void Do(T obj);
}

public class ThingOne : IThing<int>
{
    public void Do(int obj)
    {
    }
}

public class ThingTwo : IThing<string>
{
    public void Do(string obj)
    {
    }
}

public class ThingFactory
{
    public IThing<T> Create<T>(string param)
    {
        if (param.Equals("one"))
            return (IThing<T>)new ThingOne();

        if (param.Equals("two"))
            return (IThing<T>)new ThingTwo();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var f = new ThingFactory();

        // any way we can get the compiler to infer IThing<int> ?
        var thing = f.Create("one");

    }
}

【问题讨论】:

  • 这不是类型推断 - 您的返回类型不是静态的,即事先不知道是否会返回 TypeOne 或 TypeTwo。
  • 添加到答案中,由于Create&lt;T&gt; 方法,尤其是因为您的铸件,您的代码甚至不应该在没有那种“推理”类型的情况下编译。 new ThingTwo() 不能转换为 IThing&lt;T&gt;ThingOne 也是如此。看起来您需要一种动态类型的语言。或者你在设计中犯了(即将犯)错误。

标签: c# generics types inference


【解决方案1】:

问题似乎在这里:

// any way we can get the compiler to infer IThing<int> ?
var thing = f.Create("one");

没有。您需要明确指定类型:

var thing = f.Create<int>("one");

如果没有在方法中专门使用的参数,则无法推断返回类型。编译器使用传递给方法的参数来推断T 的类型,在这种情况下,它是一个字符串参数,没有T 类型的参数。因此,无法为您推断出这一点。

【讨论】:

    【解决方案2】:

    不,您不能这样做,因为您的 Create 工厂方法的结果将在运行时根据参数的值进行评估。泛型是为了编译时的安全性,在你的情况下你不能有这样的安全性,因为参数值只有在运行时才知道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-14
      • 2020-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多