【问题标题】:Compile time generics syntax编译时泛型语法
【发布时间】:2011-04-13 21:57:24
【问题描述】:
class GenericWrapper<T>
{   
}

class WrapperInstance : GenericWrapper<string>
{   
}

class Usage
{
    public static Usage Create<T1, T2> (T2 t2) where T1 : GenericWrapper<T2>
    {
        return null;
    }
}

...

// works
Usage.Create<WrapperInstance, string>("bar");

// doesnt work
Usage.Create<WrapperInstance>("bar");

我怀疑答案是否定的,但有没有办法编译最后一行?

我希望编译器强制我提供一个字符串参数,而不必知道或先去检查WrapperInstance 看看它实现了GenericWrapper 中的T 什么。

我知道我可以通过使用第一种方法或将 object 作为参数并进行运行时检查来编译它,但这不是问题;)我很大程度上怀疑这是我仅有的两个选择。

谢谢

【问题讨论】:

  • 由于 C# 的限制,它不会工作。但是,如果您详细说明要归档的内容,则可能有更好的方法将其写下来。 ;-)

标签: c# generics


【解决方案1】:

我怀疑答案是否定的,但有没有办法编译最后一行?

没有。 Create 有两个泛型类型参数。您要么不指定,要么同时指定两者。如果没有,编译器将尝试从调用参数推断类型。但是,在这种情况下它不能,因为T1 从未出现在参数列表中。因此,您必须同时指定两者。

【讨论】:

  • 相信不用多解释原因了。请参阅我在问题中的评论,这是关于几乎同一件事的长时间讨论:)
【解决方案2】:

这里有两个问题:

  • 您只想推断一个类型参数,并指定另一个。你不能用普通的类型推断来做到这一点。但是,您可以Usage设为泛型,从而在此处指定一个类型参数,并让其他使用泛型方法推断:

    Usage<WrapperInstance>.Create("foo");
    

    这是我以前经常做的事情,但这只会导致第二个问题......

  • 要指定的类型参数 (T1) 受要推断的类型参数 (T2) 的约束。上面的例子不能这样做,因为Usage&lt;WrapperInstance&gt; 没有“有”一个 T2 来验证......而且你不能在泛型方法上限制 existing 类型参数 - 只有那些方法中介绍的。

我认为我们可以通过一种方式做到这一点:

public class Usage
{
    public static Usage<T2> For<T2>(T2 t2)
    {
        return new Usage<T2>(t2);
    }
}

public class Usage<T2>
{
    private readonly T2 t2; // Assuming we need it

    public Usage(T2 t2)
    {
        this.t2 = t2;
    }

    // I don't know what return type you really want here
    public static Foo Create<T1>() where T1 : GenericWrapper<T2>
    {
        // Whatever
    }
}

你会这样使用它:

Usage.Foo("bar").Create<WrapperInstance>();

如果不知道更多关于你想要做什么,我不知道这是否有帮助 - 但它确实设法完成你所追求的:

  • 验证WrapperInstance 类型参数
  • 推断string 类型参数

【讨论】:

  • 嗯谢谢这是一个有趣的方法。我希望能够指定 T1,然后被提示输入 T2 的实例,而不必“知道” T2 是什么(即不必知道 T1 在 T1 : X 情况下扩展了什么)
  • @Andrew:不幸的是你不能这样做,因为 T1 受到 T2 的限制,而不是相反。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 2015-07-31
  • 1970-01-01
相关资源
最近更新 更多