C# 泛型类型参数推断

C# 泛型类型参数推断,c#,generics,C#,Generics,我的中间层有一个方便的集合,用于收集属于父对象的子对象 public class ChildCollection<TParent, TChild> { public IEnumerable<TChild> GetChildren(); etc. } 公共类ChildCollection { 公共IEnumerable GetChildren(); 等 } 在界面中,我有一个方便的网格,它可以显示ChildCollection的内容,并允许用户对其进行操

我的中间层有一个方便的集合,用于收集属于父对象的子对象

public class ChildCollection<TParent, TChild>
{
    public IEnumerable<TChild> GetChildren();
    etc.
}
公共类ChildCollection
{
公共IEnumerable GetChildren();
等
}
在界面中,我有一个方便的网格,它可以显示ChildCollection的内容,并允许用户对其进行操作

public abstract class ChildCollectionGrid<TCollection, TParent, TChild> : MyGridControl
    where TCollection : ChildCollection<TParent, TChild>
{
    public abstract TCollection Collection;
    etc.
}
公共抽象类ChildCollectionGrid:MyGridControl where-TCollection:ChildCollection { 公开摘要收集; 等 } 继承这个类来创建一个网格来处理小部件上的华夫饼,结果是这样的

public class WidgetWafflesGrid : ChildCollectionGrid<WidgetWafflesCollection, Widget, Waffle>
公共类WidgetWafflesGrid:ChildCollectionGrid 这有点多余。WidgetWaffleCollection是一个ChildCollection。指定了第一个泛型类型参数后,除非您精确地指定另外两个参数,否则该类将无法编译

如果编译器可以推断出其他两种类型,是否有更漂亮的方法来实现这一点?我知道我很挑剔,但理想情况下,我希望类声明如下所示:

public class WidgetWafflesGrid : ChildCollectionGrid<WidgetWafflesCollection>
公共类WidgetWafflesGrid:ChildCollectionGrid
谢谢你的帮助

不,没有。泛型参数推断只对方法有效。

不,没有。泛型参数推断仅对方法有效。

为什么从您的集合派生?保持这样:

public abstract class ChildCollectionGrid<TParent, TChild> : MyGridControl
{
    public abstract ChildCollection<TParent, TChild> Collection;
    etc.
}

public class WidgetWafflesGrid : ChildCollectionGrid<Widget, Waffle>
{  
}
公共抽象类ChildCollectionGrid:MyGridControl { 公共摘要收集; 等 } 公共类WidgetWafflesGrid:ChildCollectionGrid { }
为什么要从您的收藏中衍生?保持这样:

public abstract class ChildCollectionGrid<TParent, TChild> : MyGridControl
{
    public abstract ChildCollection<TParent, TChild> Collection;
    etc.
}

public class WidgetWafflesGrid : ChildCollectionGrid<Widget, Waffle>
{  
}
公共抽象类ChildCollectionGrid:MyGridControl { 公共摘要收集; 等 } 公共类WidgetWafflesGrid:ChildCollectionGrid { }
在具有泛型的集合中处理继承的唯一方法是使用
Collection:where TCollection:Collection{}
模式

下面是一个具体类的示例

public abstract class Collection<TCollection, TChild>
    where TCollection : Collection<TCollection, TChild>, new()
{
    protected Collection()
    {
        List=new List<TChild>();
    }
    protected List<TChild> List { get; set; }

    public TCollection Where(Func<TChild, bool> predicate)
    {
        var result=new TCollection();
        result.List.AddRange(List.Where(predicate));
        return result;
    }

    public void Add(TChild item) { List.Add(item); }
    public void AddRange(IEnumerable<TChild> collection) { List.AddRange(collection); }
}

public class Waffle
{
    public double Temperature { get; set; }
}

public class WafflesCollection : Collection<WafflesCollection, Waffle>
{
    public WafflesCollection BurnedWaffles
    {
        get
        {
            return Where((w) => w.Temperature>108);
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        WafflesCollection waffles=new WafflesCollection();

        // Count = 3
        waffles.Add(new Waffle() { Temperature=100 });
        waffles.Add(new Waffle() { Temperature=120 });
        waffles.Add(new Waffle() { Temperature=105 });

        var burned=waffles.BurnedWaffles;
        // Count = 1
    }
}
公共抽象类集合
其中TCollection:Collection,new()
{
受保护的集合()
{
列表=新列表();
}
受保护列表{get;set;}
公共集合,其中(Func谓词)
{
var result=new TCollection();
result.List.AddRange(List.Where(谓词));
返回结果;
}
public void Add(TChild项){List.Add(项);}
public void AddRange(IEnumerable集合){List.AddRange(集合);}
}
公共类华夫饼干
{
公共双温{get;set;}
}
公共类华夫饼集合:集合
{
公共华夫饼收集燃烧华夫饼
{
得到
{
返回其中((w)=>w.温度>108);
}
}
}
班级计划
{
静态void Main(字符串[]参数)
{
华夫饼集合华夫饼=新华夫饼集合();
//计数=3
Add(new Waffle(){Temperature=100});
Add(new Waffle(){Temperature=120});
Add(new Waffle(){Temperature=105});
var burned=华夫饼干。burned华夫饼干;
//计数=1
}
}

在具有泛型的集合中处理继承的唯一方法是使用
Collection:where TCollection:Collection{}
模式

下面是一个具体类的示例

public abstract class Collection<TCollection, TChild>
    where TCollection : Collection<TCollection, TChild>, new()
{
    protected Collection()
    {
        List=new List<TChild>();
    }
    protected List<TChild> List { get; set; }

    public TCollection Where(Func<TChild, bool> predicate)
    {
        var result=new TCollection();
        result.List.AddRange(List.Where(predicate));
        return result;
    }

    public void Add(TChild item) { List.Add(item); }
    public void AddRange(IEnumerable<TChild> collection) { List.AddRange(collection); }
}

public class Waffle
{
    public double Temperature { get; set; }
}

public class WafflesCollection : Collection<WafflesCollection, Waffle>
{
    public WafflesCollection BurnedWaffles
    {
        get
        {
            return Where((w) => w.Temperature>108);
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        WafflesCollection waffles=new WafflesCollection();

        // Count = 3
        waffles.Add(new Waffle() { Temperature=100 });
        waffles.Add(new Waffle() { Temperature=120 });
        waffles.Add(new Waffle() { Temperature=105 });

        var burned=waffles.BurnedWaffles;
        // Count = 1
    }
}
公共抽象类集合
其中TCollection:Collection,new()
{
受保护的集合()
{
列表=新列表();
}
受保护列表{get;set;}
公共集合,其中(Func谓词)
{
var result=new TCollection();
result.List.AddRange(List.Where(谓词));
返回结果;
}
public void Add(TChild项){List.Add(项);}
public void AddRange(IEnumerable集合){List.AddRange(集合);}
}
公共类华夫饼干
{
公共双温{get;set;}
}
公共类华夫饼集合:集合
{
公共华夫饼收集燃烧华夫饼
{
得到
{
返回其中((w)=>w.温度>108);
}
}
}
班级计划
{
静态void Main(字符串[]参数)
{
华夫饼集合华夫饼=新华夫饼集合();
//计数=3
Add(new Waffle(){Temperature=100});
Add(new Waffle(){Temperature=120});
Add(new Waffle(){Temperature=105});
var burned=华夫饼干。burned华夫饼干;
//计数=1
}
}

实际上那是我的原创设计!显然,我遗漏了很多细节,但我可以说我的具体收藏类有很多特别的优点,总是铸造收藏属性感觉不太理想。事实上,这是我最初的设计!很明显,我遗漏了很多细节,但我可以说我的具体集合类有很多特殊的优点,总是铸造集合属性感觉不太理想。