C# 异步任务中的Ref

C# 异步任务中的Ref,c#,asynchronous,async-await,windows-store-apps,C#,Asynchronous,Async Await,Windows Store Apps,如何将引用作为参数传递给Windows应用商店应用程序中的异步方法我在找这样的东西: var a = DoThis(ref obj.value); public async Task DoThis(ref int value) { value = 10; } public async Task DoStuff(Func<int> getter, Action<int> setter) { var value1 = getter(); await

如何将引用作为参数传递给Windows应用商店应用程序中的异步方法
我在找这样的东西:

var a = DoThis(ref obj.value);

public async Task DoThis(ref int value)
{
    value = 10;
}
public async Task DoStuff(Func<int> getter, Action<int> setter)
{
    var value1 = getter();
    await DoSomeOtherAsyncStuff();
    setter(value1 * value1);
}
await DoStuff(() => obj.Value, x => obj.Value = x);
但错误是:

异步方法不能有ref或out参数

还有别的办法吗


注意:
我需要准确传递obj.value。此方法将由不同类型的对象、相同类型的对象、一个对象使用,但我将传递obj.val_1、obj.val_2或obj.val_10。所有值都将是相同的类型(对于ex string)

您可以直接传递对象本身,并在方法内设置相应属性的值:

var a = DoThis(obj);

public async Task DoThis(SomeObject o)
{
    o.value = 10;
}
如果没有这样的对象,只需编写一个,并让异步方法将该对象作为参数:

public class SomeObject
{
    public int Value { get; set; }
}

你不能这样做,因为你有它(如你所知)。因此,有一些解决办法:

您可以通过传递初始对象来实现这一点,因为它将是引用类型

var a = DoThis(obj);  

public async Task DoThis(object obj) //replace the object with the actual object type
{
    obj.value = 10;
}
编辑

根据您的注释,创建一个接口并让您的类实现它(前提是它始终是您想要传递的相同类型)。然后,您可以传递共享的接口(可能是过度杀戮,取决于您的需要,甚至是不切实际的工作量)

或者,提供一个带有属性的基类!(我不喜欢这个建议,但既然你要求的是一些做不到的事情,也许就足够了,尽管我不推荐)

这里有一个界面示例(不使用您现有的,但使用Colsone应用程序就足够接近了)

EDIT2

在下一个注释之后,您将不得不继续使用接口,但随后重新分配值。我相信有更好的方法可以做到这一点,但这是可行的:

using System.Text;

namespace InterfacesRerefenceTypes
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            Console.WriteLine(mc.Number);
            mc.val1 = 3;
            mc.val2 = 5;
            mc.Number = mc.val2;
            DoThis(mc);
            mc.val2 = mc.Number;

            Console.WriteLine(mc.val2);
            Console.ReadKey();
        }

        static void DoThis(IDemo id)
        {
            id.Number = 15;
        }
    }

    class MyClass : IDemo
    {
        public int val1 { get; set; }
        public int val2 { get; set; }
        public int Number { get; set; }
    }

    interface IDemo
    {
        int Number { get; set; }
    }
}

您可以始终使用
任务
类并返回所需的值。然后,您的代码将类似于:

var a = DoThis(obj.value);
obj.value = a.Result;

public async Task<int> DoThis(int value)
{
    int result = value + 10; //compute the resulting value
    return result;
}

就我测试而言,更改是在子线程中进行的,但其效果在父线程中仍然可见。希望这对您有所帮助。

如果您不关心对象的一点开销和可能延长的生命周期,您可以通过向函数传递setter和getter方法来模拟ref行为,如下所示:

var a = DoThis(ref obj.value);

public async Task DoThis(ref int value)
{
    value = 10;
}
public async Task DoStuff(Func<int> getter, Action<int> setter)
{
    var value1 = getter();
    await DoSomeOtherAsyncStuff();
    setter(value1 * value1);
}
await DoStuff(() => obj.Value, x => obj.Value = x);

请阅读问题:我需要准确传递obj.value。此方法将由不同类型的对象、相同类型的对象、一个对象使用,但我将传递obj.val_1、obj.val_2或obj.val_10@jimpanzer,我做到了-你的帖子从来没有提到它将被不同类型的对象使用!我可以假设val_1、val_2等都是相同的类型吗?val_1、val_2、val_10-都是相同的类型(字符串或int或其他,但相同)。我只需要传递一个值,因为我从不同的地方得到这个值。@jimpanzer,Updated-你可以使用一个接口来实现这个我理解你的想法,但是在我的类中可以是Number,Number1,number2。。。还有许多其他数字。我只想要传递值。但是谢谢,你花了你的时间。请阅读这个问题:我需要准确地传递obj.value。此方法将由不同类型的对象使用,由相同类型的对象使用,由一个对象使用,但我将传递obj.val_1,obj.val_2或obj.val_10请阅读您收到的错误消息:这在C#中不受支持,除非您自己编写一个支持将ref/out变量传递给
async
方法的编译器,否则我看不出如何解决您的问题。你还指望我告诉你什么?向您展示一个如何做不受支持的事情的工作示例?我的问题是:“有其他方法吗?”答案必须简短:“没有,因为…”或“是的,您需要做…”以及您已经提供的没有帮助的答案。我知道这种方法,但我正在寻找一种方法,可以在异步任务中更改值。但是+1对你来说。关于你的编辑:你不允许在lambda表达式中使用ref参数。我相信这是一个很好的答案,因为有很多原因,他可以通过使其通用化来扩展许多不同类型对象的可重用性:
DoStuff(Func getter,Action setter)
.Nate Diamond我认为Func和Action已经是泛型类型的委托了