4

Its been a long time since I casted an array and cant remember if it can be done the way Im hoping.

I have an array of type Row (Row[] rows) that is returned from a method. The method I need to pass it into takes DataRow[] dataRows. DataRows is a child of Row.

I am trying to cast like (DataRow[]) rows when I pass in the param, but its no working.

CODE:

Row[] rows = getRows();
savetable(id, (DataRow[]) rows);

Obviously its not working for me, but is there a way to cast arrays in some similar manner?

The inheritence structure is basic:

class Row()
{
    (variables/methods)
}

class DataRow extends Row()
{
    (variables/methods)
}
2
  • 1
    Are these custom types? Can you share the actual inheritance structure?
    – Adrian Larson
    Jun 1, 2017 at 21:17
  • Ive added the inheritence structure now. Jun 2, 2017 at 14:00

2 Answers 2

2

Sadly, this doesn't work, because collection inheritance is broken. As I outlined in my previous answer, the following code demonstrates the inheritance problem:

class c1 {

}
class c2 extends c1 {

}
// All C2s are C1s, but this won't compile
Map<String, c2> m1 = new Map<String, c1>();
// Not all C2s are C1s, but this compiles and can crash.
Map<String, c1> m2 = new Map<String, c2>();

Instead, you have to create a list, and copy the elements individually:

DataRows[] datarows = new DataRows[0];
for(Row row: getRows()) {
    datarows.add(row);
}
savetable(id, datarows);

I still plan on bringing this up with the Apex PM when I get a moment. Maybe someday this will work as intended.

-1

You can only use type casting when you are using related objects (virtual classes/inheritance)

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_casting.htm

In general, all type information is available at runtime. This means that Apex enables casting, that is, a data type of one class can be assigned to a data type of another class, but only if one class is a child of the other class. Use casting when you want to convert an object from one data type to another.

Basically, if dataRow is not a child/parent of Row, you can't type cast it.

You'll have to manually define this behavior.

public static DataRow[] convertFromRows(Row[] rows) {
    DataRow[] result = new DataRow[];

    for (Row r : rows) {
        DataRow tmp = new DataRow();
        // Work your magic here
        result.add(tmp);
    }

    return result;
}

Finally:

saveTable(id, DataRow.convertFromRows(rows));
6
  • You can't type-cast it anyways, because collection casting is broken.
    – sfdcfox
    Jun 1, 2017 at 21:28
  • Yea, I read your answer. I just did some testing though and it seems its only broken in 1 direction. I can typecast a child to the parent class but I cannot typecast a parent to a child class with collections.
    – gNerb
    Jun 1, 2017 at 21:36
  • It's broken both directions, because it allows you to type-cast a smaller collection into a larger collection, thus resulting in runtime errors.
    – sfdcfox
    Jun 1, 2017 at 21:37
  • I'm not sure I understand then, I was able to get it to work without runtime errors using a few simple classes.
    – gNerb
    Jun 1, 2017 at 21:39
  • Object[] a = new String[0]; a.add(5);
    – sfdcfox
    Jun 1, 2017 at 21:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .