Обнаружил забавный эффект при упаковке значения. Берём пример из книги "C# 2010: ускоренный курс для профессионалов" Трея Нэша:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace test03
{
public interface IPrint
{
void Print();
}
public struct MyValue : IPrint
{
public int x;
public void Print()
{
Console.WriteLine("{0}", x);
}
}
class Program
{
static void Main(string[] args)
{
MyValue myval = new MyValue();
myval.x = 123;
myval.Print(); // (1)
IPrint printer = myval;
myval.x = 456;
myval.Print(); // (2)
printer.Print(); // (3)
}
}
}
и вставляем в него две строчки, выделенные жирным шрифтом. Что получаем?
123
456
123
Выражения (1) и (2) работают как и ожидается. Выражение (3) вроде должно было бы также вывести 456, но выводит 123.
На мой взгляд, имеется в наличии источник трудноотлавливаемых ошибок. Значение в поле структуры было изменено, а интерфейс printer помнит старое значение, поскольку именно оно и было неявно упаковано при создании объекта-интерфейса. Теперь в программе значение (в смысле типа, т.е. struct) myval существует в двух ипостасях: со значением (в смысле содержимого) поля x, равным 123, и со значением 456. Что и подтверждает явная распаковка, которую можно добавить после (3):
MyValue unpacked_myval = (MyValue)printer;
unpacked_myval.Print();
Вот.
Тестировалось на MS VS 2008.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace test03
{
public interface IPrint
{
void Print();
}
public struct MyValue : IPrint
{
public int x;
public void Print()
{
Console.WriteLine("{0}", x);
}
}
class Program
{
static void Main(string[] args)
{
MyValue myval = new MyValue();
myval.x = 123;
myval.Print(); // (1)
IPrint printer = myval;
myval.x = 456;
myval.Print(); // (2)
printer.Print(); // (3)
}
}
}
и вставляем в него две строчки, выделенные жирным шрифтом. Что получаем?
123
456
123
Выражения (1) и (2) работают как и ожидается. Выражение (3) вроде должно было бы также вывести 456, но выводит 123.
На мой взгляд, имеется в наличии источник трудноотлавливаемых ошибок. Значение в поле структуры было изменено, а интерфейс printer помнит старое значение, поскольку именно оно и было неявно упаковано при создании объекта-интерфейса. Теперь в программе значение (в смысле типа, т.е. struct) myval существует в двух ипостасях: со значением (в смысле содержимого) поля x, равным 123, и со значением 456. Что и подтверждает явная распаковка, которую можно добавить после (3):
MyValue unpacked_myval = (MyValue)printer;
unpacked_myval.Print();
Вот.
Тестировалось на MS VS 2008.