C#验证泛型类型使用类型参数扩展泛型抽象类 [英] C# Validate that generic type extends generic abstract class with type parameters

查看:85
本文介绍了C#验证泛型类型使用类型参数扩展泛型抽象类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我被困住了,正在寻找一些澄清.

I've am stuck and I'm looking for some clarification.

我在思考问题上遇到了问题,我有一个WPF应用程序,并且已经实现了此处记录的插件系统:

I'm having an issue with reflection, I have a WPF app and I've implemented a plugin system as documented here: https://docs.microsoft.com/en-us/dotnet/core/tutorials/creating-app-with-plugin-support

但是,我已经对其进行了一些修改和扩展,其中我的插件直接扩展了Abstract类而不是Interface,因为我在构造函数中有一些东西.

However, I've modified and extended this a bit where my plugins extend an Abstract class instead of an Interface directly because I have some stuff in the constructor.

在我的项目中,总体结构如下:

On my project, the overall structure is the following:

    public abstract class AbstractPlugin<TSignatureFile, TLoadedFile> : 
        IPlugin<TSignatureFile, TLoadedFile> 
        where TSignatureFile : IFileSignature
        where TLoadedFile : LoadedFile { }

    public interface IPlugin<out TSignatureFile, TLoadedFile> 
        where TSignatureFile : IFileSignature
        where TLoadedFile : LoadedFile { }

    public class MyPlugin : AbstractPlugin<MyPluginFileSignature, MyPluginFile { }

    public class MyPluginFileSignature : IFileSignature { }

    public class MyPluginFile : LoadedFile { }

我有一个叫"PluginManager"的类,加载实例化插件.此加载和实例化机制主要基于以下内容: https://github.com/dotnet/samples/tree/master/core/extensions/AppWithPlugin/AppWithPlugin

I have then a class I call the "PluginManager" which loads instantiates the plugins. This load and instantiate mechanic is mostly based on this: https://github.com/dotnet/samples/tree/master/core/extensions/AppWithPlugin/AppWithPlugin

我遇到的问题是"CreatePlugin"方法将列出在程序集中找到的所有类型,直到找到匹配项并实例化该匹配项为止.

The problem I'm having is that the "CreatePlugin" method will list all types found in the assembly until it finds a match and instantiate that, which is not working.

代码是这样的:

foreach (Type type in assembly.GetTypes())
{
   if (type.IsClass && !type.IsAbstract && type.IsInheritedFrom(typeof(AbstractPlugin<IFileSignature, LoadedFile>)))
   {
      AbstractPlugin<IFileSignature, LoadedFile> result = Activator.CreateInstance(type, notificationCallBack) as AbstractPlugin<IFileSignature, LoadedFile>;

      if (result != null)
      {
          count++;
          yield return result;
      }
   }
}

有人从StackOverflow的一篇帖子中建议在Type上创建一个扩展方法,即"IsInheritedFrom".是.

From one of the StackOverflow posts someone recommended creating a extension method on Type which is what that "IsInheritedFrom" is.

这是它的当前状态,我想让它工作起来很混乱.

Here is the current status of it / mess of me trying to get it to work.

public static bool IsInheritedFrom(this Type type, Type lookup)
{
    var baseType = type.BaseType;
    if (baseType == null)
        return false;

    var isAbstract = lookup.IsAbstract;
    var areEqual = baseType == lookup;
    var isSubClass = type.IsSubclassOf(lookup);

    if (baseType.IsGenericType
            && baseType.GetGenericTypeDefinition() == lookup)
        return true;

    return baseType.IsInheritedFrom(lookup);
}

由此,areEqual和isSubClass始终返回false.有什么想法吗?

From this, areEqual and isSubClass always returns false. Any ideas?

谢谢.

推荐答案

好吧,我对IsInheritedFrom方法进行了以下更改,设法做到这一点:

Ok, I managed to get this working with the following changes to the IsInheritedFrom method:

public static bool IsInheritedFrom(this Type type, Type lookup)
{
    var baseType = type.BaseType;
    if (baseType == null)
        return false;

    var lookup_typeDefinition = lookup.IsGenericType ? lookup.GetGenericTypeDefinition() : null;
    var baseType_typeDefinition = baseType.IsGenericType ? baseType.GetGenericTypeDefinition() : null;

    if (lookup_typeDefinitionCheck == baseType_typeDefinitionCheck) return true;

    return baseType.IsInheritedFrom(lookup);
}

我非常确定这可以在这种特定情况下使用,并且不会在其他情况下使用,特别是因为我依赖于基本类型并且查找是通用的,否则它将返回false.但是,由于我不打算将此用于任何其他目的,所以可以.

I'm pretty sure that this works on this specific scenario and won't work on others, specially because I'm relying on the base type and lookup being generic otherwise it will return false. However, since I don't plan to use this for any other purpose, it will do.

现在,我在转换实例化对象时遇到了另一个问题,但是对此我将提出另一个问题.

Now I've ran into another problem with casting the instantiated object, but I will raise another question for that.

谢谢.

这篇关于C#验证泛型类型使用类型参数扩展泛型抽象类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆