C# 初始化变量时,使用新内存位置的标准是什么?
我在编写新的单元测试时遇到了一些问题。我在代码示例中的注释解释了我的具体问题:C# 初始化变量时,使用新内存位置的标准是什么?,c#,variables,reference,equality,C#,Variables,Reference,Equality,我在编写新的单元测试时遇到了一些问题。我在代码示例中的注释解释了我的具体问题: KeyboardLayout layout = Engine.ParseLayout(Dimensions.Create(300, 300), "FooBar", provider); var dweeb = layout.Layout.SelectMany(t => t); //Parsed layout is not a mutant Assert.IsTrue(!layout.IsMutant)
KeyboardLayout layout
= Engine.ParseLayout(Dimensions.Create(300, 300), "FooBar", provider);
var dweeb = layout.Layout.SelectMany(t => t);
//Parsed layout is not a mutant
Assert.IsTrue(!layout.IsMutant);
KeyboardLayout newLayout = StandardKeyboardMutations.MutateKeyboard(layout);
var newb = newLayout.Layout.SelectMany(t => t);
//I don't understand why this test fails. They should be stored in seperate memeory locations and therefore not equal by reference comparison.
//Unless of course saying var x = foo doesn't always provide a fresh memory location for the value of foo.
Assert.AreNotEqual(layout, newLayout);
这一行Assert.AreNotEqual(布局,新布局)代码>总是失败
我不知道为什么到目前为止我一直在做这样的假设(在注释中陈述):声明变量总是执行一个存储过程到一个新的内存位置。(当前正在运行的程序未使用的程序)
明确地说,问题是,在c#中,doesvar x=foo代码>是否始终使用新的存储单元?如果没有,使用标准是什么?或者它总是将值的地址存储在x中?或者我错过了什么,我问了一个错误的问题,完全是为了找出这里的错误
这是我的第一次“正式”单元测试体验,提前感谢。您正在寻找而不是
Assert.AreName()
断言检查参数是否引用相同的对象(您提到的“相同内存位置”),而Assert.AreEqual()
(分别是AreNotEqual()
),断言检查底层对象的相等性,即检查a.Equals(b)
,即使a
和b
引用了不同的对象,这也可以成立。您正在查找而不是
Assert.AreName()
断言检查参数是否引用相同的对象(您提到的“相同内存位置”),而Assert.AreEqual()
(分别是AreNotEqual()
),断言检查底层对象的相等性,即检查a.Equals(b)
,即使a
和b
引用了不同的对象,它也可以成立
是否var x=foo
;总是使用新的存储单元吗
是的,x
永远是记忆的新和平。然而,它并不一定意味着你认为它意味着什么。
或者它总是在x
中存储值的地址
是,如果值类型是引用类型。e、 g
var x = new MyClass();
var y = x;
x
和y
都包含对相同内存和平的引用(您可以将其视为一个地址),其中实际存储了MyClass()
实例
对于值类型,这是完全不同的:
var x = new MyStruct();
var y = x;
当指定给y
时,将复制整个对象。没有引用,对象本身存储在y
中
是否var x=foo
;总是使用新的存储单元吗
是的,x
永远是记忆的新和平。然而,它并不一定意味着你认为它意味着什么。
或者它总是在x
中存储值的地址
是,如果值类型是引用类型。e、 g
var x = new MyClass();
var y = x;
x
和y
都包含对相同内存和平的引用(您可以将其视为一个地址),其中实际存储了MyClass()
实例
对于值类型,这是完全不同的:
var x = new MyStruct();
var y = x;
当指定给y
时,将复制整个对象。没有引用,对象本身存储在y
中,我找不到任何有关标准键盘突变的文档。你有参考资料吗?自定义类。如果你想了解它的实现,我必须给出一个不同的例子。答案可能在于它的实现。除非您覆盖了KeyboardLayout.Equals
否则您将获得ReferenceEquals
实现。这意味着标准键盘突变。MutateKeyboard
正在返回与布局
相同对象的引用-可能不是您想要的。我找不到任何关于标准键盘突变
的文档。你有参考资料吗?自定义类。如果你想了解它的实现,我必须给出一个不同的例子。答案可能在于它的实现。除非您覆盖了KeyboardLayout.Equals
否则您将获得ReferenceEquals
实现。这意味着某种程度上标准键盘突变。MutateKeyboard
返回与布局
相同对象的引用-可能不是您想要的。我怀疑OP实际上还需要其他东西。但是好的开始:)如果两个变量共享内存位置,那么优化和各种别名呢。。。简单的Eric Lipperts博客链接就足够了……那么在我的示例代码中,如果dweeb和newb在初始化的右侧都有引用类型,你会说它们可以引用相同的东西吗?我不这么认为,它们引用的是LINQ内存查询定义。你之所以能得到相等的结果,是因为你使用了错误的Assert
方法(如其他答案所述)。我怀疑OP实际上还需要其他东西。但是好的开始:)如果两个变量共享内存位置,那么优化和各种别名呢。。。简单的Eric Lipperts博客链接就足够了……那么在我的示例代码中,如果dweeb和newb在初始化的右侧都有引用类型,你会说它们可以引用相同的东西吗?我不这么认为,它们引用的是LINQ内存查询定义。你之所以得到相等的结果,是因为你使用了错误的Assert
方法(如其他答案所述)。这是一个很好的信息。但是,我使用了Assert.AreNotSame();方法和断言仍然失败。即使我的示例代码让我相信不是这样,它们也必须引用相同的对象。如果它们仍然相同,则标准键盘突变
有可能利用来共享它传递的突变。如果你能扩大规模,那就最好了