【问题标题】:Using code contracts to make a generic to be of type enum使用代码契约将泛型设为枚举类型
【发布时间】:2012-01-03 18:16:55
【问题描述】:

几天前我问了一个题为How to constraint a generic to be of type enum?的问题。总结问题是以下代码:

class MyClass<T> where T : enum // Not possible in C#
{
}

我被介绍了代码契约,并且我可以针对该问题生成一个编译时警告,这就是我想要的(在编译时被告知 T 应该是 enum)。我尝试了以下代码 (Full source)。

class MyClass<T>
{
  public MyClass()
  {
    Contract.Requires(typeof(System.Enum).IsAssignableFrom(typeof(T)));
  }
}

它只会产生一个无用的运行时错误。我应该能够产生编译时警告,但我无法让它工作。谁能告诉我我做错了什么?

这是项目代码合同设置的图片:

【问题讨论】:

  • 您是否使用了该问题已接受答案中建议的库?
  • @Oded,我试过了,但是没有示例代码,所以我什至不知道从哪里开始。虽然这是另一个问题,但我发现这是一种更好的方法,因为它已经是 .NET 框架的一部分。
  • @AtoMerZ:Unconstrained Melody 旨在用作库,但您可以对自己的代码使用相同的 IL 重写。看看代码 - 非常简单。
  • 您是否在相关项目中启用了“执行静态检查”?
  • @JonSkeet,我得到了 NuGet,在我的项目中添加了不受约束的旋律,之后我不知道我应该做什么。编写类MyClass&lt;T&gt; where T:enum 时仍然出现错误。你能提供一个如何使用它的示例吗?

标签: c# inheritance enums constraints code-contracts


【解决方案1】:

所以,我在一个文件中写了以下代码:

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>();

    }
}

从那里,我进入项目选项的代码合同部分并选中“静态检查”下的所有复选框。然后我将警告级别设置为“高”。当我重建解决方案时,我收到一个警告:“代码合同:不变量需要未经证实:typeof(...)”,对应于类不变量。

从那里,我将警告级别设置回低,并看到没有警告,你报告的内容。所以,我认为将警告级别设置为高是您所需要的。

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

编辑:我在发布后看到了您的屏幕截图,因此我将对此进行修改以建议使用我的“如果这不起作用”建议与类级别不变量而不是来自 xtor 的 requires 调用。

【讨论】:

  • 谢谢。它适用于两种方式(前提条件和不变量)。我不确定错误是什么,但我注意到编译后警告需要几秒钟才会出现,所以我认为我只是不耐烦。
  • 默认是在后台运行静态检查,所以编译完成后它会继续运行。当项目变得更大时,这变得很重要,因为没有它,静态分析将需要很长时间。如果需要,您可以通过取消选中“签入后台”来绕过这个,对于较小的项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多