簡體   English   中英

如何獲取屬性的后備字段(AssociatedPropertyOrEvent為null)?

[英]How to get the backing field for the property (AssociatedPropertyOrEvent is null)?

我正在嘗試使用Roslyn來獲取對該屬性的支持字段的符號(FieldSymbol)的引用,但是AssociatedPropertyOrEvent為null。 這是單元測試失敗。

[Test]
public void Get_BackingField_for_Property()
{

    var sourceCode = @" public class Player
                    {
                        private Person _MyPerson;

                        public virtual Person MyPerson
                        {
                            get { return _MyPerson; }
                        }

                        public virtual void Set(Person person)
                        {
                            _MyPerson = person;
                        }
                    }";


    var syntaxTree = SyntaxTree.ParseText(sourceCode);


    var mscorlib = MetadataReference.CreateAssemblyReference(
                                     "mscorlib");


    var compilation = Compilation.Create("HelloWorld")
                    .AddReferences(mscorlib)
                    .AddSyntaxTrees(syntaxTree);

    //var  semanticModel = compilation.GetSemanticModel(syntaxTree);

    var classSymbol =
        compilation.GetTypeByMetadataName("Player");

    Assert.That(classSymbol,Is.Not.Null, "class");

    var propertySymbol = classSymbol.GetMembers().Where(x => x.Kind == SymbolKind.Property);

    Assert.That(propertySymbol, Is.Not.Null, "property");

    var backingField = classSymbol.GetMembers().Where(x=>x.Kind== SymbolKind.Field).Cast<FieldSymbol>().First();

    Assert.That(backingField.AssociatedPropertyOrEvent, Is.Not.Null,"backing field");

更新:對於嘗試執行相同操作的任何人,INotifyPropertyChaged示例都具有獲取屬性的支持字段的代碼。 我修改它以滿足我的需要。 這是代碼

internal static IFieldSymbol GetBackingField(this IPropertySymbol property, ISemanticModel semanticModel)
{
    var propertyDelcarationSyntax = (PropertyDeclarationSyntax)property.DeclaringSyntaxNodes.First();

    var getter = propertyDelcarationSyntax.AccessorList.Accessors.First(a => a.Kind == SyntaxKind.GetAccessorDeclaration);

    return GetBackingFieldFromGetter(getter, semanticModel);
}
private static IFieldSymbol GetBackingFieldFromGetter(AccessorDeclarationSyntax getter, ISemanticModel semanticModel)
{
    // The getter should have a body containing a single return of a backing field.

    if (getter.Body == null)
    {
        throw new Exception("Missing a getter body for property " + semanticModel.GetDeclaredSymbol(getter.Parent).Name);
    }

    var statements = getter.Body.Statements;
    if (statements.Count != 1)
    {
        throw new Exception("Getter body has more then one statement for property " + semanticModel.GetDeclaredSymbol(getter.Parent).Name);
    }

    var returnStatement = statements.Single() as ReturnStatementSyntax;
    if (returnStatement == null || returnStatement.Expression == null)
    {
        throw new Exception("Getter body is missing a return statement for property " + semanticModel.GetDeclaredSymbol(getter.Parent).Name);
    }

    return semanticModel.GetSymbolInfo(returnStatement.Expression).Symbol as IFieldSymbol;
}

AssociatedPropertyOrEvent的文檔說:

如果此字段用作自動生成的屬性或類字段事件的后備變量,則返回該屬性/事件。 否則返回null。

由於您的字段與任何autoproperties無關,因此AssociatedPropertyOrEvent正確返回null

一般來說,你所要求的是不可能的,因為可能有許多屬性訪問同一個字段。

您只能使用當前的API進行其他方式。 使用GetMembers獲取所有這些,然后找到其AssociatedPropertyOrEvent是您想要的屬性的字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM