简体   繁体   中英

Trying to create a type in Roslyn from a Type, but I get BadImageFormatException when converting a nullable

I'm trying to write a function that takes in an existing Type, and converts the Type to a PropertyDeclaration. I almost have it working, but if the Type I pass in is Nullable, I get this error when I eventually try to compile my class with it: System.BadImageFormatException: is not a valid Win32 application. (Exception from HRESULT: 0x800700C1).

Here's my code:

var classDeclaration = SyntaxFactory.ClassDeclaration("class name");
classDeclaration.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword));
classDeclaration.AddMembers(ConvertToProperty(myType, myTypeName));

private static PropertyDeclarationSyntax ConvertToProperty(Type propertyType, string propertyName)
{
    var typeSyntax = SyntaxFactory.ParseTypeName(propertyType.ToString());
    var propertyDeclaration = SyntaxFactory.PropertyDeclaration(typeSyntax, propertyName)
        .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
        .AddAccessorListAccessors(
            SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
            SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)));

    return propertyDeclaration;
}

The class will compile just fine if the Type I pass in is not nullable. I'm not very familiar with Roslyn and I haven't found any examples online of someone doing what i'm trying to do. Is anyone more familiar and has an idea?

First, you really need to add more details to your question. Look here: Minimal, Complete, and Verifiable example

To your problem, when you run your code on a non nullable type, lets say int you will get this output:

public class MyClass
{
    public System.Int32 MyProperty { get; set; }
}

But with nullable , you will get this:

public class MyClass
{
    public System.Nullable`1[System.Int32] MyProperty { get; set; }
}

You can see that it is not a valid C# code.

To solve it, check this answer , just copy paste and the result will look like this:

public class MyClass
{
    public Nullable<Int32> MyProperty { get; set; }
}

Full code:

private static PropertyDeclarationSyntax ConvertToProperty(Type propertyType, string propertyName)
{
    var typeSyntax = ParseTypeName(propertyType.ToGenericTypeString());
    return PropertyDeclaration(typeSyntax, propertyName)
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddAccessorListAccessors(
                AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
                AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
}

var classDeclaration = ClassDeclaration("MyClass");
classDeclaration = classDeclaration.AddModifiers(Token(SyntaxKind.PublicKeyword));
classDeclaration = classDeclaration.AddMembers(ConvertToProperty(typeof(int?), "MyProperty"));

Console.WriteLine(classDeclaration.ToString());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM