泛型在 C# 中编译错误(但在 VB.NET 中有效)

本文关键字:NET VB 有效 但在 错误 编译 泛型 | 更新日期: 2023-09-27 17:56:34

我在泛型方面遇到了一个奇怪的问题。 我收到以下编译错误:

最佳重载方法匹配具有一些无效参数

参数"1":无法从"实体库"转换为"T"

错误在EntityWrapper.DoSomethingElse,见下文:

public abstract class EntityBase
{
    public static bool DoSomething<T>(T entity, string someArg) where T : EntityBase
    {
        // implementation doesn't matter
        return true;
    }
}
public class EntityWrapper<T> where T : EntityBase
{
    private EntityBase _entity;
    public void DoSomethingElse()
    {
        EntityBase.DoSomething<T>(_entity, "some arg"); // <--- error here ---
    }
}

我有此代码的 VB.NET 版本,可以很好地编译和执行,因此我希望它可以在 C# 中工作。

我在这里错过了什么?

最后,虽然这无关紧要,但这是VS2008,.NET 3.5。

泛型在 C# 中编译错误(但在 VB.NET 中有效)

让我告诉你为什么你的代码是无效的: 想象一下,我创建了一个EntityWrapper<MyEntity>,其中MyEntity派生自BaseEntity

var myWrapper = new EntityWrapper<MyEntity>();

EntityWrapper 内部会发生什么?这:

EntityBase.DoSomething<T>(_entity, "some arg");

成为

EntityBase.DoSomething<MyEntity>(_entity, "some arg");

这是无效的:DoSomething 期望MyEntity作为其第一个参数,但您传递了一个BaseEntity。这就是错误Argument '1': cannot convert from 'EntityBase' to 'T'的意思。


如何解决这个问题?在 EntityWrapper 中,按如下所示声明_entity

private T _entity;

这允许您将_entity静态类型保留BaseEntity 的具体子类型。

只需省略<T>即可。类型推断会弄清楚:

EntityBase.DoSomething(_entity, "some arg"); 

也许您可以按如下方式调用该方法:

EntityBase.DoSomething<EntityBase>(_entity, "some arg");

编译器无法将_entityEntityBase)强制转换为T(在方法调用中指定)。