加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 通用类型推理与多重实现的协变接口,如何解决?

发布时间:2020-12-15 06:24:37 所属栏目:百科 来源:网络整理
导读:考虑这个愚蠢的程序,什么都不做: interface Iout T { }class A1 : IA1 { }class A2 : A1,IA2 { }class B1 { }class B2 : B1,IB2 { }class C1 : IA1 { }class C2 : C1,IA2 { }static class Program{ static void fT(IT obj) { } static void Main() { fA1(ne
考虑这个愚蠢的程序,什么都不做:
interface I<out T> { }
class A1 : I<A1> { }
class A2 : A1,I<A2> { }
class B1 { }
class B2 : B1,I<B2> { }
class C1 : I<A1> { }
class C2 : C1,I<A2> { }

static class Program
{
    static void f<T>(I<T> obj)
    {
    }

    static void Main()
    {
        f<A1>(new A2());
        f<A2>(new A2());
        f<B1>(new B2());
        f<B2>(new B2());
        f<A1>(new C2());
        f<A2>(new C2());
    }
}

这表明,A2和C2实现了I< A1>和I A2,并且B2实现了两个I B1.和I B2.

但是,将其修改为

static void Main()
{
    f(new A2());
    f(new B2());
    f(new C2());
}

表示在第一行和第三行,f的泛型类型参数不能从传递的参数推断,但在第二行,它可以是.

我明白编译器在这里做什么,所以不需要解释.但是我该如何解决这个问题?有没有办法修改这个,以便我可以在基类和派生类上定义接口,但是在传递派生类时,还有类型推断工作?

我想到的是寻找一种方法来“隐藏”一个基类实现的接口,这样编译器就不会看到它们并使用它们,即使它们存在.但是,C#似乎没有提供这样的选择.

澄清:在我的愚蠢的示例程序中,A1将自己实现为通用类型参数.我确实有我的真实代码,但我也有类实现我与一个不同的通用类型的参数,并添加了C1和C2到我的示例代码为此原因.

解决方法

使用两个F变体(第二个仅用于调用另一个的类型推断)和“继承”接口J继承自I,它不会像这样做:
using System;
using System.Threading;


interface I<out T>
{
    void Print();
}

interface J<out T> : I<T> { }

class A : I<C>
{
    void I<C>.Print()
    {
        Console.WriteLine("A: I<C>");
    }
}

class B {}

class C : B { }

class D1 : I<A>
{
    void I<A>.Print()
    {
        Console.WriteLine("D1: I<A>");
    }
}

class D2 : D1,J<B>
{
    void I<B>.Print()
    {
        Console.WriteLine("D2: I<B>");
    }
}

class D3 : D1,J<C>
{
    void I<C>.Print()
    {
        Console.WriteLine("D3: I<C>");
    }
}

class D4 : A,J<B>
{
    void I<B>.Print()
    {
        Console.WriteLine("D4: I<B>");
    }
}

static class Program
{
    static void f<T>(J<T> obj)
    {
        f((I<T>)obj);
    }

    static void f<T>(I<T> obj)
    {
        obj.Print();
    }

    static void Main()
    {

        f<A>(new D2());
        f(new D2());

        f(new D3());

        f(new D4());
        f<C>(new D4());

        Console.ReadKey();
    }
}

输出:

D1: I<A>
D2: I<B>
D3: I<C>
D4: I<B>
A: I<C>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读