Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何创建类字典,以便使用键确定要初始化的新类?_C#_Dictionary_Abstract Class - Fatal编程技术网

C# 如何创建类字典,以便使用键确定要初始化的新类?

C# 如何创建类字典,以便使用键确定要初始化的新类?,c#,dictionary,abstract-class,C#,Dictionary,Abstract Class,根据这个问题,我如何在C#中创建一个字典,其中键是一个整数,但值是我可以通过使用字典中的值来调用构造函数的类?每个类都是从一个抽象类派生的,它们采用相同的参数,因此我觉得应该能够将对新类对象的引用结果存储在抽象类类型的变量中 也就是说,字典的值集通常由对象的引用填充,而不是类型本身。举个简单的例子,下面是我要做的: abstract class BaseObject { int someInt; } class ObjectA : BaseObject { ObjectA

根据这个问题,我如何在C#中创建一个字典,其中键是一个整数,但值是我可以通过使用字典中的值来调用构造函数的类?每个类都是从一个抽象类派生的,它们采用相同的参数,因此我觉得应该能够将对新类对象的引用结果存储在抽象类类型的变量中

也就是说,字典的值集通常由对象的引用填充,而不是类型本身。举个简单的例子,下面是我要做的:

abstract class BaseObject {

     int someInt;
}

class ObjectA : BaseObject {

    ObjectA (int number) {
        someInt = number;
    }
} 

class ObjectB : BaseObject {

    ObjectB (int number) {
        someInt = number;
    }
}
我希望能够做到以下几点:

Dictionary<int, ???????> objectTypes = new Dictionary<int, ???????>();

objectTypes.Add(0, ObjectA);
objectTypes.Add(1, ObjectB);
语法可能有很大不同,但我希望我至少了解了我要完成的任务。

Dictionary objectTypes=new Dictionary();
Dictionary<int, Type> objectTypes = new Dictionary<int, Type>();

objectTypes.Add(0, typeof(ObjectA));
objectTypes.Add(1, typeof(ObjectB));

var newObjectA = (BaseObject)Activator.CreateInstance(objectTypes[0], new object[] {1000});
添加(0,typeof(ObjectA)); 添加(1,typeof(ObjectB)); var newObjectA=(BaseObject)Activator.CreateInstance(objectTypes[0],新对象[]{1000});


这只是另一种实现方法,但Phuong的答案是在编译时采用一种更干净、可定制的方法


关键区别在于您是否希望在运行时或编译时实现动态。如果都是编译时,我建议使用
Func
方法。如果您的类型在编译时是未知的,那么您将希望使用这种方式,因为有许多方法可以使用
Activator.CreateInstance

动态实例化类。您正在寻找类似的方法吗

var objectTypes = new Dictionary<int, Func<int, BaseObject>>();
objectTypes[0] = input => new ObjectA(input);
objectTypes[1] = input => new ObjectB(input);

objectTypes[0](1000);
objectTypes[1](2000);
var objectTypes=newdictionary();
objectTypes[0]=input=>newobjecta(input);
objectTypes[1]=input=>newobjectb(input);
objectTypes[0](1000);
objectTypes[1](2000年);

在这里,我不存储对象,而是存储一个Func来生成每个具体对象

听起来像是在尝试实现自己的依赖注入框架,或类似的框架。至少一个服务容器。(这不是一件坏事,尽管你可能希望看看像Ninject这样的现有产品)哇,我不得不查几个术语。本质上,我的目标是能够生成类的实例,这些类可以通过基类订阅更新机制。但是,我从基类派生了大量不同的类,每个类的构造函数都非常不同。我不认为这实际上是依赖注入,因为我让我的每个类都获取它所需要的,这样我就可以使用相同的构造函数,我只想能够在运行时创建和使用它们的实例,这样它们生成的对象类型就可以受输入的影响。啊,这是一个发布者-订阅者机制(让您继续查找术语):-P)您的权利不是依赖注入或服务容器。也就是说,使用依赖注入框架可以大大简化您的生活。我遇到的唯一问题(因为我最初就是这样做的)我在一个权威服务器框架上运行它,将不同的权威信息封装到适当的管理器中更容易,这样我就可以在客户端和服务器之间同步管理器,然后让运行时生成的类在需要时获取它们所需的。这样,我的网络只包括管理器和命令RPC的同步没有任何实际的信息参数。总而言之,你能想出更好的方法将每种类型的派生类的运行时生成与基元关联起来吗?这实际上正是我要问的,但Phuong的方法也非常有趣。接下来对函数进行一些研究,以确定使用Activator还是Func是最有效的方法。@Kyton
Activator.CreateInstance
可能会更慢。
Func
只是一个委托,最终会被编译成它自己的方法。我说的更慢,但这是相对的(小毫秒)因为您可能永远不会注意到这一点,这取决于您使用它的位置。无论哪种方法,都很容易通过循环两个10万次进行测试。@Kyton这两种方法的主要区别在于,您是否需要在运行时从程序集动态加载类型并初始化这些类型。
Func
,您需要在编译时知道。啊!这就清除了谢谢你的解释。因此,如果我要使用某种在编译代码时无法访问的外部编译库,我必须使用激活器。但是如果所有类及其构造函数都是在我编译代码的范围内定义的,那么使用Func可以很好地(更快地)工作@Kyton正确。关于您上面的一条评论,听起来好像您在运行时做一些动态的事情,这是从配置文件中驱动出来的(假设)。
CreateInstance
的一个重载包含一个
string
。它将完全从类的名称空间和名称中实例化类(名称空间可能是可选的…我忘记了)。编辑:1st param是程序集名称。这非常有趣,我没有想到它可以替代存储类型。你知道这是否比存储类型和使用Activator快吗?据我所知,这应该比Activator快,因为它不使用反射
var objectTypes = new Dictionary<int, Func<int, BaseObject>>();
objectTypes[0] = input => new ObjectA(input);
objectTypes[1] = input => new ObjectB(input);

objectTypes[0](1000);
objectTypes[1](2000);