C#裸型约束

Ed *_*hin 3 c# generics generic-constraints

在"C#6.0 in a Nutshell"中有一个裸体类型constarint用法的例子:

class Stack<T>
{
  Stack<U> FilteredStack<U>() where U : T {...}
}
Run Code Online (Sandbox Code Playgroud)

老实说,我不明白为什么我应该在这里使用这个约束.如果我将其删除并将U更改为T,结果将是相同的.那有什么意义呢?

谢谢.

15e*_*153 8

关键是U可以是任何类型的子类T,并且Stack你得到的是这种类型的堆栈,而不是T.因此,添加到它的项目必须是类型U,并且U如果它们不为null ,则保证从中返回的项目.所有熟悉的编译时类型检查的悲欢离合.

在这些项目Stack<T>可能是类型T,或任何的子类T.该方法的名称表明它返回的堆栈只包含父堆栈中实际属于某个特定子类的项目.一旦你保证新堆栈中的所有项都是更专业的类型,那么如果它也是新堆栈的类型则更有用.

这是一个非常人为的例子(显然,这个"堆栈"类实际上并没有做任何堆栈,但对于我们的例子,它不需要):

public class A
{
    public A(String s)
    {
        SA = s;
    }
    public String SA { get; set; }
}

public class B : A
{
    public B(String s, string s1)
    {
        SA = s;
        SB = s1;
    }
    public String SB { get; set; }
}

class Stack<T>
{
    Stack<U> FilteredStack<U>() where U : T
    {
        return new Stack<U>(Items.OfType<U>());
    }

    public IEnumerable<T> Items { get { return _items; } }

    public static void Test()
    {
        var s1 = new Stack<A>(new[] { new A("A1"), new B("B1", "Some other value") });
        var s2 = s1.FilteredStack<B>();

        //  s2 is a strongly typed stack of type B
        Console.WriteLine(s2.Items.First().SB);
    }


    private List<T> _items = new List<T>();
    public Stack(IEnumerable<T> items) {
        _items = new List<T>(items);
    }
}
Run Code Online (Sandbox Code Playgroud)