简体   繁体   中英

Declare 2D array of different object types depending on if else (or switch) c#

I am working with matrix and have problem how correctly initialize different 2D array of objects, when their type depends on condition (if else). If I declare matrix and its type before if else, then i can't declare different types inside. If I declare it in if else, it doesn't exist outside of scope.

On Stack Overflow are already similar questions and I found out some approaches how to fix this problem.

  1. Put all methods (even not overloaded - doing exactly the same for both types) inside if else. -> This works but code is duplicate.
  2. Make common interface. -> Methods didn't work with ICell and I couldn't figure out retyping ICell[][] to CellA[][].
  3. Declare matrix as array of arrays of vars. -> Couldn't figure out how this works.

Is there any other option and whats best solution? Or is my approach completly wrong?

Thank you

PS Code is long and this is simplified version.

class CellA : IComparable {
    // 2 attributes
    //constructor 1 param
    public int CompareTo(object obj) {
        //code
    }
}

class CellB : CellA {  
    // 3 attributes  
    //constructor 2 params  
}

class Program {    
    static void Main(string[] args) {
        data[0] = "...";
        ...
        data[x] = "...";
        //user input own data or chooses data set
        ...
        bool mode = true/false; //user chooses computing mode
        if (mode) {
            CellA[][] matrix = InitializeMatrixA(data[indexOfSet]);
        } else {
            CellB[][] matrix = InitializeMatrixB(data[indexOfSet]);
        }
        DoSomethingOther(ref matrix);
        //several ref matrix manipulation methods
        Console.WriteLine(DoSomethingSame(matrix));
    }

    static CellA[][] InitializeMatrixA(string data) {
        //string processing, not important
        CellA[][] matrix = new CellA[9][];
        for (int i = 0; i < 9; i++) {
            matrix[i] = new Cell[9];
            for (int j = 0; j < 9; j++) {
                matrix[i][j] = new CellA(stringPart[i*9+j]);
            }
        }
        return matrix;
    }

    static CellB[][] InitializeMatrixB(string data) {
        //different string processing, not important
        CellB[][] matrix = new CellB[9][];
        for (int i = 0; i < 9; i++) {
            matrix[i] = new Cell[9];
            for (int j = 0; j < 9; j++) {
                matrix[i][j] = new CellA(stringPart[i*18+j*2], stringPart[i*18+j*2+1]);
            }
        }
        return matrix;
    }
    //same function for As and Bs
    static int DoSomethingSame(ref CellA[][] matrix) { //code }

    //many different overloaded methods all working with reference to "matrix", slightly different computing for As and Bs
    static void DoSomethingOther(ref CellA[][] matrix) { //code }
    static void DoSomethingOther(ref CellB[][] matrix) { // slightly different code}

Well, in my opinion, the second solution you posted would be the best solution, a common interface called ICell.

The way I would handle it is to create ICell like this: No need for the ref modifier, arrays are naturally passed by reference.

public interface ICell
{
    int DoSomethingSame(ICell[][] matrix);
    void DoSomethingOther(ICell[][] matrix);
}

and then I would create classes: CellA, CellB and make each one implement ICell interface by their own logic. Each constructor of the cell class defines the logic of InitializeMatrix by their own logic. So when you create an instance of the class it already initializes the matrix.

And then in the main:

static void Main(string[] args)
{
    data[0] = "...";
    ...
    data[x] = "...";
    //user input own data or chooses data set
    ...
    bool mode = true/false; //user chooses computing mode
    ICell[][] matrix = (mode)? new CellA(data[indexOfSet]): new CellB(data[indexOfSet])

    DoSomethingOther(ref matrix);
    //several ref matrix manipulation methods
    Console.WriteLine(DoSomethingSame(matrix));
}

If you need examples how to define CellA and CellB let me know and i will update.

EDIT: The full solution would be:

public class Matrix
{
    ICell[][] cell;
    public Matrix(bool mode, string data)
    {
        cell = (mode)? new CellA(data): new CellB(data);
    }
}

I would implement the doSomething methods inside the class.

and then in the main:

static void Main(string[] args)
{
    data[0] = "...";
    ...
    data[x] = "...";
    //user input own data or chooses data set
    ...
    bool mode = true/false; //user chooses computing mode
    Matrix matrix = new Matrix(mode, data[indexOfSet]);

    matrix.DoSomethingOther();
    //several ref matrix manipulation methods
    Console.WriteLine(matrix.DoSomethingSame);

}

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