C# 使用代码约定将泛型设置为enum类型

C# 使用代码约定将泛型设置为enum类型,c#,inheritance,enums,constraints,code-contracts,C#,Inheritance,Enums,Constraints,Code Contracts,几天前我问了一个问题,题目是。总结问题的代码如下: class MyClass<T> where T : enum // Not possible in C# { } 它只会产生一个无用的运行时错误。我应该能够生成编译时警告,但我无法让它工作。谁能告诉我我做错了什么 以下是项目代码合同设置的图片: 因此,我在一个文件中编写了以下代码: public class SomeClass<T> { [ContractInvariantMethod] privat

几天前我问了一个问题,题目是。总结问题的代码如下:

class MyClass<T> where T : enum // Not possible in C#
{
}
它只会产生一个无用的运行时错误。我应该能够生成编译时警告,但我无法让它工作。谁能告诉我我做错了什么

以下是项目代码合同设置的图片:
因此,我在一个文件中编写了以下代码:

public class SomeClass<T>
{
    [ContractInvariantMethod]
    private void Invariants()
    {
        Contract.Invariant(typeof(System.Enum).IsAssignableFrom(typeof(T)));
    }

    /// <summary>Initializes a new instance of the SomeClass class.</summary>
    /// <param name="dependency"></param>
    public SomeClass()
    {

    }
}

public class SomeOtherClass
{
    public SomeOtherClass()
    {
        var myClass = new SomeClass<int>();

    }
}
公共类SomeClass
{
[收缩变量法]
私有void不变量()
{
Contract.Invariant(typeof(System.Enum).IsAssignableFrom(typeof(T));
}
///初始化SomeClass类的新实例。
/// 
公共类()
{
}
}
公共类其他类
{
公共SomeOtherClass()
{
var myClass=new SomeClass();
}
}
从那里,我进入了项目选项的代码合同部分,并选中了“静态检查”下的所有复选框。然后我将警告级别调到“高”。当我重新构建解决方案时,收到了一条警告:“代码契约:invariant需要未经验证的:typeof(…)”,该警告对应于类invariant

从那里,我将警告级别设置为低,并看到没有警告,正如您所报告的。因此,我认为将警告级别设置为高是您需要的

如果这不起作用,您可以尝试遵循我所做的,并将契约定义为类不变量(学究般地说,我建议您无论如何都这样做,因为从概念上讲,这更像是类级不变量,而不是构造函数执行的结果)


编辑:我在发布后看到了你的屏幕截图,因此我建议将我的“if that not work”建议与类级不变量一起使用,而不是从xtor中调用requires。

你是否使用了该问题公认答案中建议的库?@Oded,我尝试过,但是没有示例代码,所以我甚至不知道从哪里开始。虽然这是另一个问题,但我发现这是一种更好的方法,因为它已经是.NET framework的一部分。@AtoMerZ:UnconstratedMelody被设计为用作库,但您可以对自己的代码使用相同的IL重写。只需看一下代码——非常简单。您在所讨论的项目中启用了“执行静态检查”吗?@JonSkeet,我得到了NuGet,为我的项目添加了无约束的旋律,之后我不知道该怎么做。当我编写class
MyClass,其中T:enum
时,仍然会出错。你能提供一个如何使用它的样品吗?谢谢。它以两种方式工作(先决条件和不变)。我不确定错误是什么,但我注意到编译后需要几秒钟才会出现警告,所以我认为我只是不耐烦。默认情况是在后台运行静态检查,所以编译完成后它会继续运行。当项目变得更大时,这一点就变得非常重要,因为如果没有它,静态分析将花费很长很长的时间。对于较小的项目,如果需要,可以通过取消选中“CheckinBackground”来绕过此选项。
public class SomeClass<T>
{
    [ContractInvariantMethod]
    private void Invariants()
    {
        Contract.Invariant(typeof(System.Enum).IsAssignableFrom(typeof(T)));
    }

    /// <summary>Initializes a new instance of the SomeClass class.</summary>
    /// <param name="dependency"></param>
    public SomeClass()
    {

    }
}

public class SomeOtherClass
{
    public SomeOtherClass()
    {
        var myClass = new SomeClass<int>();

    }
}