[英]C# Generic Class Question
我正在开发一个类库,并且在泛型方面遇到了一些麻烦。 我有一个ITransaction
接口,其中包含ITransactionItem
的集合。 每个ITranscation
可以是CapitalCall
或Distribution
。 CapitalCall
是ITransaction
但具有一些其他属性。 CapitalCallItem
是一个ITransactionItem
,具有一些其他属性。 一个CapitalCall
具有集合CapitalCallItems
。 同样,存在一个带有Distribution
集合的DistributionItem
。
我尝试使Transaction
接口通用:
interface ITransactionBase<TItem>
where TItem: ITransactionItem
{
List<TItem> ITransactionItems
{
get;
set;
}
}
当我实现它时,这完美地工作:
class CapitalCall : ITransactionBase<CapitalCallItem>
现在,集合中的所有项目都为CapitalCallItem
类型。
我遇到以下问题。 我想知道ITranscationItem
上的关联ITransaction
。 我创建的属性ITransactionItem
类型的表ITranscation
。 当我使用此属性时,不再将其键入正确的类:
var capitalCall = new CapitalCall();
var trans = capitalCall.TransactionItems[0].Transaction;
// trans is now of the base type ITransaction, instead of typed to CapitalCall.
我曾尝试使ITransactionLineItem
接口也使用泛型,但是当我尝试声明它时,我陷入了递归泛型的噩梦。 对此建模的正确方法是什么?
这项工作会:
interface ITransaction<TAction, TItems>
where TItems : ITransactionItem<TAction, TItems>
where TAction : ITransaction<TAction, TItems>
interface ITransactionItem<TAction, TItems>
where TItems : ITransactionItem<TAction, TItems>
where TAction : ITransaction<TAction, TItems>
我对如何使用接口本身感到困惑-如果我想要混合ITransactionItem
的集合而不指定类型怎么办? 另外,我还应该补充一点,我具有实现该接口的基本Transaction / Transaction项目类,并且CapitalCall / Dist继承自该类。
是的,这种相互递归的泛型声明可以工作,但是会使事情变得非常复杂-我从经验中知道。 如果您想要一个类似的例子,请从我的协议缓冲区端口查看以下声明 :
public interface IMessage<TMessage, TBuilder> : IMessage<TMessage>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
IBuilder<,>
具有等效功能。
该声明还演示回答你的最后一个问题:如果你的界面的某些部分不需要知道交易的确切类型,您可以在“少通用的”基本接口声明它们。 因此,您可以:
interface ITransaction<TAction, TItems> : ITransaction
where TItems : ITransactionItem<TAction, TItems>
where TAction : ITransaction<TAction, TItems>
例如,其中ITransaction
是一个非通用接口。
再说一次,这不是为了胆小者。 就我而言,我可以避免它,因为几乎没有人使用原始接口-所有实现都是自动生成的,而客户端代码则使用那些非泛型实现。 在让开发人员实际使用日常资源之前,我会经过漫长而艰辛的思考。
是的,据我所知,您写下的接口应该可以工作。 这样的“递归”声明与泛型一起使用很好,但是问题是您是否真的需要首先使这些泛型成为现实? 递归声明是一种不常用的东西,因此对于其他使用您的类的人来说可能很难理解。
至于使用该接口本身,您仍然可以制作一个通用性较低的接口并实现它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.