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)
}
  • 1
    Are these custom types? Can you share the actual inheritance structure? – Adrian Larson Jun 1 '17 at 21:17
  • Ive added the inheritence structure now. – discodowney Jun 2 '17 at 14:00
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));
  • You can't type-cast it anyways, because collection casting is broken. – sfdcfox Jun 1 '17 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 '17 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 '17 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 '17 at 21:39
  • Object[] a = new String[0]; a.add(5); – sfdcfox Jun 1 '17 at 21:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.