2013-04-09 79 views
12

目前我正在到處找一個解決方案,其中具體的枚舉轉換爲字符串,不管是不是的ToString()顯式調用。 (這些被替換使用枚舉描述來改善模糊處理的轉化率。)到處尋找一個枚舉被轉換成字符串

實施例:我想找到代碼如string str = "Value: " + SomeEnum.someValue;

我試圖用含有隱式包裝類取代枚舉本身轉換到枚舉類型和壓倒一切的ToString()的包裝類,但是當我嘗試搜索的的ToString用途()重寫它給我的解決方案的地方一個列表,其中的ToString()被調用任何東西(也只有在那裏它被明確地調用)。搜索是在Visual Studio中使用ReSharper完成的。

有另一種方式來找到這些枚舉到字符串轉換?手動瀏覽整個解決方案並不像聽起來那麼有趣。

+7

羅斯林團隊,我已經標記這讓我知道你會看到它。 :-)當前發佈的Roslyn允許搜索AST進行這種轉換嗎? – 2013-04-09 00:14:32

+6

只是你已經做什麼的延伸,如果在你的包裝類,也爲你打造一個'implicit'轉換爲'string'並用'[作廢]'屬性,編譯器警告/錯誤將無處不在告訴你它的使用將其標記:http://stackoverflow.com/questions/10585594/how-to-get-find-usages-working-with-implicit-operator-methods這不是一個答案,但可能會幫助你在一個捏。 – 2013-04-09 00:40:21

回答

16

羅斯林的技巧是使用SemanticModel.GetTypeInfo()然後檢查ConvertedType找到這些類型的隱式轉換的。

一個完整的例子:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Roslyn.Compilers; 
using Roslyn.Compilers.CSharp; 
using Roslyn.Services; 
using Roslyn.Services.CSharp; 
using Roslyn.Compilers.Common; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var code = @"enum E { V } class { static void Main() { string s = ""Value: "" + E.V; } }"; 
     var doc = Solution.Create(SolutionId.CreateNewId()) 
      .AddCSharpProject("foo", "foo") 
      .AddMetadataReference(MetadataFileReference.CreateAssemblyReference("mscorlib")) 
      .AddDocument("doc.cs", code); 
     var stringType = doc.Project.GetCompilation().GetSpecialType(SpecialType.System_String); 
     var e = doc.Project.GetCompilation().GlobalNamespace.GetTypeMembers("E").Single(); 
     var v = e.GetMembers("V").Single(); 
     var refs = v.FindReferences(doc.Project.Solution); 
     var toStrings = from referencedLocation in refs 
         from r in referencedLocation.Locations 
         let node = GetNode(doc, r.Location) 
         let convertedType = doc.GetSemanticModel().GetTypeInfo(GetNode(doc, r.Location)).ConvertedType 
         where convertedType.Equals(stringType) 
         select r.Location; 
     foreach (var loc in toStrings) 
     { 
      Console.WriteLine(loc); 
     } 
    } 

    static CommonSyntaxNode GetNode(IDocument doc, CommonLocation loc) 
    { 
     return loc.SourceTree.GetRoot().FindToken(loc.SourceSpan.Start).Parent.Parent.Parent; 
    } 
} 
+1

好用的LINQ那裏凱文。 :-) – 2013-04-10 15:16:43

+0

我通常喜歡使用lambda語法,但在這種情況下,我真的希望使用let子句進行調試。 – 2013-04-11 14:54:52