C#泛型:简化类型签名 [英] C# generics: Simplify type signature

查看:118
本文介绍了C#泛型:简化类型签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个通用的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆