我有一个具有指定类型键的泛型类,我希望创建该类的KeyedCollection(Of )。我认为这个代码更清楚我的话。
问题是是否可以重写代码,这样就可以在不指定键类型(int或整数)的情况下定义MyEnities类。
C#
public abstract class Entity<TPrimKey>
{public abstract TPrimKey Key { get; set; } }
public class Entities<TPrimKey, TItem> : ObjectModel.KeyedCollection<TPrimKey, TItem>
where TItem : Entity<TPrimKey>
{
protected override TPrimKey GetKeyForItem(TItem item)
{return item.Key;}
}
public class MyEntity : Entity<int>
{
public override int Key { get; set; }
}
public class MyEnities : Entities<int, MyEntity>
{}VB
Public MustInherit Class Entity(Of TPrimKey)
Public MustOverride Property Key As TPrimKey
End Class
Public Class Entities(Of TPrimKey, TItem As Entity(Of TPrimKey))
Inherits ObjectModel.KeyedCollection(Of TPrimKey, TItem)
Protected Overrides Function GetKeyForItem(item As TItem) As TPrimKey
Return item.Key
End Function
End Class
Public Class MyEntity
Inherits Entity(Of Integer)
Public Overrides Property Key As Integer
End Class
Public Class MyEnities
Inherits Entities(Of Integer, MyEntity)
End Class发布于 2018-01-09 19:07:23
你差点就有了。以下是一个解决方案:
using System.Collections.ObjectModel;
public class Entity<TPrimKey>
{
public TPrimKey Key { get; set; }
}
public class Entities<TPrimKey> : KeyedCollection<TPrimKey, Entity<TPrimKey>>
{
protected override TPrimKey GetKeyForItem( Entity<TPrimKey> item )
{ return item.Key; }
}
public class MyEntity1 : Entity<int>
{
}
public class MyEntity2 : Entity<int>
{
}
public class MyEntities : Entities<int>
{
public static void Test()
{
var entities = new MyEntities();
var entity1 = new MyEntity1();
entities.Add( entity1 );
var entity2 = new MyEntity2();
entities.Add( entity1 );
}
}要明确的是,这是一个稍微不同的方式思考你的目标。MyEntities仍然指定键类型int;任何想进入Entities<TPrimKey>的泛型方法。或者在Entities和MyEntities之间创建一个泛型类MyEntities,以保存这些方法:
public abstract class MyEntitiesA<TPrimKey> : Entities<TPrimKey>
{
// Methods that apply to all TPrimKeys go here.
// Some methods may need to be abstract, and implemented
// in each subclass, that has a concrete key (or at least a key with a constraint).
}
public class MyEntities : MyEntitiesA<int>
...MyEntitiesA<TPrimKey>满足您的需求,而不指定键类型int。(在某个时候,您将创建具有具体类型的类和/或变量声明;“目标”是能够保持对所有可泛化描述的方法的泛型。)
你错过的是这一行:
public class Entities<TPrimKey> : KeyedCollection<TPrimKey, Entity<TPrimKey>>在那里,值的类型是根据键的类型定义的。这允许您定义GetKeyForItem,使其适用于所有TPrimKey。
请注意,我包含了两个派生自Entity<int>的类,以显示该集合的全部功能。也可以通过Test()来展示它的作用。
您可能还会发现这些链接与以下相关:
如果将集合基于interface而不是基类,则此技术甚至更强大。这允许将支持正确接口(在该键类型上)的任何类添加到集合中。在这里,我们可以看到,这允许我们定义泛型类EntityA<TPrimKey>和EntityB<TprimKey>,其中有不同的子类:
using System.Collections.ObjectModel;
public interface IEntity<TPrimKey>
{
TPrimKey Key { get; set; }
}
public class Entities<TPrimKey> : KeyedCollection<TPrimKey, IEntity<TPrimKey>>
{
protected override TPrimKey GetKeyForItem( IEntity<TPrimKey> item )
{ return item.Key; }
}
public class EntityA<TPrimKey> : IEntity<TPrimKey>
{
public TPrimKey Key { get; set; }
}
public class MyEntityA1 : EntityA<int>
{
}
public class MyEntityA2 : EntityA<int>
{
}
public class EntityB<TPrimKey> : IEntity<TPrimKey>
{
public TPrimKey Key { get; set; }
}
public class MyEntityB1 : EntityB<int>
{
}
public class MyEntities : Entities<int>
{
public static void Test()
{
var entities = new MyEntities();
var entityA1 = new MyEntityA1();
entities.Add( entityA1 );
var entityA2 = new MyEntityA2();
entities.Add( entityA2 );
var entityB1 = new MyEntityB1();
entities.Add( entityB1 );
}
}注意:您不必使用接口来创建多个泛型子类EntityA和EntityB。我只是想说,如果你开始变得那么复杂,那就该考虑定义一个接口了,这样你就不会被“封闭”到一个基类中了。如果需要的话,定义接口可以轻松地重构类层次结构。
https://stackoverflow.com/questions/29006890
复制相似问题