我有兩個文件。其中一個是類聲明,另一個是接口聲明。類應該實現接口。如果類實現接口方法,如何檢查NRefactory?如何檢查一個類是否實現NRefactory中的接口方法
我應該提供更多細節。
第一個文件 - 例如:
class Test : IF
{
}
和第二
interface IF
{
void Foo();
}
我要讀這些文件並NRefactory解析。我需要檢查類Test是否從IF接口實現方法。
沒有編譯和加載編譯程序集。
我有兩個文件。其中一個是類聲明,另一個是接口聲明。類應該實現接口。如果類實現接口方法,如何檢查NRefactory?如何檢查一個類是否實現NRefactory中的接口方法
我應該提供更多細節。
第一個文件 - 例如:
class Test : IF
{
}
和第二
interface IF
{
void Foo();
}
我要讀這些文件並NRefactory解析。我需要檢查類Test是否從IF接口實現方法。
沒有編譯和加載編譯程序集。
我在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;
另外,您也可以使用關鍵字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
那麼爲什麼不這樣做的時候了。
這是不是答案。我不得不爲編譯版本做源代碼。 – Krzysztof
在你的示例類中,如果Test沒有實現接口,它將不會編譯 – dmck
所以沒關係,因爲我不想編譯它。我想用NRefactory檢查這個。 – Krzysztof