简体   繁体   中英

How to initialize objects of array which has been created dynamically?

class bishop:unit {}
class knight:unit {}
class peasant:unit {}

void Battle(unit first, unit second, byte firstAmount, byte secondAmount)
{
  System.Array sideA = System.Array.CreateInstance(first.GetType(),firstAmount);
  for(int i=0; i< firstAmount; i++) 
  { 
   sideA[i] = ???
  }
}

In my last question I had problems with creating dynamic arrays and here is my next step problem! :D
Passable types to this method bishop, knight and etc
Actually I don't understand how to initialize objects now. I can't type just sideA[i] = new first.GetType()(constructor parameters) and understand why, but I don't understand how to work around this

This is really, really bad design.

I assume, that your method Battle could be an instance method of a class Game , which you didn't provide to us.

Then I strongly recommend, that the Battle method should NOT create instances of objects it works with. It should only take them and do a battle action (compute lives, etc.).

So, create these objects elsewhere and then just post them to the method.

class Game
{
    List<Bishop> bishops = new List<Bishop>() { new Bishop(..), ... };
    List<Knight> knights = new List<Knight>() { new Knight(..), ... };

    void Battle(List<Unit> first, List<Unit> second)
    {
        foreach(var f in first)
        {
            // get random unit from the second collection and attack him
            f.Attack(GetRandomKnight(second)); 
        }
    }

    public void StartBattle()
    {
        Battle(bishop, knights);
    }
}

Also make sure that you use correct C# naming. A name of a class should start with a capital letter.

class Unit
{
    public virtual void Attack(Unit enemy)
    {
        // default attack
        Kick(enemy);
    }

    protected Kick(Unit enemy) { ... }
}

class Bishop : Unit { }

Ondrej has a good answer. Just to help you with arrays, you should never use reflection unless with a good reason. I see no reason why you should be doing it here. You can use the typical new keyword to instantiate an array.

void Battle(unit first, unit second, byte firstAmount, byte secondAmount)
{
  var sideA = new unit[firstAmount];
  for(int i=0; i< sideA.Length; i++) 
  { 
    sideA[i] = ???
  }
}

If the instantiated array should really be of run time type of first , then you can rely on generics.

void Battle<T1, T2>(T1 first, T2 second, byte firstAmount, byte secondAmount) 
                   where T1 : unit where T2 : unit
{
  var sideA = new T1[firstAmount];
  for(int i=0; i< sideA.Length; i++) 
  { 
    sideA[i] = ???
  }
}

The totally dynamic way to settle things will be SetValue and GetValue :

void Battle(unit first, unit second, byte firstAmount, byte secondAmount)
{
  var sideA = Array.CreateInstance(first.GetType(),firstAmount);
  for(int i=0; i< firstAmount; i++) 
  { 
   sideA.SetValue(???, i);
   sideA.GetValue(i); //to get the value back.
  }
}

Basically you dont get indexer syntax for System.Array .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM