469,631 Members | 1,666 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,631 developers. It's quick & easy.

Explicit implementation on value type leads to rather counter intuitivebehavior...

Hi,

I have been annoyed in one of my recent projects with a problem related
to the explicit implementation of an interface on a value type. I will
take an example to show the problem.

Say we have this simple interface :
interface IInitializable
{
void Init();
}

Let us implement it explicitly in a value type :
struct Struct:
IInitializable
{
public bool Initialized;

void IInitializable.Init()
{
Initialized=true;
}
}

Now if you create a new Struct :
Struct s=new Struct();

You can check that s.Initialized is false. Try to call the Init method
(you have to cast the instance to IInitializable due to the explicit
implementation) :
((IInitializable)s).Init();

Intuitively, you would expect s.Initialized to be true, but in fact it
is still false !
This is explainable, as I figure that there must be some boxing
occuring during the cast, but I found this quite disturbing... I don't
remember having read anything about boxing in casts, and I find this
"feature" quite dangerous. What do you think ?

Mathieu

PS : Here is my complete sample code

using System;

namespace TestValueType
{
interface IInitializable
{
void Init();
}

struct Struct:
IInitializable
{
public bool Initialized;

void IInitializable.Init()
{
Initialized=true;
Console.Out.WriteLine("Struct.Init()");
}
}

class Class:
IInitializable
{
public bool Initialized;

void IInitializable.Init()
{
Initialized=true;
Console.Out.WriteLine("Class.Init()");
}

[STAThread]
static void Main(string[] args)
{
Class c=new Class();
Console.Out.WriteLine("Class.Initialized={0}", c.Initialized);
((IInitializable)c).Init();
Console.Out.WriteLine("Class.Initialized={0}", c.Initialized);
Console.Out.WriteLine();

Struct s=new Struct();
Console.Out.WriteLine("Struct.Initialized={0}", s.Initialized);
((IInitializable)s).Init();
Console.Out.WriteLine("Struct.Initialized={0}", s.Initialized);
Console.Out.WriteLine();

Console.ReadLine();
}
}
}


Aug 8 '06 #1
4 2196
Agree boxing can be a headache... personally that's partly why I only
generally use structs to define immutable entities... "keep it simple" and
all that...

IIRC, even in 2.0 /standard/ interface casting does involve boxing, however,
I understand (not 100% sure) that an interface contraint on a generic method
does /not/ box... a bit tricky to prove without looking at the IL, however
(since you'd need to use ref, and its unclear if it is simply unboxing
afterwards). I don't /think/ it boxes, though... unless (within the generic
method) you assign it to an interface of the same type as it already
supports!

Marc


Aug 8 '06 #2
Mathieu Cartoixa wrote:

<snip>
This is explainable, as I figure that there must be some boxing
occuring during the cast, but I found this quite disturbing... I don't
remember having read anything about boxing in casts, and I find this
"feature" quite dangerous. What do you think ?
Boxing is always involved when you cast a value type to object,
ValueType or an interface type.
>From 13.1.5 (ECMA spec):
<quote>
A boxing conversion permits any value-type to be implicitly converted
to the type object or to any interface-type implemented by the
value-type. Boxing a value of a value-type consists of allocating an
object instance and copying the value-type value into that instance.
</quote>

As Marc said, this suggests an inappropriate use of structs.

Jon

Aug 8 '06 #3
For ref, I've just looked at some IL, and it appears to bear this out;
cast to interface = box
generic constraint = not boxed

This only really makes a difference in terms of avoiding the performance
implications of boxing / unboxing - you've still got the headache of
value-type semantics - i.e. the object being cloned as it passes between
different stacks... yup, I'll definitely stick to immutables ;-p

Marc
Aug 8 '06 #4
Jon Skeet [C# MVP] a écrit :
>
<snip>

From 13.1.5 (ECMA spec):
<quote>
A boxing conversion permits any value-type to be implicitly converted
to the type object or to any interface-type implemented by the
value-type. Boxing a value of a value-type consists of allocating an
object instance and copying the value-type value into that instance.
</quote>

As Marc said, this suggests an inappropriate use of structs.

Jon
Well, you know how it goes : I started with simple structures (similar
to SqlInt16, SqlInt32...), and one day I realized that they would have
to be "internally mutable", i.e. mutable only inside the library I was
building. I (wrongly) figured that explicit implementation of an
interface would do the trick.
As for the C# Reference (MSDN), it just states that "Structs can
implement an interface but they cannot inherit from another struct." and
that "A struct can implement interfaces."...

Anyway, thanks for your lights.

Mathieu
Aug 9 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by David Mertz, Ph.D. | last post: by
6 posts views Thread by MPowell | last post: by
1 post views Thread by Stub | last post: by
31 posts views Thread by Michael C | last post: by
2 posts views Thread by COLIN JACK | last post: by
3 posts views Thread by Steven T. Hatton | last post: by
12 posts views Thread by Rahul | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.