'Code generation for struct property of user control

I create a user control like below:

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; }
        }
    }
}

Then I can drag the control from toolbox and modify the Data value in the designer.

property

The problem is the designer will generate this code in InitializeComponent method:

this.testControl1.MyState.Data = 0;

But this line will throw an error:

Cannot modify the return value of 'TestControl.MyState' because it is not a variable

I understand why the statement is error, the question is how can I control the code generation to correct the error, for example to generate code like this?

var myState = this.testControl1.MyState;
myState.Data = 0;

More information

  • State struct is just a bridge to modify the internal property in TestControl

  • So I want to keep State as a struct to avoid GC overhead.

  • The reason for not define property in TestControl class is there are multiple states in the class, and a state will contain multiple properties, so I need to wrap the modification methods rather than define a lot of properties in the TestControl class.



Solution 1:[1]

Why a compile time error for Control.StructProperty.Member = Value;?

Consider the following statement

this.Control.StructProperty.Value = 0;

StructProperty is a property, so first its getter will execute and since it's a structure and is a value type, it will return a copy of the struct and setting a property for that copy is not useful/working. The knows about the situation well and instead of compiling a confusing non-working code, it generates Compiler Error CS1612:

Cannot modify the return value of 'expression' because it is not a variable

How can I generate a working code for a Struct property?

You probably have noticed that you cannot assign this.Size.Width = 100 with the same reason. And the way that form generates the code for Size property is:

this.Size = new Size(100,100);

You also can generate code for the property the same way, by implementing a type descriptor by deriving from TypeConverter returning an InstanceDescriptor in its ConvertTo method to generate the code for your structure property using a parametric constructor which you should have for the struct.

In general, I suggest using classes rather that structures for such property.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1