[英]C# call generic interface method from non generic parent interface without dynamic
Say we have a non generic base interface, with a generic inheriting interface: 假设我们有一个非通用的基本接口,带有一个通用的继承接口:
public interface IFoo { }
public interface IBar<T, K> : IFoo {
K Do(T t);
}
public class BarImpl : IBar<Type, AnotherType> {
public AnotherType Do(Type type) {
return new AnotherType(type);
}
}
I need to create a factory which returns an IFoo instance, but using the returned instance I need to be able to call the derived types Do(T), which isn't available. 我需要创建一个返回IFoo实例的工厂,但是使用返回的实例,我需要能够调用派生类型Do(T),该类型不可用。
public class FooFactory() {
IFoo Get() {
// simplified, in reality i am returning the correct
// type by checking the generic interface
// types to get an object from a stored list
// of implementations
return BarImpl();
}
}
// Now in another class
public void DoFoo() {
IFoo iFoo = new FooFactory().Get();
// Need to be able to call iFoo.Do(Type) but cannot
}
The only way I have been able to get this to work is to create a dynamic object, instead of IFoo, and then call Do() - which does work in my case but I lose some type safety which i'd prefer to keep. 我能够使它起作用的唯一方法是创建一个动态对象而不是IFoo,然后调用Do()-在我的情况下确实有效,但是我失去了一些我希望保留的类型安全性。
My question is can I re-engineer this to be able to get access to the derived interfaces method, whilst still being able to maintain a list (and subsequently factory method return type) of IFoo???? 我的问题是我可以对此进行重新设计,以便能够访问派生的接口方法,同时仍然能够维护IFoo的列表(以及随后的工厂方法返回类型)吗?
You expect or want type safety, but think about it this way: 您期望或想要类型安全性,但是可以这样考虑:
Do
, Get
needs to return a type which defines that method. Do
, Get
需要返回定义该方法的类型。 IFoo
does not have it, but IBar<T, K>
does. IFoo
没有它,但是IBar<T, K>
有。 Get
however returns an IFoo
object which is not guaranteed to be a IBar<T, K>
. Get
返回一个IFoo
对象,该对象不能保证是IBar<T, K>
。 Get
would make sure that only a IBar<T, K>
is returned, there is no way the type system would know this without actually returning that type . Get
的实现可以确保仅返回IBar<T, K>
,类型系统也不会在不实际返回该类型的情况下知道这一点 。 Do
method, the type would be unclear: You need to pass it an object of type T
. Do
方法的类型,则该类型尚不清楚:您需要向其传递类型为T
的对象。 But the returned IFoo
or IBar<T, K>
does not necessarily use the same type T
that you wanted to pass to Do
. IFoo
或IBar<T, K>
不一定使用您想要传递给Do
的相同类型T
Get
would provide this (like “Get me an IBar<T, K>
that accepts the type T
”) and the type system would have a way to reflect this, then this still wouldn't say anything about K
. Get
的实现可以提供此信息(例如“给我一个接受类型T
的IBar<T, K>
”),并且类型系统也有办法反映这一点,那么对于K
来说,它什么也没说。 For a known T
, it could still be an IBar<T, int>
, or an IBar<T, string>
. T
,它仍然可以是IBar<T, int>
或IBar<T, string>
。 And there is actually no way to know that without actually having the concrete type. Do
. Do
返回的类型。 My point is that you only need generic types, when you actually have a reason to maintain a concrete type. 我的观点是,当您实际上有理由维护具体类型时,只需要通用类型。 Usually if you call a generic method or a method of a generic type from another non-generic method, then you either have a discrete set of types you're working with, or you don't actually need the generic type information.
通常,如果您从另一个非泛型方法中调用一个泛型方法或一个泛型类型的方法,那么您要么拥有一组正在使用的离散类型,要么实际上不需要泛型类型信息。
So maybe you're better off introducing a non-generic IBar
type here: 因此,也许最好在这里引入非通用的
IBar
类型:
interface IBar
{
object Do(object t);
}
interface IBar<T, K> : IBar
{
K Do(T t);
}
public class BarImpl : IBar<Type, AnotherType>
{
public AnotherType Do(Type type)
{
return new AnotherType(type);
}
public object Do(object t)
{
return Do((Type) t);
}
}
Then you could make Get
return an IBar
instead, and you have a way to call Do
. 然后,你可以把
Get
返回的IBar
,而是和你有一个方法来调用Do
。
Btw. 顺便说一句。 this pattern is used pretty commonly in the BCL, eg
IEnumerable<T>
and IEnumerable
. 此模式在BCL中非常常用,例如
IEnumerable<T>
和IEnumerable
。
You could add a object DoIt()
method to IFoo
, then BarImpl
would implement it: 您可以在
IFoo
添加一个object DoIt()
方法,然后BarImpl
将其实现:
public object DoIt()
{
return Do(typeof(T));
}
The problem here is that you would then need to cast the return of DoIt
to the actual type. 这里的问题是您然后需要将
DoIt
的返回值DoIt
转换为实际类型。 But you won't know apriori what that is. 但是您不会知道apriori是什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.