为什么下面的代码抛出System.Reflection.AmbiguousMatchException谁能给我解释一下?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么下面的代码抛出System.Reflection.AmbiguousMatchException谁能给我解释一下?相关的知识,希望对你有一定的参考价值。
using System;
using System.Reflection;
namespace A
interface IObjectWithId<TId>
TId Id get;
interface IEntityBase : IObjectWithId<object>
new object Id get;
abstract class BusinessObject<TId> : IObjectWithId<TId>
public abstract TId Id get;
class EntityBase : BusinessObject<object>, IEntityBase
public override object Id get return null;
public static class Program
public static void Main()
Console.WriteLine(typeof(EntityBase).GetProperty("Id", BindingFlags.Instance | BindingFlags.Public));
我得到这个:
System.Reflection.AmbiguousMatchException was unhandled
Message="Ambiguous match found."
Source="mscorlib"
StackTrace:
at System.RuntimeType.GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
at System.Type.GetProperty(String name, BindingFlags bindingAttr)
at A.Program.Main() in C:\Home\work\A\Program.cs:line 26
InnerException:
微软的Visual Studio 2008 版本9.0.30729.1 SP Microsoft .NET框架 3.5版SP1
编辑:
奇怪的是,看起来像其他人无法复制它。尽管它在我的机器上的每一次崩溃。我发现这样的代码:
Console.WriteLine(typeof(EntityBase).GetProperty("Id", BindingFlags.Instance | BindingFlags.Public, null, typeof(object), Type.EmptyTypes, null));
是否工作正常,但它应该是相同的。
为了让您的问题回答了,我去给你熟悉的术语“方法表”。这是在.NET框架中,其中每一个.NET类型有其自己的方法的表类型的内部表示的一部分。可以把它想象成包含所有方法和类型的属性的散列映射(或字典)。关键是该方法/属性签名(方法名称和参数类型,而不返回类型),值是匹配的方法/属性,沿着诸如类型已声明的方法/属性一些反射的元数据信息的集合。
当类A
从基类派生 - B
,或实现一个接口C
,在B
的方法表中的项目和在C
的A
方法表成为直接可用。如果A
的方法表已经包含某些签名的项目,该项目被添加到集合相同的签名,所以现在A
将有2种方法/属性的签名点。区分这些重复条目的唯一方法是通过比较描述上代表声明的签名类型的元数据。
让我们接口IObjectWithId<TId>
,它定义了属性TId ID get; set;
。所述EntityBase
类实现IObjectWithId<TId>
所以接收TId ID get; set;
属性及其方法表。同时,这个类实现了IEntityBase
接口,这使得它的Object ID get; set;
财产。该EntityBase
类,然后接收相同的签名(因为返回类型不参加签名)下的两个属性,同时它仍然会暴露出2个不同的属性。下面的声明将导致编译错误:
public class EntityBase : IEntityBase, IObjectWithId<int>
public int ID get; set;
因为qazxsw POI未实现。同样,以下也将失败:
IEntityBase
因为这个时候 public class EntityBase : IEntityBase, IObjectWithId<int>
public object ID get; set;
不满意。你可以试试这样做:
IObjectWithId<int>
刚收到另一个编译错误,有2-8特性具有相同签名。
上班这周围的方式,是落实冲突的特征明确的至少一个:
public class EntityBase : IEntityBase, IObjectWithId<int>
public object ID get; set;
public int ID get; set;
现在,回到你的代码 - 你用 public class EntityBase : IEntityBase, IObjectWithId<int>
private object objID;
private int intID;
object IEntityBase.ID get return objID; set objID = value;
int IObjectWithId<int>.ID get return intID; set intID = value;
代替object
它创建了一个罕见的,但有趣的例子 - 因为他们的签名相同的两个TId
性统一。所以这个类:
ID
将编译,因为 public class EntityBase : IEntityBase, IObjectWithId<object>
public object ID get; set;
属性满足这两个接口。然而,ID
类仍然在其方法表中的两个EntityBase
属性(一个未来形式中,每个接口)。两个属性被自动分配给由编译器在ID
类相同的实现(该过程被称为统一)。
下面的代码:
EntityBase
将调查typeof(EntityBase).GetProperty(
"ID", BindingFlags.Instance | BindingFlags.Public);
类的方法表,会看到该签名2个属性条目,并不会知道哪一个选择。
这是因为你可能已经实现类这样的:
EntityBase
请参阅 - 这两个属性可以有不同的实现,并在这一点上运行时无法知道自己是否实现统一(反射在运行时发生的现在,进行统一时,在编译时)。你收到的 public class EntityBase : IEntityBase, IObjectWithId<object>
private object objID1;
private int objID2;
object IEntityBase.ID
get return objID1;
set objID1 = value;
object IObjectWithId<object>.ID
get return objID2;
set objID2 = value;
是.NET框架的方式,以防止你有可能是未知/无意行为执行代码。
当提供为每个接口没有什么不同的实现(如你的情况),你唯一的实现是由在该签名的方法表两个条目调用,但还是有指向同一属性的两个项目。为了防止混乱的框架,你应该使用一个类型的继承层次不够高,所以它只有一个在它的方法表要反映成员条目。在我们的例子中,如果我们反映AmbiguousMatchException
属性时使用的接口类型,而不是,我们会解决我们的情况下,为每个接口只有一个在其方法表中所要求的签名条目。
然后,您可以使用
Id
要么
Console.WriteLine(
typeof(IEntityBase).GetProperty(
"Id", BindingFlags.Instance | BindingFlags.Public));
这取决于你想要检索的实现。在我最近的一个例子,其中每个接口都有不同的实现的情况下,你必须调用反射任何实现的,通过选择正确的接口的能力。在从你的问题的例子,你可以使用任何你想要的界面,都有一个实现。
当有一个一个接口方法两种实现我得到这个错误。
以上是关于为什么下面的代码抛出System.Reflection.AmbiguousMatchException谁能给我解释一下?的主要内容,如果未能解决你的问题,请参考以下文章
可能是什么原因,卡夫卡消费者承认,抛出InterruptedException?
php的异常处理,一个try代码块中抛出了多个异常,怎么全都捕获,并输出来?下面的代码为只输出一个异常?