如何将引用作为参数传递给Windows Store App中的Async方法? 我在寻找这样的东西:
var a = DoThis(ref obj.value);
public async Task DoThis(ref int value)
{
value = 10;
}
但是错误:
异步方法不能有ref或out参数
还有别的办法吗?
注意: 我需要准确传递obj.value。此方法将由不同类型的对象,相同类型的对象,一个对象使用,但我将传递obj.val_1,obj.val_2或obj.val_10。所有值都是相同的类型(对于ex string)
如果你不关心对象的一点开销和可能延长的生命周期,你可以通过将setter和getter方法传递给函数来模拟ref行为,如下所示:
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);
您可以直接传递对象本身并在方法内设置相应属性的值:
var a = DoThis(obj);
public async Task DoThis(SomeObject o)
{
o.value = 10;
}
如果你没有这样的对象,只需编写一个并使用async方法将该对象作为参数:
public class SomeObject
{
public int Value { get; set; }
}
您始终可以使用Task<>
类并返回所需的值。然后你的代码看起来像:
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;
}
编辑
好吧,我能想到的另一种方法是将给定对象成员的更新封装在一个方法中,然后将调用此方法的操作作为任务的参数传递,如下所示:
var a = DoThis(() => ChangeValue(ref obj.value));
public void ChangeValue(ref int val)
{
val = 10;
}
public async Task DoThis(Action act)
{
var t = new Task(act);
t.Start();
await t;
}
就我测试它而言,更改是在子线程中进行的,但它的效果在父线程中仍然可见。希望这有助于你。
你不能这样做(如你所知)。所以,一些解决方法:
您可以通过传递初始对象来完成此操作,因为它将是一个引用类型
var a = DoThis(obj);
public async Task DoThis(object obj) //replace the object with the actual object type
{
obj.value = 10;
}
编辑
根据您的评论,创建一个界面并让您的类实现它(假设它总是与您想要传递的类型相同)。然后你可以传递共享的界面(可能过度杀戮,取决于你的需要,甚至是不切实际的工作量)。
或者,提供属性的基类! (我不喜欢这个建议,但既然你要求的东西不能做,它可能就足够了,虽然我不推荐它)。
这里是一个接口的例子(不使用你拥有的,但使用Colsone应用程序足够接近)
using System;
namespace InterfacesReferenceTypes
{
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
DoThis(mc);
Console.WriteLine(mc.Number);
Console.ReadKey();
}
static void DoThis(IDemo id)
{
id.Number = 10;
}
}
class MyClass : IDemo
{
//other props and methods etc
public int Number { get; set; }
}
interface IDemo
{
int Number { get; set; }
}
}
Aaditi
在下一个注释之后,您仍然必须使用接口,但之后重新分配值。我确信有更好的方法可以做到这一点,但这有效:
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; }
}
}