C#。引用扩展方法的引用返回委托

时间:2019-08-16 17:11:51

标签: c# extension-methods ref c#-7.2

我具有以下扩展方法,用于监视变量并等待其具有给定的期望值:

        public static async Task AwaitForValue<T>(this Func<T> valueGetter, T expectedValue, int? millisecondsToAwaitBetweenChecks = null, int? maxMillisecondsToAwait = null) 
            where T : struct
        {
            var timeToAwait = millisecondsToAwaitBetweenChecks ?? 20;
            if (maxMillisecondsToAwait.HasValue)
            {
                var stopWatch = new Stopwatch();
                stopWatch.Start();
                while (!valueGetter().Equals(expectedValue) || stopWatch.ElapsedMilliseconds >= maxMillisecondsToAwait)
                {
                    await Task.Delay(timeToAwait);
                }
            }
            else
            {
                while (!valueGetter().Equals(expectedValue))
                {
                    await Task.Delay(timeToAwait);
                }
            }    
         }

工作正常:

class Foo
        {
            private bool _flag;

            public async void DoWork()
            {
                Task.Run(() =>
                {
                    Thread.Sleep(5000);
                    _flag = true;
                });
                await new Func<bool>(() => _flag).AwaitForValue(true);
                Console.WriteLine(_flag);
            }
         }

我想定义一个ref扩展方法,该方法给我一个委托,该委托向我返回ref变量的当前值,例如:

public delegate ref T RefFunc<T>();

通过这种方式,我以前的扩展方法可以扩展RefFunc<T>而不是Func<T>并被假设使用,如下所示:

_flag.ToRefFunc().AwaitForValue(true);

问题是我找不到正确定义ToRefFunc<T>(this ref T value);的方法,因为在lambda中不允许使用ref。那么,有没有一种方法可以定义以下方法?

public static RefFunc<T> ToRefFunc<T>(this ref T value) where T : struct
{
     //todo some day
}

理想情况下,它看起来像这样:

public static RefFunc<T> ToRefFunc<T>(this ref T value) where T : struct => new RefFunc<T>(() => value);

任何帮助将不胜感激

编辑

问题不在于是否允许引用扩展方法,从“重复”问题中请参见this

编辑2 匿名委托语法也不起作用:

public static RefFunc<T> ToRefFunc<T>(this ref T value) where T: struct
{
    return delegate { return value; }; 
}

在这里我得到:不能在匿名方法,lambda表达式,查询表达式或局部函数内使用ref,out或in参数'value'

1 个答案:

答案 0 :(得分:1)

ref参数只能在函数中使用,而不能“保存以备后用”。这是因为ref参数无法使其参照变量保持活动状态。

考虑使用引用类型(C#说法:class)来保存数据。然后,您可以拥有任意数量的句柄,它们将参与垃圾回收(对象生存期,内存压缩等)。不幸的是,这需要更改该变量的所有用户-您不能在现有对象模型中的数据上进行改造。