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
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);

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.