76

I have a function that returns same kind of objects (query results) but with no properties or methods in common. In order to have a common type I resorted using an empty interface as a return type and "implemented" that on both.

That doesn't sound right of course. I can only console myself by clinging to hope that someday those classes will have something in common and I will move that common logic to my empty interface. Yet I'm not satisfied and thinking about whether I should have two different methods and conditionally call next. Would that be a better approach?

I've been also told that .NET Framework uses empty interfaces for tagging purposes.

My question is: is an empty interface a strong sign of a design problem or is it widely used?

EDIT: For those interested, I later found out that discriminated unions in functional languages are the perfect solution for what I was trying to achieve. C# doesn't seem friendly to that concept yet.

EDIT: I wrote a longer piece about this issue, explaining the issue and the solution in detail.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Sedat Kapanoglu
  • 46,641
  • 25
  • 114
  • 148
  • 15
    These are called [marker interfaces](http://en.wikipedia.org/wiki/Marker_interface_pattern) and apparently they're widely used. – BoltClock Sep 26 '11 at 08:49
  • 3
    Read this http://msdn.microsoft.com/en-us/library/ms182128%28v=vs.80%29.aspx (my opinion need to be different methods) – V4Vendetta Sep 26 '11 at 08:49
  • 1
    Something on similar lines http://stackoverflow.com/questions/835140/using-marker-classes-to-control-logic-flow – V4Vendetta Sep 26 '11 at 08:57
  • 9
    Can a code smell be a nice smell, in which case it's good? Coffee, waffles and bacon for example – Chris S Sep 26 '11 at 14:44
  • When you call your function, do you already know from the parameters you give what kind of object is comming back? If so, having multiple functions returning the proper type would be more correct. – Angel O'Sphere Sep 27 '11 at 12:25
  • @AngelO'Sphere no I don't. I use a single `if(x is y)` construct to decide on what path to take. – Sedat Kapanoglu Sep 27 '11 at 14:06
  • Well, inside the method that is returning the object you do, so the question is: would it make more sense to do that from outside? – Angel O'Sphere Sep 27 '11 at 22:15
  • @AngelO'Sphere: I think it wouldn't since the function and the calling code are in separate assemblies. Isolation is clear. That's why my other approach was to have "two functions" and call them based on conditions/return values. – Sedat Kapanoglu Sep 28 '11 at 08:27
  • @ssg, I guess we talk cross over. What has the fact that caller and callee are in different assemblies to do with my question? The method you called is a kind of factory, right? Obviously the object it creates is always only an "Interface". I assume the parameters you give, determine the true type of the object. So, again: if you look sharply at the parameters before you call that factory method, do you know what kind of object it will create? If so, why not making several factory methods and call the right one and get the correct return type? Now you need to dynamic cast your interface, or? – Angel O'Sphere Sep 28 '11 at 12:20
  • @AngelO'Sphere No I don't know the return type. In order to determine the return type I need to implement the business logic in assembly A again in assembly B which means unnecessary replication and kills the purpose of having such isolation and componentization. That's why different assemblies were significant. – Sedat Kapanoglu Sep 28 '11 at 13:14
  • Oki, if that is the case, it is no code smell ;D (well it is smelling, hence the questions, but it is not stinking and seems as solution adequate). – Angel O'Sphere Sep 28 '11 at 13:58
  • Without wanting to cross-post, there is a good discussion here about "marker interfaces". I provided some reasoning for why they are a bad idea: http://stackoverflow.com/questions/1023068/what-is-the-purpose-of-a-marker-interface/12688851#12688851 – Tom B Oct 09 '12 at 10:19

5 Answers5

48

Although it seems there exists a design pattern (a lot have mentioned "marker interface" now) for that use case, i believe that the usage of such a practice is an indication of a code smell (most of the time at least).

As @V4Vendetta posted, there is a static analysis rule that targets this: http://msdn.microsoft.com/en-us/library/ms182128(v=VS.100).aspx

If your design includes empty interfaces that types are expected to implement, you are probably using an interface as a marker or a way to identify a group of types. If this identification will occur at run time, the correct way to accomplish this is to use a custom attribute. Use the presence or absence of the attribute, or the properties of the attribute, to identify the target types. If the identification must occur at compile time, then it is acceptable to use an empty interface.

This is the quoted MSDN recommendation:

Remove the interface or add members to it. If the empty interface is being used to label a set of types, replace the interface with a custom attribute.

This also reflects the Critique section of the already posted wikipedia link.

A major problem with marker interfaces is that an interface defines a contract for implementing classes, and that contract is inherited by all subclasses. This means that you cannot "unimplement" a marker. In the example given, if you create a subclass that you do not want to serialize (perhaps because it depends on transient state), you must resort to explicitly throwing NotSerializableException (per ObjectOutputStream docs).

  • 1
    I think in my use case (two classes only and will unlikely be derived), it seems ok. See my clarification edit. – Sedat Kapanoglu Sep 26 '11 at 09:25
  • I'm accepting this as the answer. Although other answers provide valuable information too this one elaborates most about the potential issues with the approach. – Sedat Kapanoglu Sep 26 '11 at 10:54
  • 1
    As has been pointed-out elsewhere, although `attributes` are the 'correct' way of doing this, they are more awkward to implement and use, which in practise will work against their use. – nicodemus13 Nov 29 '12 at 18:36
9

You state that your function "returns entirely different objects based on certain cases" - but just how different are they? Could one be a stream writer, another a UI class, another a data object? No ... I doubt it!

Your objects might not have any common methods or properties, however, they are probably alike in their role or usage. In that case, a marker interface seems entirely appropriate.

ColinE
  • 68,894
  • 15
  • 164
  • 232
8

If not used as a marker interface, I would say that yes, this is a code smell.

An interface defines a contract that the implementer adheres to - if you have empty interfaces that you don't use reflection over (as one does with marker interfaces), then you might as well use Object as the (already existing) base type.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • 2
    `object` would be too generic and would provide no hint on the return "kind". interface helps me narrow down my options on interpreting the function's return value. but I understand your comment in relation to lack of clarification on similarity of the objects I'm returning. – Sedat Kapanoglu Sep 26 '11 at 09:31
  • @ssg - quite. There must be _something_ similar with these objects if you pass them to one method to operate on them, otherwise you should have separate methods. – Oded Sep 26 '11 at 09:39
6

You answered your own question... "I have a function that returns entirely different objects based on certain cases."... Why would you want to have the same function that returns completely different objects? I can't see a reason for this to be useful, maybe you have a good one, in which case, please share.

EDIT: Considering your clarification, you should indeed use a marker interface. "completely different" is quite different than "are the same kind". If they were completely different (not just that they don't have shared members), that would be a code smell.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • This looks like a better candidate for a comment. I added a clarification section to my question. Ask away if you need anything else. – Sedat Kapanoglu Sep 26 '11 at 09:23
4

As many have probably already said, an empty interface does have valid use as a "marker interface".

Probably the best use I can think of is to denote an object as belonging to a particular subset of the domain, handled by a corresponding Repository. Say you have different databases from which you retrieve data, and you have a Repository implementation for each. A particular Repository can only handle one subset, and should not be given an instance of an object from any other subset. Your domain model might look like this:

//Every object in the domain has an identity-sourced Id field
public interface IDomainObject
{
   long Id{get;}
}

//No additional useful information other than this is an object from the user security DB
public interface ISecurityDomainObject:IDomainObject {}

//No additional useful information other than this is an object from the Northwind DB
public interface INorthwindDomainObject:IDomainObject {}


//No additional useful information other than this is an object from the Southwind DB
public interface ISouthwindDomainObject:IDomainObject {}

Your repositories can then be made generic to ISecurityDomainObject, INorthwindDomainObject, and ISouthwindDomainObject, and you then have a compile-time check that your code isn't trying to pass a Security object to the Northwind DB (or any other permutation). In situations like this, the interface provides valuable information regarding the nature of the class even if it does not provide any implementation contract.

KeithS
  • 70,210
  • 21
  • 112
  • 164