使用两个属性公开相同的集合集合

-4 .net c# generics typing covariance

注意:请不要在当前状态下重视此问题.一旦我能够解决我的潜在问题,我就会意识到我会很难重新解释这个问题,以真正反映出它的动机和决议是什么.Anwyay,我将在接下来的几天里尝试对其进行改写,以便它对未来的访问者有用,并且回答者可能有机会调整答案.即使是我的自动回答也没有反映出这个问题,所以它对社区有用......

假设我有一个这样的界面:

public interface IHasMany<T>
{
      ISet<T> Items { get; }
}
Run Code Online (Sandbox Code Playgroud)

一个类实现如下:

public class X : IHasMany<IWhatever>
{
     public ISet<Whatever> Whatevers { get; } = new HashSet<Whatever>();
     ISet<IWhatever> IHasMany<IWhatever>.Items { get; }
}
Run Code Online (Sandbox Code Playgroud)

由于集合泛型类型不能协变(我理解为什么它被设计阻止的背景),所以没有简单的路径可以同时公开一组给定的接口实现和一组与接口同时输入的相同实现.

为了找到一个理想情况下我不需要实现某种同步或更改跟踪来维护两个不同集合的解决方案,我正在摸不着头脑......

请注意,IHasMany<T>.Items必须仍然可写,否则就像键入它一样容易IEnumerable<IWhatever>并继续前进......

Ser*_*rvy 5

C#不会阻止你的集合变成协变,因为C#团队并不打算弄清楚如何实现它.相反,它在C#中是不可能的,因为它在概念上是不可能的.您根本无法将其ISet<Whatever>视为一个ISet<IWhatever>因为您可以将项目添加到非ISet<IWhatever>类型的项目中Whatever,并且如果实际对象是a ISet<Whatever>,则不允许添加非类型的项目Whatever.

你可以拥有一个类型的属性IReadOnlySet<IWhatever>并使其变得协变,但是因为你想拥有一个可变的集合,所以没有办法让它工作.你必须让你的实际底层集合成为一组IWhatever对象,或者具有X实现IHasMany<Whatever>而不是IHasMany<IWhatever>,因为它只是你真正希望它实现的前者合约,而不是后者.

  • @MatíasFidemraizer这是你问题的答案.这肯定不是评论.我还特别提到你发布的"答案"作为你可能应该做的事情之一,即使你的"答案"实际上没有回答你自己的问题,因为它没有做你的问题所要求的它应该做,因此应该只是一个评论. (2认同)
  • 不,你的回答不是*问题的答案.它没有回答你提出的问题.如果您实际上问了一个代表您实际问题的问题,而不是明确说明您不能使用能够真正解决您问题的解决方案,那么您的问题就会解决您的问题,但是您的问题被拒绝了选项*实际上是答案.这就是为什么你需要非常小心你如何表达你的问题,以及你的要求. (2认同)
  • @MatíasFidemraizer我认为你发布了一个不正确的答案,但实际上没有回答你的问题而不是接受正确的答案,因为你没有问你想问的问题,这是个好主意吗?不,不是真的. (2认同)
  • @MatíasFidemraizer你问过如何处理一个集合,好像它是协变的.你没有使用这些词,但这就是你的要求.你希望能够将`ISet <Whatever>`视为`ISet <IWhatever>`而不实际拥有多个底层集.*这就是通用协方差*.这就是你的问题实际上要求的一切.你根本没有提供关于如何使用界面的上下文,因此没有可能解决你实际拥有的问题,因为*你没有解释你实际上有什么问题*.你不能指望人们读懂你的想法. (2认同)
  • @MatíasFidemraizer他们不适用.这些问题询问问题*描述问题*的情况,然后询问与该问题相关的特定问题.您提供了一个特定问题*,根本没有上下文*,然后根据问题中未提供的大量信息发布答案,而没有解决实际问题.同样,如果您希望人们帮助您提供实际问题的解决方案,而不是回答您提出的具体问题,那么至少您需要*陈述您的实际问题*. (2认同)
  • @MatíasFidemraizer你是对的,你的问题没有意义.询问如何做一些你知道不可能的事情确实不是一个明智的事情.然而那就是你所问的,所以这一切都可以回答.如果你知道你不能同心对待你的套装,那么你不应该问如何协同对待你的套装,你应该已经提出了你的实际问题,以便那些*不需要同时处理你的套装的解决方案*可以提供. (2认同)
  • @MatíasFidemraizer我试图帮助您了解问题的问题,以便在您提出未来问题而不是重复相同的错误时修复它们.很明显,你没有兴趣从错误或改进中学习,这是不幸的.希望将来你会变得谦虚,意识到实际上有一点点可能性,你可能没有真正完成所有事情,并且可能有一些东西可以让你改进,而不是要求你的思想回答你的想法为了回答. (2认同)