Are C# Interfaces purely aesthetic?

I’ve been reading up on interfaces and their uses, but I’m having trouble finding anything that makes me feel like interfaces are worth implementing into my code. So far, it seems that all it does is create a “contract” for methods, variables, etc. that says, “These things are required in your code.”

Aside from an interface making it required to add certain functions or variables to a class, is there another use? Or is it purely a design/aesthetic decision for implementing your code so that you don’t forget to add certain things in your code?

Thanks!

To answer that, might be good to explain where interfaces come from! :slight_smile:

Back in the day, with the advent of object oriented programming, we had inheritance, which you’re probably familiar with. This is basically the ability for a type to inherit member variables and functions from a parent type. Its one of many approaches to code that helps share functionality between systems or parts of a system. You probably know that already though!

What you are probably also familiar with is the concept of virtual functions. These were a concept introduced with object orientation, that allowed a parent (or base) class to say ‘I should have this function’ (and potentially define the default version of it), but child classes to override it. The really powerful aspect of this feature was that you could write code that dealt with the base class without worrying about what derived class it really corresponded to. So I could write a ‘vehicle’ class that had an ‘explode’ function. Then another system could have a list of vehicles that it might tell to explode without worrying about whether they were cars, helicopters, boats or planes :slight_smile:

One of the languages that introduced a lot of these features was C++, which was effectively object oriented C. However it also introduced a capability that turned out to be extremely complex and bug prone - multiple inheritance. This was having a class that derived from multiple base classes, and when unrestriced this type of feature can cause no end of issues with working out where data should exist and how it should be copied around - look up slicing for an example.

However, a really useful feature of C++ multiple inheritence was when the code team agreed they could use it, but a class could only ever inherit from 1 full base class. Anything else it inherited from had to consist of nothing other than pure (undefined) virtual functions - no member variables! This simplification allowed for the biggest benefits of inheritance - vehicle/explode example, as you could still define ways classes should communicate by saying what functions they had to contain, but didn’t have to worry about confusions over member variable duplication or layout. Programmers ended up describing these types of base class as interfaces, because they did nothing other than describe the interface a type had to the rest of the code.

In C#, this principle was made a feature of the language. The coder is forced to distinguish between a class definiton and an interface definition. A class can only derive from 1 other class, but can derive from as many interfaces as it likes. An interface can only contain pure virtual functions, and a class must define all of those functions.

The langugage uses this feature extensively. An IComparable interface on your class provides the language with a way of ‘comparing’ that you can define. An IEnumerable interface provides the language with a way of enumerating (using in something like a for loop - think the ‘List’ class) your class. There’s many more, all of which allow you to expand the language.

Whether you need to write your own, in all honestly probably not. You may hit situations in which you really see the need to define multiple interfaces to your types for other areas of your game to use, but Unity is geared towards a model in which you share functionality by defininng multiple components, and less dependent on inheritance. You might well find yourself making use of the built in interfaces to extend the language though.

Hope that little history lesson helps a bit :slight_smile:

No, they’re not.

You can get by without them, and I wouldn’t go to the trouble of defining an interface until I know that I’m going to be using it, but when they’re the right thing to use they can be very useful, in particular for making modular and reusable code.

The above is a general coding point. For a C#-specific example note for example that many functions, as well as things like foreach, can be used on any class that implements the IEnumerable interface. If you want to be able to use foreach on your own class, all you need to do is ensure that it implements that interface - all other details of your class is totally up to you. That’s a very worthwhile use of interfaces, and it’s the kind of thing that you can do in your own code.

And a Unity use case: I have just been adapting some inherited code so as to totally change the class that controls how the user’s screen swipe controls movement. I started by looking at the existing one and how it interacts with other systems. From that I defined an interface, made the old class implement that interface, and then made sure that those other systems only know about the interface. Now, as far as the rest of the code is concerned, all the implementation detail for the old mechanism is totally hidden behind that interface. So I am able to create different mechanisms which might work in totally different ways to the old one but, so long as they implement the interface, they will just slot in.