在一个文件中我定义了一个公共结构
public struct mystruct
{
public Double struct1;
public Decimal struct2;
}
在另一个我尝试这样做:
class Test
{
mystruct my_va;
public mystruct my_va
{
get { return my_va; }
set { my_va = value; }
}
public Test()
{
my_va.struct1 = 10;
}
}
Intellisense识别My_va.struct1,但编译器说
错误1无法修改返回值 'TEST.mystruct'因为它不是 变量
如何更正语法?
答案 0 :(得分:48)
My_va
时,您正在获取值 - 当前值my_va
的副本。更改该值将没有任何好处,因为您将立即丢弃该副本。编译器阻止你编写代码,而代码看起来不像它那样。
一般来说,避免使用可变结构。他们是邪恶的。在这种情况下,您可以(例如)将mystruct
更改为不可变,但使用如下方法:
public mystruct WithStruct1(double newValue)
{
return new mystruct(newValue, struct2);
}
然后将构造函数代码更改为:
My_va = My_va.WithStruct1(10);
...虽然在这个的情况下,你应该写的更有可能(假设你在构造函数中):
My_va = new mystruct(10, 0);
结构不仅应该是不可变的,它们在大多数代码库中都应该是非常罕见的,IMO。除了Noda Time之外,我几乎没有编写自己的自定义值类型。
最后,请了解.NET naming conventions并尝试关注它们,即使是示例代码:)
答案 1 :(得分:38)
强烈建议避免使用可变结构。他们表现出各种令人惊讶的行为。
解决方案:使您的结构不可变。
public struct MyStruct
{
public readonly double Value1;
public readonly decimal Value2;
public MyStruct(double value1, decimal value2)
{
this.Value1 = value1;
this.Value2 = value2;
}
}
用法:
class Test
{
private MyStruct myStruct;
public Test()
{
myStruct = new MyStruct(10, 42);
}
public MyStruct MyStruct
{
get { return myStruct; }
set { myStruct = value; }
}
}
答案 2 :(得分:2)
最简单的修复:将结构更改为类。
答案 3 :(得分:2)
我使用结构列表,并以不同的方式解决了这个问题。
struct Pixel
{ Public int X;
Public int C;
}
List<Pixel> PixelList = new List<Pixel>
TempPixel = new Pixel();
现在,当我想设置一个像我这样的代码值时:
TempPixel = PixelList[i];
TempPixel.X= 23; // set some value
PixelList[i] = TempPixel
代码看起来有点奇怪,但它解决了这个问题。 它解决了结构不能直接分配单个值的问题,但可以是类似类型的副本。 解决错误CS1612:
答案 4 :(得分:1)
不幸的是,在分配属性(即调用属性设置器)时可能会错误地生成此错误。不可变结构仍然可以具有有效的属性设置器,只要属性设置器实际上不分配给结构中的任何字段。例如,
A
答案 5 :(得分:0)
值得注意的是,你可以通过以下方式克服这种行为:
Struct : IStruct
Struct strExplicitly;
示例:强>
public interface IStruct
{
int Age { get; set; }
}
public struct Struct : IStruct
{
public int Age { get; set; }
}
public class Test
{
IStruct strInterface { get; set; }
Struct strExplicitly;
public Test()
{
strInterface = new Struct();
strExplicitly = new Struct();
}
public void ChangeAge()
{
strInterface.Age = 2;
strExplicitly.Age = 2;
}
}