c# – 为什么我的类型没有标记为相同?
关于这一点还有其他几个问题,但我觉得它们中没有一个真正提供了可靠的答案.
我最近在反思很多,我想检查实现某个接口的几个程序集中包含的类型. 所以我有一个名为BESCollector的类,它实现了ICollector public class BESCollector : ICollector { // ... } 在这里,我加载程序集,循环遍历所有类型,并查看该类型是否包含ICollector类型的接口… Assembly pluginAssembly = Assembly.ReflectionOnlyLoadFrom(pluginConfig.AssemblyLocation); IEnumerable<Type> types = pluginAssembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(ICollector))); ……没有结果:(.调试时我可以清楚地看到它包含这种类型.我打破了if循环 Assembly pluginAssembly = Assembly.ReflectionOnlyLoadFrom(pluginConfig.AssemblyLocation); IEnumerable<Type> types = pluginAssembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(ICollector))); foreach (Type type in pluginAssembly.GetTypes()) { Type[] interfaces = type.GetInterfaces(); if (interfaces.Contains(typeof(ICollector))) { Console.WriteLine(@"o/"); } } 这些结果直接来自调试器.在这里你可以看到接口包含一个Type,即ICollector: - interfaces {System.Type[1]} System.Type[] + [0] {Name = "ICollector" FullName = "SquidReports.DataCollector.Interface.ICollector"} System.Type {System.ReflectionOnlyType} Type I调用.GetInterfaces()on显然是BESCollector: + type {Name = "BESCollector" FullName = "SquidReports.DataCollector.Plugin.BES.BESCollector"} System.Type {System.ReflectionOnlyType} 但是相等语句interfaces.Contains(typeof(ICollector))永远不会计算为true. 只是这样你认为我不是在混合类型,当我在调试时鼠标悬停(typeof(ICollector))时,它清楚地显示了SquidReports.DataCollector.Interface.ICollector. 当然,这确实有效: Type[] interfaces = type.GetInterfaces(); if (interfaces.Any(t => t.Name == typeof(ICollector).Name)) { Console.WriteLine(@"o/"); } 但除了同名的类型之外,这并没有告诉我很多. 而且,为什么这个检查失败了? if (typeof(ICollector).Equals(typeof(ICollector))) { Console.WriteLine("EQUALIZED"); } 为什么我的第一次相等检查失败?更具体地说,类型相等如何在C#5.0中起作用?对于’Type’类型,.Equals()没有特定的实现吗? 编辑: 如果在同一个程序集中定义了接口和类,则在下面的I Quality Catalyst的请求下,如果等式将评估为true,则快速进行测试.这个工作: class Program { public interface ITest { } public class Test : ITest { public int ID { get; set; } } static void Main(string[] args) { Type[] interfaces = (typeof(Test)).GetInterfaces(); if (interfaces.Any(t => t == typeof(ITest))) { Console.WriteLine(@"o/"); } } } EDIT2:这是ICollector的实现 public interface ICollector { IDbRelay DbRelay { get; set; } ILogManager LogManager { get; set; } void Init(ILogManager logManager,IDbRelay dbRelay); void Execute(); } 但是,我相信我可能错过了一个重要的细节.我在这里使用三个程序集: >我正在进行相等性检查的’Main'(SquidReports.DataCollector)程序集 可能非常重要的是要注意从InterfaceOnlyAssemblyResolve事件加载’Interface'(SquidReports.DataCollector.Interface),如下所示,因为ReflectionOnlyLoadFrom()不会自动解析依赖关系: public Assembly ReflectionOnlyAssemblyResolve(object sender,ResolveEventArgs args) { // This event is used to resolve dependency problems. We need to return the requested assembly in this method. // We should probably look in two locations: // 1. The SquidReports.DataCollector folder // 2. The Corresponding folder in SquidReports.DataCollectorPlugins // Let's first turn the 'full' assembly name into something more compact AssemblyName assemblyName = new AssemblyName(args.Name); this.Logger.LogMessage(LogLevel.Debug,String.Format("Attempting to resolve Assembly {0} to load {0}",assemblyName.Name,args.RequestingAssembly.GetName().Name)); // Let's also get the location where the requesting assembly is located DirectoryInfo pluginDirectory = Directory.GetParent(args.RequestingAssembly.Location); string assemblyFileName = String.Format("{0}.dll",assemblyName.Name); if (File.Exists(assemblyFileName)) { // It's in the main bin folder,let's try to load from here return Assembly.ReflectionOnlyLoadFrom(assemblyFileName); } else if (File.Exists(Path.Combine(pluginDirectory.FullName,assemblyFileName))) { // It's in the plugin folder,let's load from there return Assembly.ReflectionOnlyLoadFrom(Path.Combine(pluginDirectory.FullName,assemblyFileName)); } return null; } 编辑3:根据Joe的建议,我使用以下方法再次调试了应用程序: if (type.Name == "BESCollector") { Type[] interfaces = type.GetInterfaces(); Type interface1 = interfaces[0]; Type interface2 = typeof(ICollector); Console.WriteLine(""); } 我复制了interface1和interface2的完整属性,然后将它们放在文件diff中. 我认为结果可能解决了我的问题: interface1描述如下: interface1 {Name = "ICollector" FullName = "SquidReports.DataCollector.Interface.ICollector"} System.Type {System.ReflectionOnlyType} 而interface2的描述如下: interface2 {Name = "ICollector" FullName = "SquidReports.DataCollector.Interface.ICollector"} System.Type {System.RuntimeType} 所以我正确地假设问题是由于{System.RuntimeType}!= {System.ReflectionOnlyType}引起的,而Assembly.ReflectionOnlyLoadFrom()应该归咎于此吗? 解决方法
感谢Joe Enzminger,我偶然发现了答案:
看起来,因为我使用的是Assembly.ReflectionOnlyLoadFrom(),我从Assembly加载的Type实际上是System.ReflectionOnlyType而不是System.RuntimeType. 基本上,有一个简单的,一个非常酷的解决方案: >停止使用ReflectionOnlyLoadFrom()并切换到LoadFrom().这解决了你所有的问题.当然,除非您使用ReflectionOnlyLoadFrom是有充分理由的. if((typeof(MyReflectionType)).GUID ==(typeof(MyType)).GUID) 那应该解决你的问题:) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |