Why can't I use a generic method to implement multiple typed interfaces in C#?
https://softwareengineering.stackexchange.com/questions/403250
-
06-03-2021 - |
문제
public class B { }
public class C { }
public class D { }
public class E { }
public class A :
IRetrievable<B, C>,
IRetrievable<D, E>
{
public TValue Retrieve<TKey, TValue>(TKey input)
{
throw new NotImplementedException();
}
}
What is the reason I can't do this? Visual Studio is telling me that the interfaces aren't being implemented, even though they could be via putting types B, C and D, E in TKey, TValue, respectively.
해결책
The generic type will have the actual types used in the code added at compile time.
Here you are confusing Method and class generic types
public class B { }
public class C { }
public class D { }
public class E { }
public class A :
IRetrievable<B, C> //interface not implemented!!
{
public TValue Retrieve<TKey, TValue>(TKey input)
{
throw new NotImplementedException();
}
}
public interface IRetrievable<T1, T2>
{
T1 Retrieve(T2 input);
}
public void Main()
{
var a = new A()
a.Retrieve<D,E>(new D());
}
Here A should implement IRetrievable for A and B. but the method is called with D and E and so a class A_DandE will be created which doesn't match the interface
A must implement the interface as specified, but the actual implementation is defined by the calling code and as such cant be guaranteed when you just compile A on its own
working code:
public class A :
IRetrievable<B, C>,
IRetrievable<D, E>
{
public B Retrieve(C input)
{
throw new NotImplementedException();
}
public D Retrieve(E input)
{
throw new NotImplementedException();
}
}
Here A implements both methods as defined by the interfaces
다른 팁
Use composition instead. Pass implementations of your two interfaces as parameters into the constructor of your class, and assign each one to an IRetrievable<T, K>
member of your class.
Alternatively, inherit from a dual interface:
public interface IDualRetrievable
{
IRetrievable<T, K> Retrievable1 { get; set; }
IRetrievable<T, K> Retrievable2 { get; set; }
}
public class MyClass : IDualRetrievable
If you wish, you can pass the same implementation for each interface instance.