c# - 如何为 IDisposable 类型使用自定义生成器?

标签 c# fscheck

请注意:这是一个关于 fscheck 的问题,而不是关于 C# 中 IDisposable 的一般用法

假设我有以下类(class)(为了说明目的而夸大):

public class MyDataTypeWrapper : IDisposable
{
    private MyDataType fMyDataType; // MyDataType implements IDisposable

    public MyDataTypeWrapper(int[] randomData)
    {
         // some conversion routine (not shown)
         var inputToMyDataType = ConvertRandomDataToMyDataInputs(randomData);

         // this could all be done in one method but breaking out into two to illustrate.
         fMyDataType = new MyDataType(inputToMyDataType);
    }

    public void Dispose()
    {
         fMyDataType.Dispose();
    }
}

MyDataType 消耗一些非托管资源,因此它实现了 IDisposableMyDataType 类实际上没有采用 int[] 的构造函数,因此使用了包装类。

为此创建一个生成器相对简单,但我看不出有什么办法让这样的生成器在每次测试迭代后也负责处理创建的对象,这意味着我的测试代码经常充斥着显式调用处置。请参阅下面的大纲示例。

var generator = from randomData in Arb.Generate<int[]>()
                select new MyDataTypeWrapper(randomData);

// use the generator as input to some fscheck property based tests
Prop.ForAll(generator.ToArbitrary(), (MyDataTypeWrapper randomClassUnderTest) =>
{
    // want to avoid this
    using(randomClassUnderTest)
    {
        // assert some properties
        ...
    }
}).QuickCheckThrowOnFailure();

Prop.ForAll(generator.ToArbitrary(), (MyDataTypeWrapper randomClassUnderTest) =>
{
    // assert some properties
    ...

    // also want to avoid this (equivilant to use of using in example above)
    randomClassUnderTest.Dispose();
}).QuickCheckThrowOnFailure();

任何关于如何避免这种情况的想法\建议都将不胜感激。

最佳答案

第一个解决方案相当明显,但我还是要说明它,因为它实际上回答了问题:

var generator = from randomData in Arb.Generate<int[]>()
                select new MyDataTypeWrapper(randomData);

Prop.ForAll(generator.ToArbitrary(), (MyDataTypeWrapper randomClassUnderTest) =>
{

   using(randomClassUnderTest)
   {

   }

}).QuickCheckThrowOnFailure();

如果你不想对每个元素都这样做,你需要创建一些辅助方法来为你做这件事,例如:

  public static WhateverItReturns DisposablePropAll<TDisposable>(this IEnumerable<TDisposable> elements, Action<TDisposable> action) where TDisposable : IDisposable
        {
            return Prop.ForAll(elements, (TDisposable randomClassUnderTest) =>
            {
                using (randomClassUnderTest)
                {
                    action(randomClassUnderTest);
                }
            });
        }

关于c# - 如何为 IDisposable 类型使用自定义生成器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49113698/

相关文章:

c# - 欢迎消息在网络聊天中不可见,但在模拟器中有效

functional-programming - FsCheck 生成器能否创建不断增加的序列

c# - 不同网络平台/网络产品之间常见的同音异义词和同义词有哪些?

C# Razor : Why does this null check fail

c# - 如何为 FsCheck 测试生成空字符串

f# - 为任意长度相同的整数列表制定一个任意

asynchronous - 如何在 FsCheck 中运行异步测试?

f# - 如何组合 2 个任意实例以匹配测试方法签名

c# - 在我的事件处理程序范围内遇到问题(ASPX .NET 3.5)

c# - 如何测试 Linq-To-SQL ConnectionString 以确保其有效