gpt4 book ai didi

c# - 在 C# 类型约束中指定 "any subclass"而不是 "one particular subclass"

转载 作者:太空狗 更新时间:2023-10-29 22:20:12 26 4
gpt4 key购买 nike

如果我想编写一个采用可变数量“TDerived”的方法,其中 TDerived 是类“Base”的任何子类,有什么办法可以做到这一点吗?

以下代码仅适用于单个特定的指定子类:

void doStuff<TDerived>(params TDerived[] args) where TDerived : Base
{
//stuff
}

即如果我有

class Super { }
class Sub0 : Super { }
class Sub1 : Super { }

那我做不到

Sub0 s0 = new Sub0();
Sub1 s1 = new Sub1();
doStuff(s0, s1);

因为我得到“最佳重载匹配...有一些无效参数”。

无论编译器如何处理类型约束和可变参数函数,这似乎(据我所知)完全是类型安全的。我知道我可以转换,但如果这是类型安全的,为什么不允许呢?

编辑:

也许是一个更有说服力的例子:

void doStuff<TDerived>(params SomeReadOnlyCollection<TDerived>[] args) where TDerived : Base
{
foreach(var list in args)
{
foreach(TDerived thing in list)
{
//stuff
}
}
}

最佳答案

TDerived需要能够解析为单一类型。在您的示例中,它可以解析的唯一类型是 Super ,但编译器不会实现这一飞跃。您可以为编译器实现这一飞跃。

doStuff(new Super[] { s0, s1 });
doStuff<Super>(s0, s1);

关于您的更新,考虑(而不是通用方法)定义一个接受 IEnumerable<ISuper> 的方法,这将支持派生类型,因为 IEnumerable<T>是协变的(从 .NET 4 开始)。 IEnumerable<T>本质上也是只读和只进的,如果你有 foreach 就完美了环形。完整的工作示例:

class Program
{
static void Main()
{
var sub0s = new Sub0[] { new Sub0() };
var sub1s = new List<Sub1> { new Sub1() };
doStuff(sub0s, sub1s);
}

static void doStuff(params IEnumerable<ISuper>[] args)
{
foreach (var sequence in args)
{
foreach (var obj in sequence)
{
Console.WriteLine(obj.GetType());
// you have the ability to invoke any method or access
// any property defined on ISuper
}
}
}
}

interface ISuper { }
class Super : ISuper { }
class Sub0 : Super { }
class Sub1 : Super { }

IEnumerable<T>自 .NET 2.0 起由 BCL 集合实现,包括 T[] , List<T> , ReadOnlyCollection<T> , HashSet<T>

关于c# - 在 C# 类型约束中指定 "any subclass"而不是 "one particular subclass",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7830422/

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