Search code examples
c#roslyncodedom

System.CodeDom set InitExpression of a CodeMemberField


I'm creating a class file (.cs) with CodeDom:

CodeTypeDeclaration myClass = new CodeTypeDeclaration("MyClass");
myClass .TypeAttributes = TypeAttributes.Public;

CodeMemberField field = new CodeMemberField();
field.Name = "Attribute_1"
field.Type = new CodeTypeReference(***);
field.InitExpression = ???

I'm creating different attributes of different types like System.Drawing.Color or my custom classes. I wonder if there is way to handle the declaration assignment of attributes whose type is not a basic one nor array or list as in the example.


Solution

  • The correct method depends on how the object is instantiated. For example in the case of System.Drawing.Color you can instantiate a value using the static method

    public static System.Drawing.Color FromArgb (int argb);
    

    Therefore the initialization will result in:

    private System.Drawing.Color Attribute_1 = System.Drawing.Color.FromArgb(-1);
    

    To build such expression\assignment you have to instruct the code builder that you want to use a method (not a constructor) and that the method takes one int argument (primitive type).

    field.InitExpression = new CodeMethodInvokeExpression(
        new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(field.Type), "System.Drawing.Color.FromArgb"),
        new CodeExpression[] { new CodePrimitiveExpression(initialValue.ToArgb()) });
    

    Typically though, classes instantiate objects via constructors, in those cases you have to specify the type and the specific list of arguments to the builder. For example, if you built a 2D Point class, with a constructor that takes two point (X,Y) you can write:

    field.InitExpression = new CodeObjectCreateExpression(field.Type,
        new CodeExpression[] { 
            new CodePrimitiveExpression(initialValue.X),
            new CodePrimitiveExpression(initialValue.Y)
    });
                    
    

    (In this case, both arguments are doubles or floats so I used CodePrimitiveExpression.) You can generalize this last example on the basis of the classes that you are handling.

    You can check the documentation here:

    https://learn.microsoft.com/en-us/dotnet/api/system.codedom.codemethodinvokeexpression https://learn.microsoft.com/en-us/dotnet/api/system.codedom.codeobjectcreateexpression