为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
翻翻过去那场雪 2022-06-19 16:48:03
我正在尝试在 C# 中创建一个工厂类,该类返回属于或扩展某个基本类型的对象。每次调用getInstance()工厂时我都需要实例化这种类型的新实例,所以我真的只想接受并存储类型本身。在 Java 中,我使用Class<? extends Base>来保存要创建的类,然后调用getInstance()它。我了解如何使用 C# 中的 Activator 类从 a 创建新对象,System.Type但我不确定的部分是对类类型的约束。我希望能够只接受属于或扩展基类的类型。我意识到我可以更改工厂的 setter 以接受基本类型的实际对象,然后从中检索类型,但我真的不想实例化整个对象只是为了检索 Type 变量。下面是一个小示例 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.");   }}
查看完整描述

2 回答

?
慕的地6264312

TA贡献1817条经验 获得超6个赞

我看不到如何在编译时强制执行此操作,但如果您对运行时检查没问题,您可以这样做:


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);

    }

}


查看完整回答
反对 回复 2022-06-19
?
郎朗坤

TA贡献1921条经验 获得超9个赞

您可以使“GetInstance”方法动态化,以便在设置类时也设置方法。这样你就可以在运行时依赖泛型来获得正确的类型。它可能看起来像这样:


public class Factory

{

    private static Func<Base> _getInstance;


    //option if you want to pass in an instantiated value

    public static void SetClass<T>(T newType) where T : Base, new()

    {

        _getInstance = () => new T();

    }


    //option if you just want to give it a type

    public static void SetClass<T>() where T : Base, new()

    {

        _getInstance = () => new T();

    }


    public static Base GetInstance()

    {

        return _getInstance();

    }


    //you could just make GetInstance Generic as well, so you don't have to set the class first

    public static Base GetInstance<T>() where T : Base, new()

    {

        return new T();

    }

}


查看完整回答
反对 回复 2022-06-19
  • 2 回答
  • 0 关注
  • 167 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号