C#generics:简化类型签名

如果我有一个通用的Item类,如下所示:

abstract class Item { } 

和一个看起来像这样的项目容器:

 class Container where TItem : Item { } 

由于TItem依赖于T,是否可以简化Container的类型签名,使其只需要一个类型参数? 我真正想要的是这样的:

 class Container where TItem : Item // this doesn't actually work, because Item takes a type parameter { } 

所以我可以实例化如下:

 class StringItem : Item { } var good = new Container(); var bad = new Container(); 

当TItem是StringItem时,编译器应该能够推断T是字符串,对吧? 我该如何做到这一点?

所需用法:

 class MyItem : Item { } Container container = GetContainer(); MyItem item = container.GetItem(0); item.MyMethod(); 

这应该做你想要的我想的。 显然你现在正在做Container而不是Container但由于你没有包含用法示例,我看不出它是个问题。

 using System.Collections.Generic; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var myContainer = new Container(); myContainer.MyItems = new List>(); } } public class Item { } public class Container { // Just some property on your container to show you can use Item public List> MyItems { get; set; } } } 

这个修订版怎么样:

 using System.Collections.Generic; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var myContainer = new Container(); myContainer.StronglyTypedItem = new StringItem(); } } public class Item { } public class StringItem : Item { } // Probably a way to hide this, but can't figure it out now // (needs to be public because it's a base type) // Probably involves making a container (or 3rd class??) // wrap a private container, not inherit it public class PrivateContainer where TItem : Item { } // Public interface public class Container : PrivateContainer, T> { // Just some property on your container to show you can use Item public T StronglyTypedItem { get; set; } } } 

我认为你的问题的一个可能的解决方案是添加接口IItem ,代码结构将如下所示。

 interface IItem { } abstract class Item : IItem { } class Container where TItem : IItem { } class StringItem: Item { } 

现在你可以拥有Container

 var container = new Container();