当接口和具体位于不同的项目中时,“无法实现接口成员”错误
本文关键字:接口 成员 错误 实现 于不同 项目 | 更新日期: 2023-09-27 17:55:58
编译:
public interface IMyInterface
{
event Action<dynamic> OnSomeEvent;
}
class MyInterface : IMyInterface
{
public event Action<dynamic> OnSomeEvent;
}
但是当我将接口和实现分离到不同的项目时,我得到:
访问 'TestProject2.MyInterface.OnSomeEvent.remove' 无法实现接口成员 "InterfaceNamespace.IMyInterface.remove_OnSomeEvent(系统.操作)" 对于类型"TestProject2.MyInterface"。 使用显式接口 实现。
这只发生在动态参数...
很好的收获。这看起来可能是 C# 编译器中的一个错误 - 我会 ping Eric Lippert 看看他的想法。(dynamic
可能有点棘手;这个错误很可能有一个非常好但不明显的原因。
编辑:下面的代码似乎根本不起作用。我可以发誓我今天早上让它工作......我对发生了什么感到非常困惑。根据西蒙的评论,代码失败,并显示一条消息,指出该语言不支持它。
请注意,如果您确实使用显式接口实现,它似乎可以很好地编译:
// Doesn't actually compile - see edit above
class MyInterface : IMyInterface
{
private Action<dynamic> foo;
event Action<dynamic> IMyInterface.OnSomeEvent
{
// TODO (potentially): thread safety
add { foo += value; }
remove { foo -= value; }
}
}
编辑:这个答案的其余部分仍然成立...
请注意,您不能将类似字段的事件指定为显式实现的事件,即这不起作用:
event Action<dynamic> IMyInterface.OnSomeEvent;
它给出以下错误消息:
测试.cs(15,39): 错误 CS0071:事件的显式接口实现必须使用事件访问器语法
如果您只是尝试更改为事件访问器语法,则会收到与原始代码。
请注意,将事件更改为属性适用于自动实现的属性实现。
感谢您发布此问题,并感谢 Jon 以我的方式发送它。我已将其放入我们专门研究"动态"的测试人员之一的调查队列中。我们将看看我们是否可以弄清楚这里发生了什么。它闻起来肯定像虫子。
将来,请考虑在 connect.microsoft.com 上发布这样的东西;这样可以更快地将其发送给测试人员,并为我们提供更好的机制来获取有关该问题的更多信息。
这个答案是为了表达我对这个有趣问题的想法。不是真正的答案,而是对整个讨论的贡献,对于普通评论来说太小了。
我检查了一些东西,这个界面:
namespace DifferentAssemblyNamespace
{
public interface IBar
{
event Action<dynamic> OnSomeEvent;
}
}
及其实施:
// implicit interface implementation
// generates compile error "Explicit interface implementation"
public class Foo1 : IBar
{
private Action<dynamic> foo;
public event Action<dynamic> OnSomeEvent
{
add { foo += value; }
remove { foo -= value; }
}
}
// implicit interface implementation
// generates compile error "Not supported by the language"
public class Foo2 : IBar
{
private Action<dynamic> foo;
event Action<dynamic> IBar.OnSomeEvent
{
add { foo += value; }
remove { foo -= value; }
}
}
永远不会起作用,似乎一个规则排除了另一个必要的规则。
但是.. 如果我们调用泛型寻求帮助,并使用 Type 参数而不是直接使用 dynamic
,如下所示:
namespace DifferentAssemblyNamespace
{
public interface IGenericBar<T>
{
event Action<T> OnSomeEvent;
}
}
及其实施。
// implicit interface implementation
public class Foo3<T> : IGenericBar<T>
{
private Action<T> foo;
event Action<T> IGenericBar<T>.OnSomeEvent
{
add { foo += value; }
remove { foo -= value; }
}
}
出于某种原因,我们可以构建(应该)并运行:
/** does build **/
IGenericBar<dynamic> f = new Foo3<dynamic>();
f.OnSomeEvent += new Action<dynamic>(f_OnSomeEvent);
似乎类型参数做了一些编译器满意的额外操作。
我不确定发生了什么,所以我也想知道。
假设,高度假设(也许是废话)
但目前我把我的两分钱放在类型比较必须有通过添加/删除访问器进行包含事件的目标/方法。
我敢打赌编译器落在它不能保证什么的问题dynamic 位于外部程序集中,因此无法确定元素是否已在列表中,这是添加或删除它们所必需的。(因此显式接口实现)
我们都知道这只是其中的一部分属性对象,但似乎仍然它需要一个额外的步骤,其中一些强型是有保证的,那就是T 在编译时做什么。
/假设,高度假设(也许是废话)