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();