0

I have method that assign value to property and generate code statement using C# CodeDOM.

private static CodeAssignStatement setProp(string propName, object propValue, Type propType, Type objType)
{
                CodeAssignStatement declareVariableName = null;
                if (propType.IsPrimitive)
                {
                    declareVariableName = new CodeAssignStatement(
                   new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("testObj"), propName), new CodePrimitiveExpression(propValue)
                   );
                }
                else
                {
                    declareVariableName = new CodeAssignStatement(
                    new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("testObj"), propName),
                     new CodeVariableReferenceExpression("\"" + propValue?.ToString() + "\"")
                    );
                }

                return declareVariableName;
}

For primitive value it is generating statements correctly. However, for rest, e.g. DateTime it generates statement like testObj.PurchasedOn = "17-09-2016 18:50:00";. One way to use target data type "Parse" methods. But it may not be available for other data types. How can I construct object? Is there any method available in framework?

1
  • I don't think there is a general way to do this, since every type can be constructed in a different way (and some don't even have public way to construct them). Commented Sep 17, 2016 at 13:40

2 Answers 2

0

The problem you're facing is that you are attempting to assign a value to a variable where the variable is an object data type.

int i = 123; // This is fine as it assigns the primitive value 123 to the integer variable i.
string s = "123"; // This is also fine as you're assigning the string value "123" to the string variable s.
string t = s; // This is fine as long as variable s is a string datatype.

Your code is attempting to assign a value to an object datatype.

testObj.PurchasedOn = "17-09-2016 18:50:00"; // This won't work as you cannot assign a string constant to a DateTime variable.

As you mention, you could use the Parse method if it is available.

If we look at the code you are expecting to produce it would most likely look like this:

testObj.PurchasedOn = new DateTime(2016, 09, 17, 18, 50, 0);

As you can see, for the DateTime object constructor you would need to specify 6 parameters. This will obviously vary for every object type you wish to create.

The solution lies in the CodeObjectCreateExpression class which can be used in place of the CodePrimitiveExpression class.

I would suggest changing your method to accept a CodeExpression rather than object propValue. That way you can provide a primitive or an object instantiator.

In this case you could pass to your method:

new CodeObjectCreateExpression(typeof(DateTime), 2016, 09, 17, 18, 50, 0);

You can find more details on CodeObjectCreateExpression here.

Sign up to request clarification or add additional context in comments.

Comments

-1

What if you just get rid of your conditional and do:

private static CodeAssignStatement setProp(string propName, object propValue, Type propType, Type objType)
{
    CodeAssignStatement declareVariableName = null;
    declareVariableName = new CodeAssignStatement(
        new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("testObj"), propName),
        new CodePrimitiveExpression(propValue)
    );

    return declareVariableName;
}

CodePrimitiveExpression appears to take in an object, which means you can assign pretty much anything to it. As such, if you pass in a DateTime, it will be correctly stored as such.

2 Comments

As name suggests, method is for primitive types only. For your code, it gives exception -Unhandled Exception: System.ArgumentException: Invalid Primitive Type: System.DateTime. Consider using CodeObjectCreateExpression.
Posted the answer only because it's working fine on my end. Using Mono 4.6 on OS X.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.