C#泛型:简化类型签名 [英] C# generics: Simplify type signature
问题描述
如果我有一个通用的Item类,看起来像这样:
抽象类项目< T>
{
}
和物品的容器,看起来像这样:
类容器< TItem,T>
式TItem:项目< T>
{
}
由于TItem取决于T,是有可能简化容器的类型签名,以便只需要一种类型的参数?我真正想要的东西是这样的:
类容器< TItem>
式TItem://项目这实际上并没有工作,因为项目需要一个类型参数
{
}
所以,我可以如下实例吧:
类的StringItem:项目<串> ;
{
}
变种好=新的Container<&StringItem的GT;();
变种坏=新的Container< StringItem的,串>();
编译器应该能够推断出T是字符串时TItem是StringItem的,对不对?我如何做到这一点。
期望用法:
类MyItem:项目<串GT;
{
}
&集装箱LT; MyItem>容器= GetContainer();
MyItem项= container.GetItem(0);
item.MyMethod();
这应该做你想要什么,我想。显然,你现在在做集装箱<串>
不是集装箱< StringItem的>
但你不包括用法示例我看不出它是一个问题。
使用System.Collections.Generic;
命名ConsoleApplication1
{
类节目
{
静态无效的主要(字串[] args)
{
变种myContainer中=新的Container<串GT;();
myContainer.MyItems =新的List<项目<串GT;>();
}
}
公共类项目< T> {}
公共类容器< T>
{
//你的容器上只是一些属性来显示你可以使用项目< T>
公开名单<项目< T>> MyItems {搞定;组; }
}
}
这个怎么样修订版:
使用System.Collections.Generic;
命名ConsoleApplication1
{
类节目
{
静态无效的主要(字串[] args)
{
变种myContainer中=新的Container<&StringItem的GT;();
myContainer.StronglyTypedItem =新的StringItem();
}
}
公共类项目< T> {}
公共类的StringItem:项目<串GT; {}
//可能的方式来掩饰这一点,但不能算出它现在
//(需要,因为它是一个基本类型是公共的)
//可能涉及制造容器(或第三类?)
//换一个私营集装箱,不可以继承
公共类PrivateContainer< TItem,T>其中,TItem:项目< T> {}
//公共接口
公共类容器< T> :PrivateContainer<项目< T> ;, T>
{
//你的容器上只是一些属性来显示你可以使用项目< T>
公共牛逼StronglyTypedItem {搞定;组; }
}
}
If I have a generic Item class that looks like this:
abstract class Item<T>
{
}
And a Container of Items that looks like this:
class Container<TItem, T>
where TItem : Item<T>
{
}
Since TItem depends on T, is it possible to simplify the type signature of Container so that it takes only one type parameter? What I really want is something this:
class Container<TItem>
where TItem : Item // this doesn't actually work, because Item takes a type parameter
{
}
So I can instantiate it as follows:
class StringItem : Item<string>
{
}
var good = new Container<StringItem>();
var bad = new Container<StringItem, string>();
The compiler should be able to deduce that T is string when TItem is StringItem, right? How do I make this happen?
Desired usage:
class MyItem : Item<string>
{
}
Container<MyItem> container = GetContainer();
MyItem item = container.GetItem(0);
item.MyMethod();
This should do what you want I think. Obviously you're now doing Container<string>
not Container<StringItem>
but as you've not included usage examples I can't see it being a problem.
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var myContainer = new Container<string>();
myContainer.MyItems = new List<Item<string>>();
}
}
public class Item<T> { }
public class Container<T>
{
// Just some property on your container to show you can use Item<T>
public List<Item<T>> MyItems { get; set; }
}
}
How about this revised version:
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var myContainer = new Container<StringItem>();
myContainer.StronglyTypedItem = new StringItem();
}
}
public class Item<T> { }
public class StringItem : Item<string> { }
// 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<TItem, T> where TItem : Item<T> { }
// Public interface
public class Container<T> : PrivateContainer<Item<T>, T>
{
// Just some property on your container to show you can use Item<T>
public T StronglyTypedItem { get; set; }
}
}
这篇关于C#泛型:简化类型签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!