我创建如下用户控件:
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
类中的属性。
答案 0 :(得分:2)
为什么Control.StructProperty.Member = Value;
出现编译时错误?
考虑以下语句
this.Control.StructProperty.Value = 0;
StructProperty
是一个属性,因此首先将执行其getter,并且由于它是一个结构且是一个值类型,因此它将返回该结构的副本,并且为该副本设置属性是无用的/不起作用的。对此情况了解得很好,它不会生成令人困惑的无效代码,而是生成Compiler Error CS1612:
无法修改'expression'的返回值,因为它不是 变量
如何为Struct属性生成工作代码?
您可能已经注意到,您不能出于相同的原因分配this.Size.Width = 100
。表单生成Size
属性代码的方式是:
this.Size = new Size(100,100);
您还可以以相同的方式为属性生成代码,方法是通过从TypeConverter
派生ConvertTo
的{{1}}方法中返回InstanceDescriptor
来生成结构代码,属性,它应使用该结构应具有的参数构造函数。
通常,我建议为此类属性使用类而不是结构。