java - C# 中的参数化 System.Type 变量

标签 java c# reflection polymorphism factory-pattern

我正在尝试在 C# 中创建一个工厂类,它返回属于或扩展特定基类型的对象。每次调用 getInstance() 时,我都需要实例化这种类型的新实例。在工厂上,所以我真的只想接受并存储类型本身。在Java中我使用了Class<? extends Base>保存要创建的类,然后调用 getInstance()就在上面。

我了解如何使用 C# 中的 Activator 类从 System.Type 创建新对象但我不确定的部分是对类类型的约束。我希望能够只接受基类或扩展基类的类型。我意识到我可以更改工厂上的 setter 以接受基本类型的实际对象,然后从中检索类型,但我真的不想实例化整个对象只是为了检索类型变量。

下面是一个 Java 程序示例,只是为了演示我需要什么,以防我的问题不清楚。有没有办法在 C# 中做到这一点?

class Program {
   public static void main(String[] args) throws InstantiationException, IllegalAccessException {
         Factory.setClass(Base.class);
         Base b = Factory.getInstance();
         b.Print();

         Factory.setClass(Child.class);
         b = Factory.getInstance();
         b.Print();
      }
}

class Factory {
   private static Class<? extends Base> type;

   // What I want to do in C#.
   public static void setClass(Class<? extends Base> newType) {
      type = newType;
   }

   // What I don't want to have to do in C#.
   public static void setClassFromObject(Base newTypeObject) {
      type = newTypeObject.getClass();
   }

   public static Base getInstance() throws InstantiationException, IllegalAccessException {
      return type.newInstance();
   }
}

class Base {
   public void Print() {
      System.out.println("Hello from base.");
   }
}

class Child extends Base {
   @Override
   public void Print() {
      System.out.println("Hello from child.");
   }
}

最佳答案

我不知道如何在编译时强制执行此操作,但如果您可以进行运行时检查,则可以这样做:

class Factory 
{
    private static Type _type;

    public static void SetClass(Type t) 
    {
        if (!(typeof(Base)).IsAssignableFrom(t))
        {
            throw new ArgumentException("type does not extend Base", nameof(t));
        }

        _type = t;
    }

    public static Base GetInstance() 
    {
        return (Base)Activator.CreateInstance(_type);
    }
}

关于java - C# 中的参数化 System.Type 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53857789/

相关文章:

java - Servlet session cookie 篡改和安全

java - 适用于 Android、iOS 和黑莓的 Codenameone 应用内计费

c# - 在 Entity Framework Core 中一起实现单一命名约定和数据注释的正确方法

c# - 泛型和父/子架构

c# - 传递方法并调用内部函数

java - 维基文本到 XML

java - "Error: Main method not found in class MyClass, please define the main method as..."

c# - Xamarin Android 应用程序

使用 TypeTag 对泛型类型进行 Scala 模式匹配会生成警告,而 ClassTag 不会?

c# - 当方法信息仅在运行时已知时优化 MethodInfo.Invoke