2013-12-12 73 views
1

我有兩個文件。其中一個是類聲明,另一個是接口聲明。類應該實現接口。如果類實現接口方法,如何檢查NRefactory?如何檢查一個類是否實現NRefactory中的接口方法

我應該提供更多細節。

第一個文件 - 例如:

class Test : IF 
{ 
} 

和第二

interface IF 
{ 
    void Foo(); 
} 

我要讀這些文件並NRefactory解析。我需要檢查類Test是否從IF接口實現方法。

沒有編譯和加載編譯程序集。

回答

3

我在NRefactory代碼中找到解決方案。爲了實現我的目標,我修改了這個。首先,我們應該實現遊客這是否類實現從接口的每個方法:

public class MissingInterfaceMemberImplementationVisitor : DepthFirstAstVisitor 
{ 
    private readonly CSharpAstResolver _resolver; 
    public bool IsInterfaceMemberMissing { get; private set; } 
    public MissingInterfaceMemberImplementationVisitor(CSharpAstResolver resolver) 
    { 
     _resolver = resolver; 
     IsInterfaceMemberMissing = false; 
    } 

    public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration) 
    { 
     if (typeDeclaration.ClassType == ClassType.Interface || typeDeclaration.ClassType == ClassType.Enum) 
      return; 
     base.VisitTypeDeclaration(typeDeclaration); 
     var rr = _resolver.Resolve(typeDeclaration); 
     if (rr.IsError) 
      return; 
     foreach (var baseType in typeDeclaration.BaseTypes) 
     { 
      var bt = _resolver.Resolve(baseType); 
      if (bt.IsError || bt.Type.Kind != TypeKind.Interface) 
       continue; 
      bool interfaceMissing; 
      var toImplement = ImplementInterfaceAction.CollectMembersToImplement(rr.Type.GetDefinition(), bt.Type, false, out interfaceMissing); 
      if (toImplement.Count == 0) 
       continue; 

      IsInterfaceMemberMissing = true; 
     } 
    } 
} 

現在我們要讀所有的文件,解析它們並以下列方式調用上面的類:

var solutionFiles = new List<FileInfo>(); 
var trees = new Dictionary<FileInfo, SyntaxTree>(); 
IProjectContent projectContent = new CSharpProjectContent(); 
foreach (var file in solutionFiles.Where(f => f.Extension == ".cs").Distinct()) 
{ 
    var parser = new ICSharpCode.NRefactory.CSharp.CSharpParser(); 
    SyntaxTree syntaxTree; 
    using (var fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) 
    { 
     syntaxTree = parser.Parse(fs, file.FullName); 
    } 
    trees.Add(file, syntaxTree); 
    var unresolvedFile = syntaxTree.ToTypeSystem(); 
    projectContent = projectContent.AddOrUpdateFiles(unresolvedFile); 
} 
var compilation = projectContent.CreateCompilation(); 

foreach (var sharpFile in trees) 
{ 
    var originalResolver = new CSharpAstResolver(compilation, sharpFile.Value, sharpFile.Value.ToTypeSystem()); 
    var visitor = new MissingInterfaceMemberImplementationVisitor(originalResolver); 
    sharpFile.Value.AcceptVisitor(visitor); 
    if (visitor.IsInterfaceMemberMissing) 
     return false; 
    } 
return true; 
2

另外,您也可以使用關鍵字as

class MyClass { } 
interface IInterface { } 

MyClass instance = new MyClass(); 
var inst = instance as IInterface; 
if (inst != null) 
{ 
    // your class implements the interface 
} 

當您需要該實例後使用而無需額外的參考鍵入時使用此功能。使用is你仍然需要做

if (instance is IInterface) 
{ 
    var inst = (IInterface) instance; 
} 

(instance as IInterface).InstanceProperty 

那麼爲什麼不這樣做的時候了。

相關問題