【问题标题】:Instantiate a random class on program start在程序启动时实例化一个随机类
【发布时间】:2013-08-28 13:36:14
【问题描述】:

目前我只是在玩继承和其他一些概念。

我创建了一个控制台应用程序,其中包含以下类:

Public abstract Organism

Public abstract Animal : Organism

Public Bird : Animal
Public Mammal : Animal
Public Reptile : Animal
Public Fish : Animal
Public Amphibian : Animal

Public Human : Organism

当控制台应用程序启动时,我想从 Human、Fish、Mammal、Reptile、Bird 或 Amphibian 类创建一个新对象。要实例化这些类中的哪一个是随机选择的。

一旦随机选择了一个类,我就使用 console.writeline 来询问用户关键问题,以将值分配给给定的对象属性。

如何从这些类之一创建随机对象?

【问题讨论】:

  • 你的意思是通过系统从上面提到的类中随机创建一个对象..??
  • 你试过什么?你知道Random Class吗?

标签: c# oop inheritance console-application


【解决方案1】:

如果您需要从列表中选择类型,您可以:

Type[] animals = new Type[]{ typeof(Bird), typeof(Mammal), typeof(Reptile), typeof(Fish), typeof(Amphibian) };
Animal animal = animals[new Random().Next(animals.Length)].GetConstructor(new Type[]{}).Invoke(new object[]{}) as Animal;

但是,如果您重视代码的简单性/可读性(并且您应该这样做),如果可能,以下内容会更好:

Animal animal = null;
switch (new Random().Next(5))
{
    case 0:
        animal = new Bird();
        break;
    case 1:
        animal = new Mammal();
...
}

编辑:我忘记了 Activator.CreateInstance (比我建议的代码更简单),但是如果没有很多类,使用更基本的代码会更易读,并且允许更大的灵活性(你不需要每种类型有一个偶数概率)。

【讨论】:

    【解决方案2】:

    不使用反射,您可以通过类实例列表来实现它:

         var classlist = new List<Organism>();  
        classlist.Add(new Bird());
        classlist.Add(new Mammal());    
        classlist.Add(new Reptile());
        classlist.Add(new Fish());  
        classlist.Add(new Amphibian());
        classlist.Add(new Human());
    
        var r = new Random();
    
        var instance = classlist[r.Next(0,5)];
    

    【讨论】:

    • 但是现在您已经有了实例。如果您只想在需要时创建实例,而不创建所有其他实例,该怎么办?
    【解决方案3】:
    // use the DLL of the project which is currently running
    var runningAssembly = Assembly.GetExecutingAssemby();
    
    // all classes have a "Type" which exposes information about the class
    var organismType = typeof(Organism);
    
    // to keep track of all organism classes that we've found.
    var allOrganismTypes = new List<Type>();
    
    // go through all types in our project and locate those who inherit our 
    // organism class
    foreach (var type in runningAssembly.GetTypes())
    {
        if (organismType.IsAssignableFrom(type))
            allOrganismTypes.Add(type);
    }
    
    // Find a random index here (do it yourself)
    var theRandomIndex = 10;
    
    
    var selectedType = allOrganismTypes[theRandomIndex];
    
    // activator is a class in .NET which can create new objects 
    // with the help of a type
    var selected = (Organism)Activator.CreateInstance(selectedType);
    

    代码中有一些“错误”,您必须自己纠正。

    【讨论】:

    • 感谢 jgauffin。我使用了你的,因为它与我的代码的耦合度最低,让我可以选择以最少的修改添加更多的物种。
    • 每个人都喜欢 LINQ... 而不是 List 声明和 foreach:List&lt;Type&gt; allOrganismTypes = runningAssembly.GetTypes().Where(t =&gt; organismType.IsAssignableFrom(t)).ToList();
    • 嗯,您还必须过滤掉界面本身。 List&lt;Type&gt; allOrganismTypes = runningAssembly.GetTypes().Where(t =&gt; !t.IsInterface() &amp;&amp; organismType.IsAssignableFrom(t)).ToList();
    猜你喜欢
    • 1970-01-01
    • 2013-12-11
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    相关资源
    最近更新 更多