在C#中,是否有可能为类型公开其成员类型的接口作为自己的接口

我不确定如何清楚地说出这个问题,所以下面是同一个问题的另外两个版本:

  • 一个结构/类可以通过委托给它的字段/属性来实现一个接口吗?
  • 我可以将由字段/属性类型实现的接口映射到其结构/类吗?

这里是一个代码示例添加伪语法,希望显示我的意思是:

public class School : IEnumerable<Student> { private List<Student> students expose IEnumerable<Student>; ... } 

如果这不是现在可能的话,这有可能吗? …或者这种方法存在一些严重的问题吗? 我认为这可能只是语法糖来摆脱锅炉板代码,否则将功能相同。 例:

 public class School : IEnumerable<Student> { private List<Student> students; ... public IEnumerator<Student> GetEnumerator() { return students.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } 

}

这当然是一个非常人为和最小的例子。 当为它设计界面时,好处会更大,特别是当有很多方法“映射”的时候。

更新:我知道我提供了一个可怕的例子,但我只是想用最简单的例子。 问题的核心不在于具体的情况。 说了这么多,我的例子很糟糕。 所以,为了更好地帮助那些喜欢看到好榜样的人陪伴一个问题,这里有一个更好的例子:

 public interface IValidPeriod { DateTime ValidFrom { get; } DateTime ValidTo { get; } DateTime ValidThrough { get; } int DaysValid { get; } } public class ValidPeriod : IValidPeriod { public DateTime ValidFrom { get; private set; } public DateTime ValidTo { get; private set; } public DateTime ValidThrough { get { return ValidTo.AddDays(1); } } public int DaysValid { get { return (ValidTo - ValidFrom).Days; } } public ValidPeriod(DateTime from, DateTime to) { ValidFrom = from; ValidTo = to; } } public class Agreement : IValidPeriod { ... public ValidPeriod ValidPeriod { get; private set; } exposes IValidPeriod; ... } public class Contract : IValidPeriod, ICancellable { private Agreement agreement exposes IValidPeriod; ... } public class Payment : IValidPeriod, ICancellable { public DateTime StartDate { get; set; } private ValidPeriod validPeriod { get { return new ValidPeriod(StartDate, DateTime.Max); } } exposes IValidPeriod; ... } public static class SomeUtility { public static void CancelIfValidBefore<T>(List<T> items, DateTime date) where T : IValidPeriod, ICancellable { ... } } 

我发布了自己的问题的答案,这要归功于Wiktor Zychla通过链接对该问题发表的评论:

github.com/dotnet/roslyn/issues/13952

链接是针对一个功能的建议,这正是我发布这个问题时所想到的。 所以我的问题的答案是 – 不,这是不可能的。

该链接包含一个良好的讨论和进一步信息的链接。 建议的语法是我会重新考虑的唯一的东西。 其中一个评论者提供了一个显示Kotlin语法的链接 ,我认为这是目前为止最好的,比我提出的更好(尽管我没有提出语法,只是试图说明我的问题)。

以下是使用Kotlin语法的我国代表团示例的更新版本:

 public class School : IEnumerable<Student> by students { private List<Student> students; ... } 
  1. 不,你所描述的方式是不可能的。 你如何告诉编译器一个“暴露”运算符优先于任何其他? 当你编写暴露相同接口的两个内部对象时会发生什么? 或者当两个“暴露”对象具有共享属性或同名的函数?

  2. 你从这个符号中获得了什么? 事实证明,你所要求的是有可能的,有一个限制。 那就是你只能“暴露”一种类型……我们称之为继承:)如果你从你想要“暴露”的类型继承,你将得到相同的逻辑结果。 你所描述的是复制一个接口的实现,但你想从课堂外隐藏这个事实? 这听起来对我来说更多的是一种反作用,它会阻碍更多的事情。

  3. 将这些对象作为公共属性公开显示是非常简单的,那么您不必在类型接口中进行任何特殊的考虑或检查重复。 以这种方式“映射”属性的唯一原因是因为您想要替换或修改基础类型的行为。 否则,你会省下麻烦,只是暴露它

  4. 你的类实现IEnumerable不是一个好设计,将有许多有经验的开发人员在他们的eys或简单地投下来,当他们看到这个问题

我不得不查看它,但是我记得在SO上有类似的请求: 为什么不从List继承

在这个话题中,围绕这个话题有许多关于SO的很好的健康讨论。 我们在这里是你的朋友,但这是我们许多人不希望用C#打开的一堆蠕虫。 我完全支持在其他语言中进行探索,并会喜欢阅读旅程,但最终我们没有保存足够的按键笔画,也没有提供一个允许更快编译或运行时策略的构造,使其成为一个很好的功能请求