I have a Tree-type class Foo<T> with its interface IFoo<T>.
I want Foo<T> to be able to implement IEquatable<Foo<T>> when T : IEquatable<T> (or more generally if T : I<T> i might want Foo<T> : I<Foo<T>> in addition of other implemented interfaces).
I tried the pseudo-following code :
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) { ... }
}
So now I have succesfully implemented Equals (I also overrided the geniric Equals, etc.).
But FooTwo<T> now does not implement IEnumerable<IFooTwo<T>> (instead it implements IEnumerable<IFoo<T>>).
So I have two questions :
T : IEquatable<T> I want to be able to implement IEquatable<Foo<T>> for Foo<T>) ? A sort of conditional where.FooTwo<T> implements IEnumerable <FooTwo<T>> using
Foo<T> IEnumerable implementation in a quick and easy way ?edit :
In the special case of IEquatable<Foo<T>>, I have a simple answer for question 1. I can test if T:IEquatable<T> and change my implementation of IEquatable<Foo<T>> if needed. However I am still wondering how to do it in a more general case.
For question 1, you should think about whether you really need this. IEquatable<T> mostly exists for performance reasons relating to value types. In your case, there shouldn't really be any reason that you need to make sure you're using the IEquatable equals rather than the object one. This is what, for example, Tuple<T> does. Then you can just have a single interface with no constraint:
public interface IFoo<T> : IEnumerable<IFoo<T>>, IEquatable<IFoo<T>>
For question 2, you may not need this either. IEnumerable<T> is covariant, meaning that if you have an IEnumerable<A>, you can assign this to a variable of type IEnumerable<B>, as long as A can be assigned to B. In your case, this means if you have, e.g., a method that takes an IEnumerable<IFoo<T>> will also accept an IEnumerable<IFooTwo<T>> since IFooTwo<T> : IFoo<T>
However, if you want to have, say, a class MyFoo<T> : IFoo<T> to be of type IEnumerable<MyFoo<T>>, there's no way to do that automatically. This is because it's perfectly possible to have a valid implementation of IEnumerable<IFoo<T>> which isn't also an implementation of IEnumerable<MyFoo<T>>. You should probably treat this requirement as a design smell and try to avoid it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With