1

It seems like no. I have a utility method

   public static Map<String, SObject> getMapOfStringToSObject(List<SObject> lstSObjs, String strKeyFieldName)
   {
       Map<String, SObject> mapStringToSObject = new Map<String, SObject>();
       for (SObject so : lstSObjs)
           mapStringToSObject.put((String)so.get(strKeyFieldName), so);

       return mapStringToSObject;
   }

But when I try to use it (with casting) I get System.TypeException: Invalid conversion from runtime type Map<String, SObject> to Map<String, MyObject> ()

Client code is

Map<String, MyObject> res = (Map<String, MyObject>)UtilsClass.getMapOfStringToSObject(someList, 'someStringField');

Sure I could not cast and loop over the results. But the whole point of this is to abstract away the looping and not have to write it over and over. I have similar methods (where I can cast successfully) that return a variety of types including among others

Map<String, List<SObject>>
Map<Id, List<SObject>>
3
  • Don't think you can do this. MyObject is not an sObject
    – alesremta
    Commented Jun 22, 2020 at 19:56
  • 1
    is MyObject in your example code an apex class type?
    – Mark Pond
    Commented Jun 22, 2020 at 19:56
  • This is a topic that has been touched on before I explain at a high level how up-casting and down-casting work salesforce.stackexchange.com/a/297775/54609. Furthermore I suggest you look at this post as well that goes into finer detail about problems with type casting in apex salesforce.stackexchange.com/a/125891/54609
    – Cowboy
    Commented Jun 23, 2020 at 14:16

3 Answers 3

0

Provided that MyObject is an SObject (which it should be, given your code so far), the best I've been able to come up with is something like

Map<String, MyObject> res = new Map<String, MyObject>(UtilsClass.getMapOfStringToSObject(someList, 'someStringField').values());

Which makes use of the map constructor which takes a list.

Unfortunately, that forces you to use the record Id as the map key. In limited situations, you could use the field aliasing trick (in a query that uses GROUP BY) to make some other field be the "Id", but I have a feeling that's not going to work for your utility class.

I don't think it's practical to avoid a loop here.

0

I found a way to do this that's only slightly clunky. If I tell my method the return type I want, I can instantiated it with newInstance()

public static Map<String, SObject> getMapOfStringToSObject(List<SObject> lstSObjs, String strKeyFieldName, Type mapType)
{
    Map<String, SObject> mapStringToSObject = (Map<String, SObject>) mapType.newInstance();
    for (SObject so : lstSObjs)
        mapStringToSObject.put((String)so.get(strKeyFieldName), so);

    return mapStringToSObject;
}

And client code:

Map<String, Account> res = (Map<String, Account>)UtilsCollection.getMapOfStringToSObject(accounts, 'Name', Map<String, Account>.class);
0

You can use:

Map<String, SObject> mapStringToSObject = new Map<String, SObject>();

   Map<String, MyObject> result = (Map<String, MyObject>) JSON.deserializeStrict(JSON.serialize(mapStringToSObject),Map<String, MyObject>.class);

You must log in to answer this question.

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