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

时间:2014-05-22 11:31:33

标签: c# code-contracts

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

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

我有以下枚举:

public enum MyEnum { A, B }

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

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

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

  

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

为什么在编译时知道值是否未经证实?

修改

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

1 个答案:

答案 0 :(得分:0)

如果您正在尝试解决c#中缺少“枚举”约束的问题,那么这里已经提出了一个奇怪但完全可行的解决方案:Enum type constraints in 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>
{ 
}

或者,你可以do it in 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));
    }
};