4

据我了解,属性不能返回引用,并且由于结构是值类型,因此无法通过属性返回对结构的引用,这将启用:

public struct SomeStruct
{
   public int SomeMember { get; set; }
}
class foo
{
   private SomeStruct bar; 
   public SomeStruct Bar{ get { return bar; } set { bar = value; } }
}

//Somewhere else
foo f = new foo();
f.Bar.SomeMember = 42; //Error, this doesn't work

我必须求助于 setMemberOfSomeStruct() 还是有其他方法?

编辑:具体来说,我想避免一直为这样的结构调用 new 。我知道使用构造函数 SomeStruct(int),这会起作用:

f.Bar = new SomeStruct(42); //ugh
4

2 回答 2

2

使您的struct实现不可变并执行以下操作:

var newSomeStruct = new SomeStruct(42 /* Feeds SomeMember */);
var myFoo = new Foo();
myFoo.Bar = newSomeStruct;

public struct SomeStruct
{
    private int _someMember;

    public int SomeMember { get { return _someMember; } }

    public SomeStruct(int someMember)
    {
        _someMember = someMember;
    }
}

不可变结构有助于保留预期的值类型语义。

如果你不让它不可变,那么上面的代码仍然是让它工作的唯一方法。

或者,但不是更好看,在类上公开一个方法来设置类的副本SomeStruct

public void SetSomeMember(int val)
{
    _bar.SomeMember = val; // Note _bar in this example is a field, not a property.
}

我只是为了完整性而提供这个,我仍然会走不变的路线,因为关于“可变结构是邪恶的”已经达成共识。属性 getter 是一个问题,就像转换为接口一样 - 不可变结构解决了这些问题。

还有另一个有趣的观点 - 不要假设在性能问题实际存在之前就存在性能问题。定义可能与您从中获得的使用风格class一样快。struct剖析是这里的王道。

于 2012-04-13T14:05:22.480 回答
0

看起来你有一个可变结构,不推荐

但是要直接回答您的问题:创建一个副本,对其进行变异,然后使用变异的结构设置属性。

var barCopy = f.Bar;
barCopy.SomeMember = 42;
f.Bar = barCopy;

顺便一提:

据我了解,属性不能返回引用。

Of course they can - properties of reference types return references from the getter.

Since structs are value types, there's no way to return a reference to a struct via properties.

Sure there is, you can return a reference to a boxed struct. Example:

 public IComparable Property { get { return 42; } }
于 2012-04-13T14:06:57.207 回答