Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting and interface inheritance

Each item has an interface, IItem. As well as this, there is a interface known as IDrawableItem which inherits from Item.

The code below, is trying to draw a drawable item, but cannot as the collection this class stores accepts only IItem. You can add anything that inherits from IItem to this class, but using other methods can only be achieved by casting.

foreach (var item in Items) {
    item.Draw();               // The casting would go here.
}

I know how to cast, as etc... but is this acceptable? Is it a best practice?

Just wondering if there are other ways to handle such scenarios.

like image 697
Finglas Avatar asked Jan 15 '10 15:01

Finglas


People also ask

What is interface inheritance?

It is the mechanism in java by which one class is allowed to inherit the features(fields and methods) of another class. Like a class, an interface can have methods and variables, but the methods declared in an interface are by default abstract (only method signature, no body).

What is the difference between interface and inheritance?

Inheritance is the mechanism in java by which one class is allowed to inherit the features of another class. Interface is the blueprint of the class. It specifies what a class must do and not how.

What is casting to an interface?

You can access the members of an interface through an object of any class that implements the interface. For example, because Document implements IStorable , you can access the IStorable methods and property through any Document instance: Document doc = new Document("Test Document"); doc.

Does interface use inheritance?

Also, it is possible for a java interface to inherit from another java interface, just like classes can inherit from other classes. You specify inheritance using the extends keyword. Inheritance will be further discussed below. But unlike classes, interfaces can actually inherit from multiple interfaces.


1 Answers

Use Enumerable.OfType to extract only those elements of Items that implement IDrawableItem:

foreach(var item in Items.OfType<IDrawableItem>()) {
    item.Draw();
}

To address the question that Nanook asked in the comments the above code will probably be translated into code equivalent to the following:

foreach(var item in Items) {
     if(item is IDrawableItem) {
        ((IDrawable)item).Draw();
     }
}

Of course, really there is an iterator behind the scenes that looks something like this:

public static IEnumerable<T> OfType<T>(this IEnumerable<TSource> source) {
    if(source == null) {
        throw new ArgumentNullException("source");
    }
    foreach(TSource item in source) {
        if(item is T) {
            yield return (T)item;
        }
    }
}

So, what this shows is that we probably only iterate through Items once. Of course, there is no requirement that OfType is implemented like the above but this is the sensible thing to do.

like image 114
jason Avatar answered Oct 15 '22 08:10

jason