gpt4 book ai didi

c# - 具有多重实现的协变接口(interface)的泛型类型推断,如何解决它?

转载 作者:可可西里 更新时间:2023-11-01 09:12:58 32 4
gpt4 key购买 nike

考虑这个什么都不做的愚蠢程序:

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());
}
}

这表明A2C2同时实现 I<A1>I<A2> ,那B2同时实现 I<B1>I<B2> .

但是,将其修改为

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

显示在第一行和第三行,f的泛型类型参数无法从传递的参数中推断出来,但在第二行,它可以。

我明白编译器在这里做什么,所以不需要解释。但我该如何解决这个问题?有什么方法可以修改它,以便我可以在基类和派生类上定义接口(interface),同时在传递派生类时进行类型推断?

我的想法是寻找一种方法来“隐藏”基类的已实现接口(interface),以便编译器看不到它们并使用它们,即使它们确实存在。但是,C# 似乎没有提供这样做的选项。

澄清:在我愚蠢的示例程序中,A1工具 I以自身作为泛型类型参数。我的真实代码中确实有它,但我也有实现 I 的类使用不同的通用类型参数,并添加了 C1C2出于这个原因我的示例代码。

最佳答案

使用两个 F 变体(第二个仅用于调用另一个的类型推断)和一个继承自 I 的“覆盖”接口(interface) J,它什么也不做,它可以像这样完成:

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>

关于c# - 具有多重实现的协变接口(interface)的泛型类型推断,如何解决它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24037495/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com