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

Edi*_*din 5 c# code-contracts

我定义了一个具有一个通用方法DoSomething的以下示例类:

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

我有以下枚举:

public enum MyEnum { A, B }
Run Code Online (Sandbox Code Playgroud)

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

class Program
{
    static void Main(string[] args)
    {
        MyClass.DoSomething(MyEnum.A);
    }
}
Run Code Online (Sandbox Code Playgroud)

在代码协定中启用静态检查后,在我调用方法的行显示以下警告:

CodeContracts:需要未经证实:typeof(T).IsEnum

如果在编译时知道该值,为什么它未经证实?

编辑

因为这显然不起作用,可能是因为Code Contracts不理解语义IsEnumval is Enum(Jon也指出).我感兴趣,如果有任何已知的方法在代码合同中进行这种检查?

dbc*_*dbc 0

如果您试图解决 c# 中缺少“枚举”约束的问题,这里已经给出了一个奇怪但完全可行的解决方案:C# 中的枚举类型约束

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>
{ 
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以在一个小型子项目中在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));
    }
};
Run Code Online (Sandbox Code Playgroud)