- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
假设我有以下代码。如何通过反射获取 MemberInfo/PropertyInfo
以“显式”实现 Test.Name
?
此外,有没有什么方法可以通过编程知道 MemberInfo
是接口(interface)属性的显式实现?
public interface ITest
{
string Title { get; set; }
}
public interface IExplicit
{
string Name { get; set; }
}
public class Test : ITest,IExplicit
{
public string Title { get; set; }
string IExplict.Name
{
get
{
return this.Title;
}
set
{
}
}
}
最佳答案
假设您有这个界面:
interface ITest
{
bool MyProperty { get; set; }
}
在这个类中实现:
class Test : ITest
{
bool ITest.MyProperty { get; set; }
}
现在让我们将此属性添加到 Test
(注意它们具有相同名称):
public bool MyProperty { get; set; }
使用 plain GetProperties()
,您不会获得显式接口(interface)实现(因为它始终是私有(private)成员):
int count = new Test().GetType().GetProperties().Length; // It's 1!
如果您同时包含 Public
和 NonPublic
成员,您将获得两者。要区分它们,您可以首先依靠名称:显式实现将包含完整的接口(interface)名称(因此您可以查找 .
,普通 属性,因为它不是允许的字符):
public static bool IsExplicitInterfaceImplementation(PropertyInfo property)
{
return property.Name.Contains(".");
}
这有点天真,所以您可能需要一些额外的检查,您可以断言该属性的 get 方法将:
虚拟
和密封
。私有(private)的
。get_
或 _set
开头让我们更改代码:
public static bool IsExplicitInterfaceImplementation(PropertyInfo property)
{
// This check is not mandatory and not cross-languages.
// How this method is named may vary
if (!property.Name.Contains("."))
return false;
if (property.Name.StartsWith("get_"))
return false;
if (!property.GetMethod.IsFinal)
return false;
if (!property.GetMethod.IsVirtual)
return false;
if (!property.GetMethod.IsPrivate)
return false;
return true;
}
当然不需要所有这些检查,我认为前两个足以排除大部分编译器生成的代码。
如果您知道可以显式实现哪个接口(interface),您会发现这里的这个问题非常有用:How to find if a method is implementing specific interface
编辑
从评论中我想到了这一点,我发现没有合适的方法来做到这一点,CLR 不应用任何规则(AFAIK),因为需要的只是接口(interface)方法和类方法之间的链接(无论它如何调用)。我想(但它可能会放宽或扩展到其他语言,如果有人愿意为更多测试做出贡献,我会将这个答案作为 wiki)这段代码在大多数情况下可能有效(感谢 Alxandr 的提示):
检查方法(给定 MethodInfo
)是否为显式接口(interface)实现的第一个通用函数。
我们不能断言的是:
我们不能使用名称(例如检查“.”),因为它依赖于实现(C# 使用 interfaceName.methodName 但其他语言不使用)。
我们不能依赖检查私有(private),因为(例如)在 C++/CLI 中,它可以是一个公共(public)方法(使用另一个名称),而且一个接口(interface)可以被“黑化”为内部的,但实现者可以公开(因此方法也不会公开)。
我们可以断言:
显式接口(interface)实现始终是密封的和虚拟的。可能并非所有语言都适用,因此我们可能会放宽此规则。
如果一个方法与它实现的接口(interface)中声明的方法名称不同,那么它就是一个显式实现。
这是代码:
public static bool IsExplicitInterfaceImplementation(MethodInfo method)
{
// Check all interfaces implemented in the type that declares
// the method we want to check, with this we'll exclude all methods
// that don't implement an interface method
var declaringType = method.DeclaringType;
foreach (var implementedInterface in declaringType.GetInterfaces())
{
var mapping = declaringType.GetInterfaceMap(implementedInterface);
// If interface isn't implemented in the type that owns
// this method then we can ignore it (for sure it's not
// an explicit implementation)
if (mapping.TargetType != declaringType)
continue;
// Is this method the implementation of this interface?
int methodIndex = Array.IndexOf(mapping.TargetMethods, method);
if (methodIndex == -1)
continue;
// Is it true for any language? Can we just skip this check?
if (!method.IsFinal || !method.IsVirtual)
return false;
// It's not required in all languages to implement every method
// in the interface (if the type is abstract)
string methodName = "";
if (mapping.InterfaceMethods[methodIndex] != null)
methodName = mapping.InterfaceMethods[methodIndex].Name;
// If names don't match then it's explicit
if (!method.Name.Equals(methodName, StringComparison.Ordinal))
return true;
}
return false;
}
用这个辅助函数来做属性检查:
public static bool IsExplicitInterfaceImplementation(PropertyInfo property)
{
// At least one accessor must exists, I arbitrary check first for
// "get" one. Note that in Managed C++ (not C++ CLI) these methods
// are logically separated so they may follow different rules (one of them
// is explicit and the other one is not). It's a pretty corner case
// so we may just ignore it.
if (property.GetMethod != null)
return IsExplicitInterfaceImplementation(property.GetMethod);
return IsExplicitInterfaceImplementation(property.SetMethod);
}
关于c# - 如何知道 MemberInfo 是否是属性的显式实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17853671/
我刚刚更新了 Ruby,现在我在尝试启动 compass 时遇到以下错误: Encoding::CompatibilityError on line ["28"] of /usr/local/Cell
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 6 年前。
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在尝试在我的 iOS 应用程序中开发可折叠/ Accordion 式的功能。这将是您可以在网站上找到的典型 FAQ 类型功能。我想点击标题,然后显示详细信息。 因为这是帮助部分,只有几个项目,我认
我正在尝试设计一个基于 REST 的 Web 服务来与我正在开发的农场动物管理系统进行交互。 为了详细说明问题,我收藏了动物 属于一个农场。每只动物都有自己的信息——例如姓名、身份证号、品种年龄等。因
我有 3 种不同的表单,其中复选框数量不同,每个部分基本上代表一个表单,因此当用户选择该部分中的复选框时,它会显示他们在该部分的总金额中 checkout 了多少 HTML
我有一份 32 页的 PDF 版家谱。与其将家谱全部放在一个非常大的 PDF 页面上(这是我想要的),不如将其格式化为一组 8 个单独的美国信纸大小的页面应该在整个宽度上缝合; 4 行这样就完成了树。
指SASS implementation for Java? : 在 Maven 目标编译包中自动编译 compass-style.org 样式表的最佳方法是什么? 我不想发送太多的自编译库,也不想通
鉴于以下 XAML... 我正在寻找一种绑定(bind) ComboBox、Button 和 Command 的方法,以便当 ComboBox 的值更改时,在 Command 上调用 CanExe
在玩具应用程序中,我有一个显示所有帖子标题的“帖子”模板。当您单击每个标题时,我不想直接进入“显示” View ,而是直接内联展开该帖子的其余内容。 我考虑过让 postRoute 重用 postsR
我需要一些使用 Twitter Bootstrap 或其他响应式框架的自定义 Swagger-UI 实现。需要在我的移动设备上使用这样的 UI 测试我的 API,但 swagger-ui 不能很好地扩
我正在做一个项目,我真的在尝试编写面向对象的 JavaScript 代码。我刚刚开始阅读Douglas Crockford's JavaScript: The Good Parts我很快开始意识到用
在 C# 中,我通过执行以下操作来加密文本数据(请注意我正在以 block ( block )的形式加密数据): public string EncryptData(string pu
我正在构建一个社交网站,该网站将向全世界公开 REST API (WCF WebAPI),以便任何开发人员都能够为该网站创建客户端应用程序、将其与其他服务集成等。 我想为 API 实现 Faceboo
我是一名优秀的程序员,十分优秀!