2016-11-30 70 views
1

我正在研究一個WPF應用程序,它需要解析來自C#類的代碼,並確定每個屬性(訪問修飾符,數據類型,屬性名等等)的屬性和不同部分。 )。我目前有一個粗糙的實現,使用一些字符串解析和猜測來確定我需要什麼,但這並不理想。解析和識別C#代碼

因此,舉例來說,如果C#代碼:

public int ID {get;set;} 
public string Name {get;set;} 
string Address {get;set} 

我希望得到的東西,如:

Collection[0] = {Modifier => public, Datatype => int, PropertyName => ID} 
Collection[1] = {Modifier => public, Datatype => string, PropertyName => name} 
Collection[2] = {Modifier => , Datatype => string, PropertyName => address} 

我不知道什麼被搜索。術語:反射,表達樹,T4模板不斷出現在我的研究中,但我不確定我是否在正確的路徑上。

我需要的是對前進道路的一些建議。

+5

現在Roslyn已經發布,你可以使用這些庫。反射僅適用於運行時的代碼,其他兩種聽起來不像您要查找的內容。 – BradleyDotNET

+0

構建代碼並使用反射?但是這似乎過於寬泛的一個問題。 – crashmstr

+0

如果您只需要擔心屬性,可以使用C#的語法創建自己的解析器,而不會有太多困難。 – Abion47

回答

-2

你有沒有想過使用正則表達式? 你的領域例如可以降低到簡單的正則表達式表達:

@"(?:(public|protected|internal|private|protected internal)\s+)?([a-zA-Z_]+\w*)\s+([a-zA-Z_]+\w*)" 

我還設置了一個rextester方案爲您here

+0

正則表達式從不用於解析實際代碼。 –

+0

以及他提到的字符串解析...實際上沒有提到解析OP – maksymiuk

+0

中的實際代碼你可以騙過我。我引用:*需要解析來自C#類的代碼* –

1

如果你想分析的C#代碼和提取的屬性和方法,你將需要一個完整的C#解析器。 (正則表達式解決方案從來沒有解析,爲什麼人們不知道這一點?)。

你不想爲此重新創建一個解析器; c#語法很複雜,要正確地做到這一點很困難。使用ANTLR,或我們的DMS軟件重新設計工具包,或者Roslyn。

ANTLR with the C# grammar可以爲您提供一個分析樹。如果您需要更復雜的分析(例如,您想知道實際類型的變量),則您將需要多於一個分析樹,請參閱Life After Parsing

DMS Software Reengineering Toolkit有一個完整的C#解析器,並提供支持解析後生命所需的所有機器。

Roslyn擁有完整的C#解析器並處理分析後的生活中討論的符號表問題。

如果您只打算解析代碼片段而不是獨立編譯源文件,那麼您的任務將更加複雜,特別是如果您需要類型信息。

1

我會使用C#的內置功能來實時編譯代碼,並結合Reflection來檢查構建的程序集。

該實施例利用了代碼的任意片,對其進行編譯,然後打印包含類的屬性:

const string MyCode = @" 
namespace MyNamespace { 
    public class MyClass { 
     public string Prop1 { get; set; } 
     public int Prop2 { get; set; } 
     public double Prop3 { get; set; } 
    } 
}"; 

var compiler = new Microsoft.CSharp.CSharpCodeProvider(); 
var options = new System.CodeDom.Compiler.CompilerParameters(); 
options.GenerateInMemory = true; 
var results = compiler.CompileAssemblyFromSource(options, MyCode); 

foreach (var compiledType in results.CompiledAssembly.GetTypes()) 
{ 
    foreach (var property in compiledType.GetProperties()) 
    { 
     Console.WriteLine("{0}.{1} is {2}", compiledType.Name, property.Name, property.PropertyType.Name); 
    } 
} 

輸出看起來像這樣:

MyClass.Prop1 is String 
MyClass.Prop2 is Int32 
MyClass.Prop3 is Double 

的屬性元數據應爲您提供所有您需要的信息。