繁体   English   中英

C#通用类问题

[英]C# Generic Class Question

我正在开发一个类库,并且在泛型方面遇到了一些麻烦。 我有一个ITransaction接口,其中包含ITransactionItem的集合。 每个ITranscation可以是CapitalCallDistribution CapitalCallITransaction但具有一些其他属性。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM