C# 什么是Type.GUID以及它与Type.Equals()的关系如何?
我在尝试将C# 什么是Type.GUID以及它与Type.Equals()的关系如何?,c#,generics,types,runtime,equals,C#,Generics,Types,Runtime,Equals,我在尝试将System.RuntimeType的实例与泛型类型TOut进行比较时遇到了一些有趣的行为: Type runtimeT = methodInfo.ReturnType; // get RuntimeType using reflection Type genericT = typeof(TOut); // This condition fails because runtimeT doesn't // seem to include an assembly qualified n
System.RuntimeType
的实例与泛型类型TOut
进行比较时遇到了一些有趣的行为:
Type runtimeT = methodInfo.ReturnType; // get RuntimeType using reflection
Type genericT = typeof(TOut);
// This condition fails because runtimeT doesn't
// seem to include an assembly qualified name
if(runtimeT.Equals(genericT)) { ... }
以下是我的证据:
免责声明:我不知道CLR/type系统上下文中的GUID是什么,当然首字母缩写表示全局唯一标识符除外。也许这个名字误导了我
假设:我在这里假设类型
GUID唯一标识完全限定的类型,包括屏幕截图中factoryInfo.ReturnType
中缺少的类型(值null
)
我的假设错了吗
- 是:类型GUID真正代表什么?它是如何使用的
- 否:为什么不通过比较GUID来实现
但简而言之,您可以将GUID视为表示ID的随机数字,长度为16字节,并且不会生成两次。没有将
Type.GUID
用作Equals
的比较的一个原因是它是用户可控制的项。例如,我可以通过执行以下操作来指定我的接口的GUID
[Guid("2bfd006d-94b9-43af-843f-5b32f7567086")]
interface IFoo { ... }
这是为COM互操作生成接口所必需的。如果Equals
依赖于类型所特有的GUID
,那么给定的开发人员可能会给他们的类型提供与字符串、int
等相同的GUID
,从而对系统造成严重破坏…您不应该真正依赖system.type的GUID属性进行类型比较。特别是在进程间通信(WCF、远程处理)中,Guid可能不同(除非像JaredPar的示例中那样手动指定)
在内部,Type.Equals使用RuntimeTypeHandle进行相等比较
我不知道为什么你上面的平等比较失败了。不应该。在下面非常简单的示例中,equal返回true
static void Main(string[] args)
{
Test<object>();
}
static object Test<T>()
{
var currentMethod = ((MethodInfo) MethodBase.GetCurrentMethod());
var oType = currentMethod.ReturnType;
var genericType = typeof (T);
var equal = oType.Equals(genericType); // result is true.
return null;
}
static void Main(字符串[]args)
{
Test();
}
静态对象测试()
{
var currentMethod=((MethodInfo)MethodBase.GetCurrentMethod());
var oType=currentMethod.ReturnType;
变量genericType=类型(T);
var equal=oType.Equals(genericType);//结果为true。
返回null;
}
我在黑暗中随机猜测,您使用的是启用代理创建的实体框架?在这种情况下,IEntitySet的泛型参数T是实体框架为您创建的动态生成的类型。。。如果是这种情况,您应该通过单独比较泛型参数来获得所需的结果:要在Jared(完全正确)的答案上展开一点: 在COM世界中,每个接口都由一个全局唯一标识符标识。COM中没有“更改”接口这样的事情;接口要求永远相同。相反,您可以创建一个新接口并为其提供一个新的GUID。任何两个不同的接口都需要有不同的guid。接口相等在COM中定义为GUID相等 在.NET世界中,类型平等更为复杂。一方面,类型与特定程序集相关联。但不仅仅如此!如果加载同一程序集两次(一次按其程序集名称加载,一次按其磁盘位置加载),并要求两个程序集使用“相同”类型,则会得到两个不同的类型对象,即使它们显然具有相同的GUID,它们也不会进行相同的比较 显然,这是一个主要的出发点。NET和COM在这方面极不兼容。当必须进行互操作时会发生什么情况?不知何故,COM和.NET在同一过程中,就如何比较类型以获得相等性达成了一些规则。(因为.NET正在调用COM代码,反之亦然。) 因此,您可以在.NET中执行以下操作:“此类型与此GUID关联”。当COM规则应用时,COM代码将通过比较GUID来比较两种类型的相等性,因为这就是COM世界中相等性的含义 在.NET中,使用.NET的常用规则比较类型是否相等 然后,这在一个常见场景中提出了一个重要的潜在问题。假设您编写了一个.NET程序,该程序可以与大型复杂的COM库进行互操作。举一个完全非随机的例子,假设您已经为Word编写了一个托管扩展,它有一个绝对巨大的COM“表面积”。该表面积通过一个主互操作程序集暴露给.NET世界,该程序集包含“虚拟”类型,这些类型与COM世界中的corersponding接口具有所有相同的GUID。然后可以编写.NET代码,通过“虚拟”对象与COM层对话,这些对象看起来像是具有适当接口类型的COM类对象,而.NET代码看起来像是具有适当.NET类型的对象 这样就可以了。然后,您将.NET库发送给客户,您会发现Word不会自动将PIA发送给客户。相反,您需要发送他们的PIA。这是巨大的 C#4的“无PIA”特征由此诞生。在C#4中,您可以生成一个单词扩展名,该扩展名只生成单词PIA实际使用部分的内部副本。它通常要小得多。然后,您可以在不使用r的情况下重新分发扩展库