C# 异步任务中的Ref
如何将引用作为参数传递给Windows应用商店应用程序中的异步方法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
我在找这样的东西:
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已经是泛型类型的委托了