【问题标题】:Cannot retrieve explicit interface implemented member无法检索显式接口实现成员
【发布时间】:2014-06-05 17:23:27
【问题描述】:

我正在使用 Roslyn 分析 C# 代码,但在使用显式实现的接口时遇到了问题。给定实现接口的类型,我无法按名称检索显式实现的成员。例如:

var tree = CSharpSyntaxTree.ParseText(@"
using System;

namespace ConsoleApplication1
{
    class MyClass : IDisposable
    {
        void IDisposable.Dispose()
        {
        }
        public void Dispose()
        {
        }
    }
}");

var Mscorlib = new MetadataFileReference(typeof(object).Assembly.Location); 
var compilation = CSharpCompilation.Create("MyCompilation",
    syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
var model = compilation.GetSemanticModel(tree);

var myType = compilation.GetTypeByMetadataName("ConsoleApplication1.MyClass");
var dispose = myType.GetMembers("Dispose").SingleOrDefault();
//explicitDispose is null.
var explicitDispose = myType.GetMembers("IDisposable.Dispose").SingleOrDefault();

只有当类型存在于命名空间中时才会出现这种情况,以下代码可以正常工作。

var tree = CSharpSyntaxTree.ParseText(@"
class MyClass : IDisposable
{
    void IDisposable.Dispose()
    {
    }
    public void Dispose()
    {
    }
}");
var Mscorlib = new MetadataFileReference(typeof(object).Assembly.Location); 
var compilation = CSharpCompilation.Create("MyCompilation",
    syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
var model = compilation.GetSemanticModel(tree);

var myType = compilation.GetTypeByMetadataName("MyClass");
var dispose = myType.GetMembers("Dispose").SingleOrDefault();
//explicitDispose is not null.
var explicitDispose = myType.GetMembers("IDisposable.Dispose").SingleOrDefault();

有人知道为什么会这样吗?有没有更好的方法来处理显式实现的接口?

【问题讨论】:

    标签: c# roslyn explicit-interface


    【解决方案1】:

    看来您需要在明确实现后提供完全限定的方法签名:

    var explicitDispose = myType.GetMembers("System.IDisposable.Dispose").SingleOrDefault();
    

    (我打算删除这个问题,但我看到有人将其标记为收藏,所以我会提供适合我的答案)

    【讨论】:

    • 回答你自己的问题并没有什么坏处——堆栈溢出的一半是它是下一个人想知道这个问题的答案的来源!
    【解决方案2】:

    使用ITypeSymbol.FindImplementationForInterfaceMethod。这些方法不应该“按名称”找到。

    【讨论】:

    • 其实这一步在我使用 FindImplementationForInterface() 之前。问题是我需要传入正确的接口成员。所以我必须首先在界面中找到那个成员。我基本上是在尝试从 MyClass.System.IDisposable.Dispose() => System.IDisposable.Dispose()
    • 也就是说,给定一个具体的方法,我试图找到它是在哪个接口中定义的(如果它是在一个接口中定义的)。
    • 您正在寻找的答案不是唯一的,因为一个方法可能实现多个接口方法。遍历该名称的所有已实现接口方法,并查看其实现是否是您的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 2023-01-31
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多