Modyfing value types through an interface doesn't work with generics (Brain Puzzle?)

G

gunters

Can please someone enlight me, I don't understand this:

It is possible in C# to "reach" inside a boxed value type through an
interface like in the following code:

interface IPerson
{
string Name { get; set;}
}

public struct Person : IPerson
{
public Person(string name)
{
m_Name = name;
}
public string Name
{
get { return m_Name; }
set { m_Name = value;}
}
public override string ToString()
{
return m_Name;
}
private string m_Name;
};

class Program
{
static void Main(string[] args)
{
Person p = new Person("Old Name");

ArrayList attendees = new ArrayList();
attendees.Add(p);
((IPerson)attendees[0]).Name = "New Name";
Console.WriteLine(attendees[0].ToString());
}
}

This will write "New Name" on the console.

But when I replace ArrayList with the generic List it doesn't work
anymore:

Person p = new Person("Old Name");
List<Person> genericAttendees = new List<Person>();
genericAttendees.Add(p);
((IPerson)genericAttendees[0]).Name = "New Name";
Console.WriteLine(genericAttendees[0].ToString());

This will print "Old Name". Why?

Regards,
Gunter

P.S.: I know, value types should be immutable. This is another example
why :)
 
G

gunters

I think I can answer the puzzle myself.

Casting a value type to an interface always leads to boxing
(http://blogs.msdn.com/abhinaba/archive/2005/10/05/477238.aspx).

This is the case with the generic list, so a copy gets modified.

Casting the boxed object back to the original value type doesn't work
and gives you an Compiler Error CS0445 ("Cannot modify the result of an
unboxing conversion").

But you can cast a boxed object (back) to an interface. This generates
a castclass opcode in IL which means no boxing/unboxing takes place. So
this time the original value gets modified.

When a value type is converted to an object an unnamed reference type
is created. All methods (also from interfaces) accessing the value type
are passed through this box.

What really puzzles it that when we use the generic list, boxing gets
in the way whereas in the object version its does not!

Really confusing. Value types should REALLY be immutable. And don't use
interfaces for value types if they are not.

Regards,
Gunter
 
G

gunters

BTW,

The code analysis feature of Visual Studio 2005 (former FxCop) doesn't
give one hint at problem. I think it should.

Regards,
Gunter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top