tags:

views:

195

answers:

8

Hi,

I am new to C#.net and was surprised to know that instances of an Interface can be created like

Iinterface myDimensions = (Iinterface) myBox;

How is memory allocated for this type of statement? Is the memory allocated on heap?

Can any one give any situation where this types of instantiations are used.

A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface.

Why is such a constraint enforced in the language?

Thanks,

+9  A: 

That's not an instantiation -- it's a type cast. The instance is the original object, i.e. myBox. As for memory, yes, there's memory allocated for the reference -- whether it's on the heap or the stack depends entirely on the context. In your example (which looks like it's in a function), I'd guess the stack.

With regards to explicit implementation: the language feature allows a single class to implement two or more interfaces containing one or more members having exactly the same signature. For example:

interface A
{
   void Foo();
}

interface B
{
   void Foo();
}

class C : A, B
{
   void A.Foo()
   {
   }

   void B.Foo()
   {
   }
}

Without this feature, it's unclear to the compiler which interface member C.Foo implements. The caveat, of course, is that callers can't simply call C.Foo, since it would also not be obvious which method to invoke; an object of type C would therefore have to be first cast to either A or B to make the programmer's Foo-lish intention clear.

Ben M
Well, in the current CLR implementation, I believe regardless of whether `myBox` is a value type or not, `myDimensions` will be treated as a reference type (and thus heap-allocated). So if `myBox` is on the stack, `myDimensions` will be a boxed copy of it on the heap.
Dan Tao
Why are you guessing the stack?
Conrad Frix
I meant the _reference_ is allocated on the stack, not that the object itself is. It's true that if `myBox` is a value type, then the memory required for boxing the value will be allocated on the heap.
Ben M
@Ben M Can you please tell me why is the constraint "When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface".
Sandeep
@Sandeep for the reason I mention above: if you have `var c = new C(); c.Foo();`, it's unclear which `Foo` you want to call--so you have to typecast. Hiding is (nearly) the whole point of explicit implementation: you don't _need_ to explicitly implement a member; it's only really useful in these situations. (Or a similar situation, in which `C : A` and `C` already has `Foo()`.)
Ben M
@Sandeep: See my answer below
abatishchev
+2  A: 

your statement

Iinterface myDimensions = (Iinterface) myBox;

is not creating anything, it is casting the object myBox (which would have to be instantiated somewhere) to the Iinterface type, and pointing myDimesions to that object.

David
+5  A: 

What you have is a cast, not an instantiation. In this case, the object already has to be created somewhere else:

// Allocate memory on the stack to point to the location on the heap
// to store the object and create the object on the heap.
Box box = new Box();

// Allocate memory on the stack to point to the location on the heap
// and point it to the already existing object on the heap.
IInterface iBox = (IInterface)box;

The quote you have from MSDN is in reference to Explicit Interface Implementations. These can be a little confusing. A quick example is easiest:

public interface ISomething
{
    void SayHi();
}

public class Something : ISomething
{
    public void SayHi() { Console.WriteLine("Hello World!"); }

    public void ISomething.SayHi() { Console.WriteLine("42!"); }
}

Now your code can have something like the following:

Something obj = new Something();

// Outputs "Hello World!"
obj.SayHi();

ISomething iObj = obj;

// Outputs "42!"
iObj.SayHi();

In that example, memory works the same way as I first explained.

Justin Niessner
+2  A: 

The language in the MSDN C# reference for interface is a bit misleading. When it says instance of the interface it actually means a reference to the interface, which you can get by casting an object (i.e., an instance of a class) to an interface type.

Interface members can be implicitly implemented or explicitly implemented. When it's explicitly implemented, the interface name is used to qualify it:

public class Box: IInterface
{
   void IInterface.Foo() { ... }
}

This hides the member from the public class interface. One reason for this is for versioning, like when the class already has an unrelated Foo() method. In order to specify the IInterface.Foo() and not Box.Foo(), the only way is through a reference to IInterface, either by casting it or through a variable declared as IInterface. You can just as easily have this:

 IInterface myDimensions = myBox; //no casting needed
 myDimensions.Foo(); //calls Box.IInterface.Foo() and NOT Box.Foo()
Mark Cidade
A: 

Basically you have an object X that is pointed by a variable name call "myBox". The object memory allocation depends on how you create this object X.

The code: Iinterface myDimensions = (Iinterface) myBox; only assign your object X to "myDimensions" variable. Since this variable is an Iinterface, you have to use (Iinterface) to cast it. This is a type safety feature that kind of enforce you to know what kind of object you are dealing with.

By now you have at least two variables "myBox" and "myDimensions" that point to object X.

You can create as many variables as you want to point to this object. You will need to cast "myBox" to "myDimensions" during assignment if the variable type of myBox doesn't implement "Iinterface", even though your object X supports Iinterface.

As a side note, variables takes up memory too, because it needs to store the address of the actually instance

dsum
A: 

Can any one give any situation where this types of instantiations are used.

As others have said, this isn't really an instantiation. As for its usage, one example is one you actually wouldn't see because it happens under the covers. Consider the using statement

using (DisposableObject foo = new DisposableObject())
{
   // doing things with foo
}

And how the compiler evaluates that expression and transforms it to something like

DisposableObject foo = null;
try 
{
   foo = new DisposableObject();
   // doing things with foo
}
finally
{
   if (foo != null)
   {
       ((IDisposable)foo).Dispose();
   }
}

Or consider other scenarios where a method accepts in interface type rather than a class. This is because you could have multiple classes that implement such an interface, but the method is only concerned that objects of those classes fulfill the contract of the interface.

public void Dance(ICanDance dancer, bool wantTo)
{
     if (wantTo)
         dancer.Dance();
}

The actual dancer can be anything that implements the interface, be it LipSynchingPopSinger, StageDancer, or GuyThatIsNotTheFather.

Anthony Pegram
+1  A: 

Declaration:

interface IMy
{
    void OhMy();
}

class Explicit : IMy
{
    public void IMy.OhMy() { }
}

class Implicit : IMy
{
    public void OhMy() { }
}

Usage:

Implicit i = new Implicit();
i.OhMy(); // ok

Explicit e = new Explicit();
e.OhMy(); // it cannot be accessed through a class instance
((IMy)e).OhMy(); // but only through an instance of the interface

IMy my = new Explicit();
my.OhMy(); // ok
abatishchev
+7  A: 

Before answering your first question, I note that you have two questions here. In the future, consider asking two separate questions on Stack Overflow when you have two questions. As you might have noticed, when you ask two questions in one, often the second question gets ignored by almost everyone.

I was surprised to know that instances of an interface can be created like

Iinterface myDimensions = (Iinterface) myBox; 

How is memory allocated for this type of statement? Is the memory allocated on heap?

As others have pointed out, this is not necessarily the creation of an instance of a type that implements the interface. What everyone seems to have forgotten in their haste to tell you that reference conversions do not allocate memory, is that boxing conversions do allocate memory. If myBox is of a struct type then this will allocate memory on the heap for a "wrapper" and make a copy of the value in the wrapper. The wrapper then implements the interface.

Moving on to your second question:

A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface. Why is such a constraint enforced in the language?

The purpose of explicit interface implementation is to enable a class to implement a particular interface without requiring that those methods show up in places they are not wanted. For example, suppose you have:

class MyConnection : IDisposable
{
    public void OpenConnnection() { ... }
    public void CloseConnection() { ... }
    public void Dispose() { ... CloseConnection(); ... }
}

If disposing an open connection is the same as closing a connection then you probably do not want to confuse your users by either (1) having two methods that do the same thing, or (2) having a method OpenConnection paired with a non-obvious name like Dispose. By enabling you to make Dispose "invisible" unless the object is converted to IDisposable then you make it easier on your users to discover the right thing to do.

Another circumstance where you'd use this is when you have two interfaces with the same name:

interface IFoo { void M(); }
interface IBar { void M(); }

Now how do you make a class C that implements both IFoo and IBar, but has different implementations for the two M methods? You have to use explicit implementation for one or both of them if you want two different bodies.

Eric Lippert