C#从非泛型父接口调用泛型接口方法,无需动态

C#从非泛型父接口调用泛型接口方法,无需动态,c#,.net,generics,dynamic,C#,.net,Generics,Dynamic,假设我们有一个非泛型基接口,带有泛型继承接口: 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); }

假设我们有一个非泛型基接口,带有泛型继承接口:

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);
    }
}
我唯一能够让它工作的方法是创建一个动态对象,而不是IFoo,然后调用Do()——在我的情况下,它确实可以工作,但我失去了一些我更愿意保留的类型安全性


我的问题是,我是否可以重新设计它,以便能够访问派生接口方法,同时仍然能够维护IFoo???的列表(以及随后的工厂方法返回类型)

您可以将
对象DoIt()
方法添加到
IFoo
,然后
BarImpl
将实现它:

public object DoIt()
{
    return Do(typeof(T));
}

这里的问题是,然后需要将
DoIt
的返回转换为实际类型。但是您不知道它是什么。

您可以将
对象DoIt()
方法添加到
IFoo
,然后
BarImpl
将实现它:

public object DoIt()
{
    return Do(typeof(T));
}

这里的问题是,然后需要将
DoIt
的返回转换为实际类型。但您不知道这是什么。

您期望或想要类型安全,但请这样考虑:

  • 为了能够调用
    Do
    Get
    需要返回定义该方法的类型
    IFoo
    没有,但IBar有<但是,code>Get返回一个
    IFoo
    对象,该对象不能保证是
    IBar
  • 即使
    Get
    的实现将确保只返回
    IBar
    ,类型系统也无法在不实际返回该类型的情况下知道这一点
  • 假设您可以返回一个允许您调用
    Do
    方法的类型,那么该类型将不清楚:您需要向它传递一个
    T
    类型的对象。但是返回的
    IFoo
    IBar
    不一定使用要传递给
    Do
    的相同类型
    T
  • 即使
    Get
    的实现提供了这一点(比如“给我一个接受类型
    T
    IBar
    ”),并且类型系统将有一种方法来反映这一点,那么这仍然不能说明有关
    K
    的任何内容。对于已知的
    T
    ,它仍然可以是
    IBar
    ,或
    IBar
    。实际上,如果没有具体的类型,就无法知道这一点
  • 尽管如此,假设这将与类型系统一起工作:这实际上有什么用途?您可以使用正确的类型化参数调用泛型类型的方法:但是返回值仍然没有具体的类型。对于从
    Do
    返回的类型,您不能说任何内容
我的观点是,当您实际上有理由维护一个具体类型时,您只需要泛型类型。通常,如果您从另一个非泛型方法调用泛型方法或泛型类型的方法,那么您要么拥有正在使用的离散类型集,要么实际上不需要泛型类型信息

因此,您最好在此处引入非通用的
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);
    }
}
接口IBar
{
对象Do(对象t);
}
接口IBar:IBar
{
K-Do(T);
}
公共类BarImpl:IBar
{
公共另一类型Do(类型)
{
返回新的其他类型(类型);
}
公共对象Do(对象t)
{
返回Do((类型)t);
}
}
然后您可以让
Get
返回一个
IBar
,这样您就可以调用
Do


顺便说一句,这种模式在BCL中非常常用,例如和。

您期望或想要类型安全,但请这样考虑:

  • 为了能够调用
    Do
    Get
    需要返回定义该方法的类型
    IFoo
    没有,但IBar有<但是,code>Get返回一个
    IFoo
    对象,该对象不能保证是
    IBar
  • 即使
    Get
    的实现将确保只返回
    IBar
    ,类型系统也无法在不实际返回该类型的情况下知道这一点
  • 假设您可以返回一个允许您调用
    Do
    方法的类型,那么该类型将不清楚:您需要向它传递一个
    T
    类型的对象。但是返回的
    IFoo
    IBar
    不一定使用要传递给
    Do
    的相同类型
    T
  • 即使
    Get
    的实现提供了这一点(比如“给我一个接受类型
    T
    IBar
    ”),并且类型系统将有一种方法来反映这一点,那么这仍然不能说明有关
    K
    的任何内容。对于已知的
    T
    ,它仍然可以是
    IBar
    ,或
    IBar
    。实际上,如果没有具体的类型,就无法知道这一点
  • 尽管如此,假设这将与类型系统一起工作:这实际上有什么用途?您可以使用正确的类型化参数调用泛型类型的方法:但是返回值仍然没有具体的类型。对于从
    Do
    返回的类型,您不能说任何内容
我的观点是,当您实际上有理由维护一个具体类型时,您只需要泛型类型。通常,如果您从另一个非泛型方法调用泛型方法或泛型类型的方法,那么您要么拥有正在使用的离散类型集,要么实际上不需要泛型类型信息

因此,您最好在此处引入非通用的
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);
    }
}
接口IBar
{
对象Do(对象t);
}
接口IBar:IBar
{
K-Do(T);
}
公共类BarImpl:IBar
{
公共另一类型Do(类型)
{
ret