我有两个具有引用类型变量的结构实例。我想交换这两个变量,但是关于如何执行此操作的第一个猜测似乎不起作用。我的代码如下所示:
struct Foo
{
Bar m_bar;
}
void Main()
{
Foo a = new Foo();
Foo b = new Foo();
//swapping the values of m_bar of a and b
Bar temp = a.m_bar;
a.m_bar = b.m_bar;
b.m_bar = temp;
}
据我所知,由于变量是引用类型,因此分配b.m_bar
给的a.m_bar
同时也会将其分配给temp
,使交换变得混乱。
那我的代码错了吗?如果是,交换两个引用类型变量的正确方法是什么?如果没有,我想我的代码会搞乱其他地方。
谢谢!
问题中的代码可以正常工作,如下面的最小再现所示。这里的混乱几乎肯定与可变的值类型有关。具有可变字段的结构因混乱而臭名昭著。我强烈建议您将其Foo
视为不可变的,readonly struct
如果您的编译器支持,则明确将其设置为-类似于:
readonly struct Foo
{
public Bar Bar { get; }
public Foo(Bar bar) => Bar = bar;
// not shown: override ToString, GetHashCode and Equals
}
但是:与原始代码类似:
static class P
{
static void Main()
{
Foo a = new Foo { m_bar = new Bar("abc") };
Foo b = new Foo { m_bar = new Bar("def") };
System.Console.WriteLine("Before");
System.Console.WriteLine($"a.m_bar: {a.m_bar}"); // abc
System.Console.WriteLine($"b.m_bar: {b.m_bar}"); // def
//swapping the values of m_bar of a and b
Bar temp = a.m_bar;
a.m_bar = b.m_bar;
b.m_bar = temp;
System.Console.WriteLine("After");
System.Console.WriteLine($"a.m_bar: {a.m_bar}"); // def
System.Console.WriteLine($"b.m_bar: {b.m_bar}"); // abc
}
struct Foo
{ // note: public fields are usually a bad idea in any type
// note: mutable fields on value-types are usually a bad idea
public Bar m_bar;
}
class Bar
{
public string Name { get; }
public override string ToString() => Name;
public Bar(string name) => Name = name;
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句