C#类型推断:在不应该的地方失败?

时间:2009-02-09 17:31:31

标签: c# .net generics type-inference

请注意以下代码。违规行已被注释掉。

interface I<R> { }

class C : I<int> { }

class Program
{
    private static void function<T, R>(T t) where T : class, I<R>
    {
    }

    static void Main(string[] args)
    {
        // function(new C()); // wont compile
        function<C, int>(new C());
    }
}

我认为类型推断应该计算出类型,因为参数T提供了第一种类型,而I<R>提供了第二种类型。

有没有办法重新设计函数,以便调用者可能不必指定类型?

5 个答案:

答案 0 :(得分:8)

如果您想保留所有约束,则不会。但是,这应该同样适用,除​​非您有特定的理由禁止价值类型:

private static void function<R>(I<R> t)

答案 1 :(得分:5)

有多种方法可以为类型推断添加额外的规则 - 人类可以应用的逻辑位,但编译器(遵守语言规范)不适用。

在您建议确实应该更新语言以使类型推断更灵活地工作之前,我强烈建议您阅读现有规范。如果你能够很容易地理解这一点,你仍然认为值得让它更复杂更多,请在Connect上发布一个功能请求 - 但我个人认为它已经非常复杂了。我会说它比C#2.0好很多。

然而,提出相反的观点 - 几种语言(特别是功能性语言)具有更强大的类型推断机制。这里总有优点和缺点 - 我相信C#中当前推理系统的一个好处就是它总是进步或停止,例如 - Eric Lippert's blog有关于此的更多信息以及许多其他类型的推断的问题。

答案 2 :(得分:4)

class D : I<int>, I<string> { }
//
function<D, int>(new D());
function<D, string>(new D());
//is R int or string?
function(new D());  

答案 3 :(得分:1)

不,C#不支持这种推断。

直接使用界面并找到带有get type的类型。

private static void function<R>(I<R> t)
{
   Type typeofT = typeof(T);
}

无法做得更好。

如果需要使用T调用另一个泛型方法,可以使用typeofT Type通过反射构建泛型调用。

答案 4 :(得分:1)

C#不支持这种类型推断。考虑这种情况会给问题增加一些含糊之处。

class Other : I<int>, I<Student>{ ... }
void Example(){
  function(new D());
}

在这种情况下,我应该选择哪种模糊性。

如果您期待C#4.0,问题只会随着他们添加的新方差功能而增加。