我创建了一个如下所示的用户控件:
public partial class TestControl : UserControl
{
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public State MyState
{
get { return new State(this); }
}
internal int[] _internalStates;
[TypeConverter(typeof(ExpandableObjectConverter))]
public struct State
{
private TestControl _myControl;
public State(TestControl _) { _myControl = _; }
public int Data
{
get { return _myControl._internalStates[0]; }
set { _myControl._internalStates[0] = value; }
}
}
}
然后我可以从工具箱中拖动控件并修改设计器中的Data
值。
问题是设计人员将在InitializeComponent
方法中生成此代码:
this.testControl1.MyState.Data = 0;
但是这一行会引发一个错误:
无法修改'TestControl.MyState'的返回值,因为它不是变量
我理解为什么语句是错误的,问题是如何控制代码生成以纠正错误,例如生成这样的代码?
var myState = this.testControl1.MyState;
myState.Data = 0;
更多信息
State
结构只是修改TestControl
内部属性的桥梁State
作为结构,以避免GC开销。TestControl
类中没有定义属性的原因是类中有多个状态,并且状态将包含多个属性,因此我需要包装修改方法而不是在TestControl
类中定义许多属性。为什么Control.StructProperty.Member = Value;
的编译时错误?
请考虑以下声明
this.Control.StructProperty.Value = 0;
StructProperty
是一个属性,所以首先它的getter将执行,因为它是一个结构并且是一个值类型,它将返回一个struct的副本,并为该副本设置一个属性是没用的/工作。它很好地了解情况,而不是编译令人困惑的非工作代码,它生成Compiler Error CS1612:
无法修改'expression'的返回值,因为它不是变量
如何为Struct属性生成工作代码?
你可能已经注意到你不能用同样的原因分配this.Size.Width = 100
。表单为Size
属性生成代码的方式是:
this.Size = new Size(100,100);
您也可以通过相同的方式为属性生成代码,方法是通过从TypeConverter
派生InstanceDescriptor
返回ConvertTo
来生成类型描述符,使用参数构造函数为结构属性生成代码。
一般来说,我建议使用类而不是这种属性的结构。