C# 模板函数:访问静态抽象成员会引发 System.BadImageFormatException

C# Template Function: Accessing static abstract members throws System.BadImageFormatException

提问人:MP9 提问时间:6/3/2023 最后编辑:MP9 更新时间:6/3/2023 访问量:36

问:

我以前问过类似的问题,这或多或少是一个后续问题。 (C# 模板函数:不能在“T”中执行非虚拟成员查找,因为它是一个类型参数)

我想在模板函数中访问一个静态抽象变量:

public static T AsType<T>(...) where T : ICode
{
    //...
    if(InterfaceCode != T.InterfaceCode) return null;
    if(SubtypeCode != T.SubtypeCode) return null;
    //...
}
        

public interface ICode
{
    public static abstract ushort SubtypeCode { get; }
    public static abstract ushort InterfaceCode { get; }
}

每当我尝试运行此代码时,都会抛出以下异常:

'T.InterfaceCode' threw an exception of type 'System.BadImageFormatException'

我最近将我的项目从 .NET Core 3.1 升级到 .NET 7,因为我想使用这个“功能”(这是我最后一个问题的建议解决方案)

如果您需要更多背景信息,请告诉我。感谢您的帮助!

可重现的示例:

internal class Program
    {
        static void Main(string[] args)
        {
            AsType<Test>(1, 3);
        }
        public static T AsType<T>(ushort InterfaceCode, ushort SubtypeCode) where T : ICode
        {
            //...
            if (InterfaceCode != T.InterfaceCode) return default(T);
            if (SubtypeCode != T.SubtypeCode) return default(T);
            //...
            return default(T);
        }
        public interface ICode
        {
            public static abstract ushort SubtypeCode { get; }
            public static abstract ushort InterfaceCode { get; }
        }
        public class Item : ICode
        {
            public static ushort SubtypeCode { get; } = 1;
            public static ushort InterfaceCode { get; } = 2;
        }
        public class Test : Item
        {
            public static new ushort InterfaceCode { get; } = 1;
            public static new ushort SubtypeCode { get; } = 3;
        }
    }

注意:它不会抛出此错误。它只在调试环境 (VS2022) 中显示时显示。T.InterfaceCode

C# 模板 摘要

评论

0赞 Jon Skeet 6/3/2023
请您提供一个最小的可重现示例,以便我们可以重现该问题而无需猜测您的代码的其余部分?(足以重现问题 - 我们不需要您的任何真实业务代码。
0赞 MP9 6/3/2023
@JonSkeet这应该做,对吧?
0赞 Jon Skeet 6/3/2023
好吧,如果它在类声明中会稍微好一些,这样我们就可以从字面上复制/粘贴/编译/运行,但它已经足够接近了。但是,当我将其放入 .NET 7 控制台应用中的类中时,它不会产生异常。只是该代码会为您抛出异常吗?你能确认你的 TargetFramework 只是 net7.0 吗?Program
0赞 MP9 6/3/2023
@JonSkeet调试(单步执行)并将鼠标悬停在它上面时显示,并且在继承类 Item 时它似乎也不起作用 (...)T.InterfaceCode'T.InterfaceCode' threw an exception of type 'System.BadImageFormatException'class Test : Item {}
1赞 Jon Skeet 6/3/2023
但是,当您只是从命令行运行时会发生什么?如果这仅在调试器中的代码单步执行时显示,则这是重要信息。dotnet run

答:

0赞 MP9 6/3/2023 #1

好的,我确定了真正的问题并找到了解决方案。

如可重现示例所示,我尝试将类继承到并隐藏基成员。当然,这是行不通的,因为这些成员不是来自 .ItemTestICode

我这边的错误是认为这是 .NET 7 的错误,只是因为调试器在将鼠标悬停在 .由于尝试显示值时出现此异常,我无法从上面检测到错误。T.InterfaceCode

我能够通过继承 的 每个子类来解决它。 (ICodeItemclass Test : Item, ICode {...})

无论如何,感谢您的帮助!