为什么代码契约将泛型类型参数的检查标记为未经验证

本文关键字:记为 验证 检查 代码 契约 泛型类型参数 为什么 | 更新日期: 2023-09-27 18:04:32

我定义了一个具有一个泛型方法DoSomething的示例类:

public static class MyClass
{
    public static void DoSomething<T>(T val)
    {
        System.Diagnostics.Contracts.Contract.Requires(typeof(T).IsEnum);
    }
}

我有以下enum:

public enum MyEnum { A, B }

现在用枚举的实例调用该方法,如下所示:

class Program
{
    static void Main(string[] args)
    {
        MyClass.DoSomething(MyEnum.A);
    }
}

如果在代码契约中启用了静态检查,那么在调用该方法的那一行将显示以下警告:

CodeContracts:需要未经证明的:typeof(T)。IsEnum

如果该值在编译时已知,为什么它未被证明?

编辑

因为这显然不起作用,可能是因为代码契约不理解IsEnumval is Enum的语义(Jon也指出了这一点)。我很感兴趣,如果有任何已知的方法来做这种检查在代码合同?

为什么代码契约将泛型类型参数的检查标记为未经验证

如果你正在尝试解决c#中缺乏"enum"约束的问题,这里有一个奇怪但完全可行的解决方案:c#中的enum类型约束

public abstract class Enums<Temp> where Temp : class {
    public TEnum DoSomething<TEnum>(string name) where TEnum : struct, Temp
    {
        // Your code
    }
}
public abstract class Enums : Enums<Enum>
{ 
}

或者,您可以在c++/CLI的一个小子项目中完成它,因为约束似乎在那里工作(示例是类型安全的"enum.parse"):

using namespace System;
public ref class EnumHelper 
{
public:
    generic <typename T> where T : Enum
    static T Parse(String^ value)
    {
        return Parse<T>(value,
                        false);
    }
    generic <typename T> where T : Enum
    static T Parse(String^ value,
                   bool ignoreCase)
    {
        return safe_cast<T>(Enum::Parse(T::typeid,
                                        value,
                                        ignoreCase));
    }
};