C# 如何使用Roslyn创建基于结构的属性

C# 如何使用Roslyn创建基于结构的属性,c#,roslyn,C#,Roslyn,我有以下代码来生成属性: 类型: types = new Dictionary<string, SpecialType>(); types.Add("Guid", SpecialType.System_Object); types.Add("DateTime", SpecialType.System_DateTime); types.Add("String", SpecialType.System_String); types.Add("Int32", SpecialType.Sys

我有以下代码来生成属性:

类型:

types = new Dictionary<string, SpecialType>();
types.Add("Guid", SpecialType.System_Object);
types.Add("DateTime", SpecialType.System_DateTime);
types.Add("String", SpecialType.System_String);
types.Add("Int32", SpecialType.System_Int32);
types.Add("Boolean", SpecialType.System_Boolean);  

generator.PropertyDeclaration(name, generator.TypeExpression(types["DateTime"]), Accessibility.Public);

我应该使用什么?

您可以根据类型的名称创建属性,因此可以使用以下代码创建DateTime和Guid属性

// Create an auto-property
var idProperty =
    SyntaxFactory.PropertyDeclaration(
        SyntaxFactory.ParseTypeName("Guid"),
        "Id"
    )
    .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
    .AddAccessorListAccessors(
        SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
        SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
    );

// Create a read-only property, using a backing field
var createdAtProperty =
    SyntaxFactory.PropertyDeclaration(
        SyntaxFactory.ParseTypeName("DateTime"),
        "CreatedAt"
    )
    .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
    .AddAccessorListAccessors(
        SyntaxFactory.AccessorDeclaration(
            SyntaxKind.GetAccessorDeclaration,
            SyntaxFactory.Block(
                SyntaxFactory.List(new[] {
                    SyntaxFactory.ReturnStatement(SyntaxFactory.IdentifierName("_createdAt"))
                })
            )
        )
    );
如果我遗漏了一些明显的东西,这意味着您不能使用这种语法,请您编辑您的答案并包含一个可执行的案例,好吗


我注意到,示例中的PropertyDeclaration方法指定的参数名称、类型和可访问性与SyntaxFactory类上的任何PropertyDeclaration方法签名都不对应-您编写的方法是否调用SyntaxFactory方法?

根据,Guid没有任何内容。你的约会时间看起来不错though@lokusking你知道为什么他们跳过了一个非常基本和常见的数据类型(如Guid)吗?@Nestor basic和common与special不是一回事。编译器只在必要时才考虑特殊类型,因为在某些情况下它需要以特殊方式处理该类型。@s单击对象或字符串的类型也是非常基本的,但它们出现在特殊类型中。为什么?为什么Guid如此特殊,以至于不能像字符串一样解释?最初的问题仍然存在:我可以创建Guid类型的属性吗?@Nestor object和string有它们自己的关键字,并且在生成IL时以特殊的方式处理,因此编译器认为它们是特殊的,这对我来说是有意义的。我可以使用SyntaxFactory,但您示例的结果是:Guid Id。没有getter,没有setter,但我打算创建自动属性,如Guid Id{get;set;}。我能和工厂一起实现吗?你的另一个问题:我使用的方法来自这个类:generator=SyntaxGenerator.GetGeneratorworkspace,LanguageNames.CSharp;PropertyDeclaration返回的PropertyDeclarationSyntax实例上有一些方法,例如AddModifiers,这样您可以公开属性,例如AddAccessorListAccessor,这样您可以添加getter和/或setter。我使用了这段代码,没有出现setter或getter,非常奇怪:我对代码示例进行了一些扩展,为属性指定了一个修饰符和一个getter——这有帮助吗?当我调用idProperty.ToString时,它返回PublicGuided{get{return_id;}},这表明它的工作取决于您对PropertyDeclarationSyntax实例所做的操作,如果_id引用,您可能会遇到问题,但希望示例代码足以帮助您继续。几乎达到了目标,我用以下代码修改了您的代码:SyntaxFactory.Block SyntaxFactory.Listnew[]{SyntaxFactory.EmptyStatement}。不幸的是,它创建了一个无效代码,因为get语句的分号周围仍然有大括号。我必须取下牙套,但我不知道怎么做。
// Create an auto-property
var idProperty =
    SyntaxFactory.PropertyDeclaration(
        SyntaxFactory.ParseTypeName("Guid"),
        "Id"
    )
    .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
    .AddAccessorListAccessors(
        SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
        SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
    );

// Create a read-only property, using a backing field
var createdAtProperty =
    SyntaxFactory.PropertyDeclaration(
        SyntaxFactory.ParseTypeName("DateTime"),
        "CreatedAt"
    )
    .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
    .AddAccessorListAccessors(
        SyntaxFactory.AccessorDeclaration(
            SyntaxKind.GetAccessorDeclaration,
            SyntaxFactory.Block(
                SyntaxFactory.List(new[] {
                    SyntaxFactory.ReturnStatement(SyntaxFactory.IdentifierName("_createdAt"))
                })
            )
        )
    );