这是我正在尝试做的简化版本
static void Main(string[] args)
{
int test = 0;
int test2 = 0;
Test A = new Test(ref test);
Test B = new Test(ref test);
Test C = new Test(ref test2);
A.write(); //Writes 1 should write 1
B.write(); //Writes 1 should write 2
C.write(); //Writes 1 should write 1
Console.ReadLine();
}
class Test
{
int _a;
public Test(ref int a)
{
_a = a; //I loose the reference here
}
public void write()
{
var b = System.Threading.Interlocked.Increment(ref _a);
Console.WriteLine(b);
}
}
在我的真实代码中,我有一个int会被许多线程递增,但是调用它的线程将不容易传递给它指向int的参数(在实际代码中这发生在一个IEnumerator
)。所以要求是必须在构造函数中进行引用。同样不是所有线程都指向同一个单一的int,所以我也不能使用全局静态int。我知道我可以在类中包装int并传递类,但我想知道这是否是正确的做这样的事情的方式?
我认为可能是正确的方法:
static void Main(string[] args)
{
Holder holder = new Holder(0);
Holder holder2 = new Holder(0);
Test A = new Test(holder);
Test B = new Test(holder);
Test C = new Test(holder2);
A.write(); //Writes 1 should write 1
B.write(); //Writes 2 should write 2
C.write(); //Writes 1 should write 1
Console.ReadLine();
}
class Holder
{
public Holder(int i)
{
num = i;
}
public int num;
}
class Test
{
Holder _holder;
public Test(Holder holder)
{
_holder = holder;
}
public void write()
{
var b = System.Threading.Interlocked.Increment(ref _holder.num);
Console.WriteLine(b);
}
}
有没有比这更好的方法?
答案 0 :(得分:5)
基本上,答案是肯定的,你需要一个班级。
没有“引用到int”的概念,您可以将其存储为字段。在C#中,它仅限于参数。
虽然存在unsafe
方式(指向int,int*
的方式),但在该方案中处理GC的复杂性使其变得不切实际且效率低下。
所以你的第二个例子看起来还不错。
答案 1 :(得分:3)
您无法存储对变量的引用,这正是某人可以执行您正在执行的操作的原因:引用局部变量,然后在回收本地变量的存储后使用该引用。
将变量放入类的字段的方法很好。执行相同操作的另一种方法是将getter和setter委托给变量。如果代理人在外部局部变量上被关闭,则该外部本地将被提升到一个字段,以使其生命周期长于代表的生命周期。
答案 2 :(得分:1)
无法将引用存储为字段。
你需要在一个类中保存int。