![](/img/trans.png)
[英]How do I add a JsonIgnore attribute to all properties with a specific return type in a class using Roslyn?
[英]Using Roslyn for C#, how do I get a list of all properties that compose a return type?
假设我从一组方法中查询了一个方法:
var myMethod = someListofMethods.FirstOrDefault(m => m.Identifier.ValueText == myMethodName);
现在我想采用该方法的返回类型。 . .
var returnType = myMethod.ReturnType;
. . .并确定(如果它不是原始类型)该类型中包含哪些属性。
因此,例如,假设返回类型是定义的FooObject
:
public class FooObject{
public string Fizz {get; set; }
public string Buzz {get; set; }
}
如何正确询问FooObject
以获取其属性列表?
这是我已经尝试过的:
returnType.DescendantNodes().OfType<PropertyDeclarationSyntax>();
但这没有用。 提前致谢。
您正在查看代码的抽象语法树 (AST)级别。 因此行:
returnType.DescendantNodes().OfType<PropertyDeclarationSyntax>();
什么都不返回。 此上下文中的returnType
是 AST 的IdentifierNameSyntax
节点,仅包含文本FooObject
。 如果要分析返回类型,您应该:
returnType
角度解释语法树以找到返回类型的完整命名空间但是,这实际上是编译器所做的,因此您可以将 Roslyn 用法升级到编译级别,例如:
var workspace = Workspace.LoadSolution(solutionName);
var solution = workspace.CurrentSolution;
var createCommandList = new List<ISymbol>();
var @class = solution.Projects.Select(s => s.GetCompilation()
.GetTypeByMetadataName(className))
.FirstOrDefault();
var method = @class.GetMembers(methodName)
.AsList()
.Where(s => s.Kind == CommonSymbolKind.Method)
.Cast<MethodSymbol>()
.FirstOrDefault();
var returnType = method.ReturnType as TypeSymbol;
var returnTypeProperties = returnType.GetMembers()
.AsList()
.Where(s => s.Kind == SymbolKind.Property)
.Select(s => s.Name);
创建以下类CsharpClass.cs
:
public class CsharpClass
{
public string Name { get; set; }
public string Namespace { get; set; }
public List<CsharpProperty> Properties { get; set; }
public string PrimaryKeyType { get; set; }
public class CsharpProperty
{
public string Name { get; set; }
public string Type { get; set; }
public CsharpProperty(string name, string type)
{
Name = name;
Type = type;
}
}
public CsharpClass()
{
Properties = new List<CsharpProperty>();
}
}
创建以下帮助类CsharpClassParser.cs
:
public static class CsharpClassParser
{
public static CsharpClass Parse(string content)
{
var cls = new CsharpClass();
var tree = CSharpSyntaxTree.ParseText(content);
var members = tree.GetRoot().DescendantNodes().OfType<MemberDeclarationSyntax>();
foreach (var member in members)
{
if (member is PropertyDeclarationSyntax property)
{
cls.Properties.Add(new CsharpClass.CsharpProperty(
property.Identifier.ValueText,
property.Type.ToString())
);
}
if (member is NamespaceDeclarationSyntax namespaceDeclaration)
{
cls.Namespace = namespaceDeclaration.Name.ToString();
}
if (member is ClassDeclarationSyntax classDeclaration)
{
cls.Name = classDeclaration.Identifier.ValueText;
cls.PrimaryKeyType = FindPrimaryKeyType(classDeclaration);
}
//if (member is MethodDeclarationSyntax method)
//{
// Console.WriteLine("Method: " + method.Identifier.ValueText);
//}
}
return cls;
}
private static string FindPrimaryKeyType(ClassDeclarationSyntax classDeclaration)
{
if (classDeclaration == null)
{
return null;
}
if (classDeclaration.BaseList == null)
{
return null;
}
foreach (var baseClass in classDeclaration.BaseList.Types)
{
var match = Regex.Match(baseClass.Type.ToString(), @"<(.*?)>");
if (match.Success)
{
var primaryKey = match.Groups[1].Value;
if (AppConsts.PrimaryKeyTypes.Any(x => x.Value == primaryKey))
{
return primaryKey;
}
}
}
return null;
}
}
如何使用?
将类的内容作为字符串读取并将其传递给CsharpClassParser.Parse()
const string content = @"
namespace Acme.Airlines.AirCraft
{
public class AirCraft
{
public virtual string Name { get; set; }
public virtual int Code { get; set; }
public AirCraft()
{
}
}
}";
var csharpClass = CsharpClassParser.Parse(content);
Console.WriteLine(csharpClass.Name);
Console.WriteLine(csharpClass.Namespace);
Console.WriteLine(csharpClass.Properties.Count);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.