1

I have a class with the following methods:

 public virtual Map<String, List<SObject>> mapBySpecifiedStringField(List<SObject> homogeneousSObjectList, SObjectField idField) { if (homogeneousSObjectList == null || homogeneousSObjectList.isEmpty()) { return null; } String sObjectTypeString = String.valueOf(homogeneousSObjectList[0]?.getSObjectType()); String sObjectListTypeString = 'List<' + sObjectTypeString + '>'; Type dynamicListType = Type.forName(sObjectListTypeString); Type dynamicMapType = Type.forName('Map<String, ' + sObjectListTypeString + '>'); Map<String, List<SObject>> valueListByIdMap = (Map<String, List<SObject>>) dynamicMapType.newInstance(); for (SObject current : homogeneousSObjectList) { String value = (String) current.get(idField); if (value != null) { List<SObject> sObjectList = valueListByIdMap.get(value); if (sObjectList == null) { sObjectList = (List<SObject>) dynamicListType.newInstance(); valueListByIdMap.put(value, sObjectList); } sObjectList.add(current); } } return valueListByIdMap; } public virtual Map<Id, List<SObject>> mapBySpecifiedIdField(List<SObject> homogeneousSObjectList, SObjectField idField) { if (homogeneousSObjectList == null || homogeneousSObjectList.isEmpty()) { return null; } String sObjectTypeString = String.valueOf(homogeneousSObjectList[0]?.getSObjectType()); String sObjectListTypeString = 'List<' + sObjectTypeString + '>'; Type dynamicListType = Type.forName(sObjectListTypeString); Type dynamicMapType = Type.forName('Map<Id, ' + sObjectListTypeString + '>'); Map<Id, List<SObject>> valueListByIdMap = (Map<Id, List<SObject>>) dynamicMapType.newInstance(); for (SObject current : homogeneousSObjectList) { Id currentId = (Id) current.get(idField); if (currentId != null) { List<SObject> sObjectList = valueListByIdMap.get(currentId); if (sObjectList == null) { sObjectList = (List<SObject>) dynamicListType.newInstance(); valueListByIdMap.put(currentId, sObjectList); } sObjectList.add(current); } } return valueListByIdMap; } 

As you can see, the logic is very much the same, only the key is a different type. And in the future, I might need additional similar methods if the SObjectField provided for mapping has some other type (such as a number or a date).

Is there some way I can determine from the provided SObjectField an appropriate type to use for the key? And if I were to do so, would I have alternatives to throwing away type safety (returning Map<Object, List<SObject>>)?

5
  • 4
    Why not make the key's type Object? Do you really benefit from type safety in this scenario? Commented Dec 2, 2024 at 10:28
  • @PhilW, 1. Because I like type safety and 2. Because I want to be able to reuse the set of keys in methods which expect sets of ids, sets of strings, etc. Commented Dec 9, 2024 at 17:18
  • I like type safety too, in general, but there are scenarios where it makes sense to just re-use common code with an abstracted type (if only we had generics in Apex!). You can still reuse the keySet, just not with the type safety in its declaration. Yes, Apex has some annoying rules around an inability to cast List<Object> to List<SpecificType>, but you can still use contains and the like... Commented Dec 9, 2024 at 17:26
  • I also want to be able to reuse existing methods without refactoring them and without looping over things to make the conversions. And I want to be able to write new methods without making them unnecessarily generic. ... I'm not saying abstracts never make sense, but I prefer to limit them as much as possible.... and you asked "why not?" Commented Dec 10, 2024 at 18:59
  • Well, you're basically stuck because Apex doesn't do generics and the closest you have is to use Object. Your choice :) Commented Dec 10, 2024 at 20:27

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.