我有一个非常简单的层次结构:1个接口由几个类继承,看起来与此相似但缺少一些属性:
public interface Test
{
List<double> Numbers { get; set; }
double Result { get; set; }
}
public class A : Test
{
public List<double> Numbers { get; set; } = new List<double>();
public double Result { get; set; }
}
public class B : Test
{
public List<double> Numbers { get; set; } = new List<double>();
public double Result { get; set; }
}
以下是我想要实现的示例代码:
A a = new A();
B b = new B();
a.Numbers.Add(b.Result);
Console.WriteLine(a.Numbers.Last());
b.Result = 50;
Console.WriteLine(a.Numbers.Last());
输出
0
0
问题在于,在第5行,我正在更改b.Result
的值,但我想在a.Numbers
列表中反映此更改,其中包含先前的b.Result
状态,如何我可以这样做吗?
答案 0 :(得分:3)
double
是value type
,无论何时传递它,都会创建它的副本。它不是通过引用传递的,因此当您说a.Numbers.Add(b.Result);
时,您实际上正在创建b.Result
的副本并传递给Add
方法。
您可以阅读此Article以通过示例了解此概念。
来自C#规范:
⦁类型和变量
C#中有两种类型:值类型 和参考类型。值类型的变量直接包含它们的变量 数据,而引用类型的变量存储对它们的引用 数据,后者被称为对象。对于引用类型,它是 可能两个变量引用同一个对象,从而 可以对一个变量进行操作以影响对象 由另一个变量引用。使用值类型,每个变量 拥有自己的数据副本,并且不可能进行操作 在一个上影响另一个(除了ref和out之外) 参数变量)。
以下是解决方法,不建议使用
public interface Test
{
List<DoubleByRef> Numbers { get; set; }
DoubleByRef Result { get; set; }
}
public class A : Test
{
public List<DoubleByRef> Numbers { get; set; } = new List<DoubleByRef>();
public DoubleByRef Result { get; set; } = new DoubleByRef(0);
}
public class B : Test
{
public List<DoubleByRef> Numbers { get; set; } = new List<DoubleByRef>();
public DoubleByRef Result { get; set; } = new DoubleByRef(0);
}
public class DoubleByRef
{
public double Value { set; get; }
public DoubleByRef(double d)
{
Value = d;
}
public override string ToString()
{
return Value.ToString();
}
}
用法:
A a = new A();
B b = new B();
a.Numbers.Add(b.Result);
Console.WriteLine(a.Numbers.Last());
b.Result.Value = 50;
Console.WriteLine(a.Numbers.Last());
打印:
0
50