0

I have a base class BaseCollectionInspector which has two derived classes: ReactionCollectionInspector and ConditionCollectionInspector.

The base class has this method:

protected override void AddItem(object obj) {
    AssetInfo assetInfo = (AssetInfo) obj;
    string assetName = Path.GetFileNameWithoutExtension(assetInfo.assetPath);
    var assetType = Type.GetType(typeof(BaseReaction).Namespace + "." + assetName + ", Assembly-CSharp");
    var newItem = (BaseReaction) collection.gameObject.AddComponent(assetType);
    newItem.showItem = false; // Hide script in inspector
    int index = collectionList.serializedProperty.arraySize++;

    collectionList.serializedProperty.GetArrayElementAtIndex(index).objectReferenceValue = newItem;
    serializedObject.ApplyModifiedProperties();
}

The difference between the two derived types is that one holds a list of BaseReaction and the other BaseCondition which both has a showItem property.

They both would use the exact same AddItem method, except the casting on assetType and newItem.

I'm trying to learn C# properly and want to use the DRY principle even if it's easy to just copy the code. I think I might be able to use an Interface, but I'm not sure how I would set that up, since I want the method to be just in the base class, adapting for the correct sub class.

I also tried putting something like this in each of the derived classes, but I can't find a way to use that for casting in the base class method:

private Type itemType = typeof(BaseReaction);

Thank you in advance!

Niclas
  • 1,362
  • 1
  • 11
  • 24
  • 1
    `AddItem(object obj)` is *rarely* good idea... It's hard to say what would be better without usage sample but consider if simply strongly typed separate methods or generic method would work. – Alexei Levenkov Apr 23 '19 at 20:08
  • This is a Unity Editor class, that is called like ` dropdownMenu.AddItem(new GUIContent(menuPath), false, AddItem, new AssetInfo {assetPath = path});` and AddItem sends whatever you click on (that can be of any type) as a parameter. So I can't really change that. – Niclas Apr 23 '19 at 20:11
  • https://stackoverflow.com/questions/298976/is-there-a-better-alternative-than-this-to-switch-on-type maybe what you are looking for... – Alexei Levenkov Apr 23 '19 at 20:14
  • Thanks, I noticed other similar problems with the derived classes, so I might have to make them separate anyhow, like both have a list called `collection` but one is of `ReactionCollection` type and the other is `ConditionCollection`. I can't seem to cast them in the subclass, and the base class still knows what properties exist in them. :/ – Niclas Apr 23 '19 at 20:16

1 Answers1

0

The solution that worked very well for me was:

  • Create a base class CollectionItem that both BaseReaction and BaseCondition derived from, which had all properties that were similar
  • Create a base class BaseCollection that both ReactionCollection and ConditionCollection derived from, which had all properties that were similar

This way I could just reference the base classes CollectionItem and BaseCollection in the BaseCollectionInspector, and set all methods that I want to be unique for the derived inspectors to abstract

I'm sure this is pretty specific to what I was working with, but the main point is that it's possible, you just need to find the common parts of similar classes, and make a parent class of it.

Thanks for your help here though :)

PS: I really love C# and realize how confusing PHP is to work with no strict typing of anything, even if I've worked in it for 20 years or so :)

Niclas
  • 1,362
  • 1
  • 11
  • 24