1

So, I have a little bit of an issue that I can't exactly wrap my head around.

So, I have a base class called Property, and I have a lot of classes that derive from that one, like IntProperty, ColorProperty and so on. Now, I also have a few of them that are of the enum type and currently they are all separate classes. I'd like to make it a generic class but here's the issue with this:

In a different part of the code I need to handle all of them. Keep in mind I can't use virtual functions for this (I'm doing something with the UnityEditor).

Currently, I have a function that takes a Property as a parameter and then I do this for all types that derive from Property:

if(property is IntProperty) { IntProperty intProperty = property as IntProperty; intProperty.theValue = specific_int_function(); } 

That specific_int_function is the same for all enum values privided I have the T from a generic.

Ideally I'd like to do something like this (pseud-ish code):

(using T) { if(property is EnumProperty<T>) { EnumProperty<T> enumProperty = property as EnumProperty<T>; enumProperty.value = (T)my_enum_value_function(typeof(T)); } } 

Any idea about how I could make all this code nicer?

Hopefully I provided all the relevant information.

Edit:

It's not so much that I can't use virtual functions in those classes but I can't call any of the specific functions in that particular file. I have 2 compilation groups and only one can access those functions (EditorGUI functions for people who know what I'm talking about)

Regards, Lorin

5
  • You could pass a function to the handler? Commented Oct 15, 2017 at 14:39
  • Can you not use virtual methods at all, or only not in your base class? The reason I'm asking is because my preferred approach would use virtual methods in a helper class. Commented Oct 15, 2017 at 15:14
  • As long as the virtual classes can be move in a different file it should be fine. Just not in the base and/or derived classes. Commented Oct 15, 2017 at 15:17
  • Are you going to derive from Property<T> and create IntProperty:Property<int>, SomeEmumProperty<SomeEnum>, SomeOtherEnumProperty<SomeOtherEnum> types? Or you want just instantiate properties this way: var intProperty = new Property<int>(name, value);? Commented Oct 15, 2017 at 15:21
  • I currently do not have Property<T>, just a regular Property that contains the common data. I put all these properties in some classes which also derive from a base class and then I use reflection to iterate over all properties. I'm comming from a C++ background so maybe I'm thinking about this in the wrong way and/or I'm abusing reflection. Commented Oct 15, 2017 at 15:25

2 Answers 2

1

Keep in mind I can't use virtual functions for this (I'm doing something with the UnityEditor).

That's really what you should be doing. If you can't, then fine, but I'm leaving this note here for the benefit of other people will be reading this question and answer too.


In my experience, the least difficult way of achieving this is with a helper class, because it lets you avoid some of the reflection complexity that you would have to deal with if you used a generic helper method.

abstract class EnumPropertyHelper { public abstract void DoSomething(Property property); } class EnumPropertyHelper<T> : EnumPropertyHelper { public override void DoSomething(Property property) { EnumProperty<T> enumProperty = property as EnumProperty<T>; enumProperty.value = (T)my_enum_value_function(typeof(T)); } } 

Then,

if (property.GetType().IsGenericType && property.GetType().GetGenericTypeDefinition() == typeof(EnumProperty<>)) { var helperType = typeof(EnumPropertyHelper<>).MakeGenericType(property.GetType().GetGenericTypeArguments()); var helper = (EnumPropertyHelper)Activator.CreateInstance(helper); helper.DoSomething(property); } 

But you do need to jump through hoops similar to this one whatever you end up doing, because C# and .NET don't allow you to have generic code in non-generic methods.

Sign up to request clarification or add additional context in comments.

Comments

0

You could use add a function pointer to the class, and each constructor could implement it's own function?

Add a property Func<void> functionPTR = null

In each class you'd have a function such as

void specific_int_function() { //Do Something } 

In the class constructor

functionPTR = specific_int_function; 

And then in the generic class

void GenericHandler() { functionPTR(); } 

I'm not sure about the syntax, but this should give you the performance you're going for.

Read up on function pointers to see how to define the return value and function parameters.

2 Comments

Yeah, I can't refer to the 'specific_int_function' in any of the base or derived classes. My issue is not with performance as this should be fast regardless of the method. I'm more interested in keeping the code clean and flexible.
Where is the specific_int_function defined? You can also pass it as an argument to the handler function.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.