C# 我有一个a级<;T>;: ;IEnumerable<;T>;,我想添加IEquatable<;A<;T>&燃气轮机;如果T ;: ;IEquatable<;T>;。我如何才能做到这一点,并保持IEnumerable以及?
我有一个树形类C# 我有一个a级<;T>;: ;IEnumerable<;T>;,我想添加IEquatable<;A<;T>&燃气轮机;如果T ;: ;IEquatable<;T>;。我如何才能做到这一点,并保持IEnumerable以及?,c#,inheritance,interface,C#,Inheritance,Interface,我有一个树形类Foo,它的接口是IFoo 我希望Foo能够在T:IEquatable时实现IEquatable(或者更一般地说,如果T:I我可能需要Foo:I以及其他实现的接口) 我尝试了以下代码: public interface IFoo<T> : IEnumerable<IFoo<T>> ... public class Foo<T> : IFoo<T> ... public interface IFooTwo<T&
Foo
,它的接口是IFoo
我希望Foo
能够在T:IEquatable
时实现IEquatable
(或者更一般地说,如果T:I
我可能需要Foo:I
以及其他实现的接口)
我尝试了以下代码:
public interface IFoo<T> : IEnumerable<IFoo<T>>
...
public class Foo<T> : IFoo<T>
...
public interface IFooTwo<T> : IFoo<T>, IEquatable<IFooTwo<T>>
where T : IEquatable<T>
...
public class FooTwo<T> : IFooTwo<T> {
... // I implement Equals
public bool NewMethod(FooTwo<T> Other) { ... }
}
公共接口IFoo:IEnumerable
...
公共类Foo:IFoo
...
公共接口IFooTwo:IFoo,IEquatable
其中T:i可满足
...
公共类FooTwo:IFooTwo{
…//我实现了Equals
公共bool-NewMethod(FooTwo-Other){…}
}
因此,现在我成功地实现了Equals
(我还覆盖了generic Equals,等等)
但是FooTwo
现在不实现IEnumerable
(而是实现IEnumerable
)
所以我有两个问题:
T:IEquatable
我希望能够为Foo
实现IEquatable
)?一种有条件的where
FooTwo
实现IEnumerable
使用
Foo IEnumerable
以快速简便的方式实现在
IEquatable
的特殊情况下,我对问题1有一个简单的答案。我可以测试T:IEquatable
,并在需要时更改IEquatable
的实现。然而,我仍然想知道如何在更一般的情况下做到这一点。对于问题1,您应该考虑您是否真的需要它<代码>IEquatable。在您的情况下,不应该有任何理由需要确保您使用的是IEquatable
equals,而不是object。例如,Tuple
就是这样做的。然后,您可以只使用一个没有约束的界面:
public interface IFoo<T> : IEnumerable<IFoo<T>>, IEquatable<IFoo<T>>
公共接口IFoo:IEnumerable,IEquatable
对于问题2,您可能也不需要这个IEnumerable
是,这意味着如果您有一个IEnumerable
,您可以将其分配给类型为IEnumerable
的变量,只要a
可以分配给B
。在您的情况下,这意味着如果您有,例如,一个采用IEnumerable
的方法也将接受IEnumerable
,因为IFooTwo:IFoo
但是,如果您希望将类
MyFoo:IFoo
的类型设置为IEnumerable
,则无法自动执行此操作。这是因为有一个有效的IEnumerable
实现是完全可能的,而不是IEnumerable
的实现。您可能应该将此需求视为一种设计气味,并尝试避免它。因为您实际上是在尝试让一些IFoo
对象成为IEquatable
对象,而另一些则不是,这显然与类型系统不一致,所以我会完全避免IEquatable
。使用IEqualityComparer
。只要提供一种方法,在给定IEqualityComparer
时创建IEqualityComparer
(或者使用T
的默认比较器,如果需要)
通过这样做,IFoo
对象没有义务进行自我比较,但是任何人都可以创建一种方法来比较IFoo
对象,只要他们知道如何比较底层对象
这还完全消除了对IFoo
的多个实现的需要,大大简化了整个代码库,并完全消除了其他问题
如何使FooTwo
实现IEnumerable
使用
Foo IEnumerable
以快速简便的方式实现
(如果您选择不按照我的建议更改处理平等的方式:)
如果您知道序列中的所有项实际上都是正确的类型,那么只需对序列使用Cast()
如果序列中的项目实际上不是
FooTwo
对象,那么您需要将项目投影到一个新序列中,在该序列中,您将每个IFoo
项目映射到FooTwo
项目。您如何确定它实现了IEnumerable
而不是IEnumerable
?您是对的,编辑编辑编辑问题时请注意预览窗格,尤其是在您试图讨论泛型类型参数时。我已经修复了您的代码一次,我没有心情再为您的编辑做一次(请尝试阅读当前显示的内容,看看它有多大意义)我不知道我的编辑有什么问题,我觉得一切都很好。阅读您的问题。编辑的第一行是“在IEquatable>的特例中,我对问题1有一个简单的答案。”。你真的想说“足够”>?不,您的意思是在那里有一个通用参数。但是,因为您没有将该部分标记为代码,所以它被解释为HTML标记,并吞没了其中的一部分。现在,对于问题1,我可以测试T:IEquatable,并更改我的IEquatable.Equals函数的实现。但是,如果它是另一个接口而不是IEquatable呢?但对于问题2,我不能将我的FooTwo类列举为我想做的FooTwo。(例如,foreach(FooTwo t in x)
将因xFooTwo
@celestinsint-Loup而失败。您可以始终在FooTwo
的声明中添加“:IEnumerable”。显然,如果x
(在您的示例中)具有静态类型IFooTwo
,而不是FooTwo
,这是不可能的