Можно ли клонировать ValueType? - PullRequest
10 голосов
/ 26 ноября 2009

Можно ли клонировать объект, когда он известен как упакованный ValueType без написания кода клона, специфичного для типа?

Код для справки

List<ValueType> values = new List<ValueType> {3, DateTime.Now, 23.4M};
DuplicateLastItem(values);

У меня частичная проблема с виртуальной машиной инструкций на основе стека значений. (И мне лень писать typeof (int) typeof (DateTime) ....)

обновление Кажется, я запутался (и несколько других людей). У меня есть рабочее решение:

List<ValueType> values = new List<ValueType> { 3, DateTime.Now, 23.4M }; 

// Clone
values.Add(values[values.Count() - 1]);

// Overwrite original
values[2] = 'p';

foreach (ValueType val in values)
   Console.WriteLine(val.ToString());

Ответы [ 6 ]

5 голосов
/ 26 ноября 2009

Каждое присвоение типа оценки по определению является клоном.

Edit:

При упаковке типа значения копия вашего значения будет содержаться в экземпляре ReferenceType.

В зависимости от метода клонирования я не предвижу никаких отличий.

4 голосов
/ 26 ноября 2009

Вы можете использовать хак, используя Convert.ChangeType:

object x = 1;
var type = x.GetType();
var clone = Convert.ChangeType(x, type);

// Make sure it works
Assert.AreNotSame(x, clone);

Результат - копия значения в новом объекте.

3 голосов
/ 26 ноября 2009

Не знаю, полностью ли я неправильно понял вопрос. Вы пытаетесь это сделать?

public static void Main()
{
    List<ValueType> values = new List<ValueType> {3, DateTime.Now, 23.4M};
    DuplicateLastItem(values);

    Console.WriteLine(values[2]);
    Console.WriteLine(values[3]);
    values[3] = 20;
    Console.WriteLine(values[2]);
    Console.WriteLine(values[3]);
}

static void DuplicateLastItem(List<ValueType> values2)
{
    values2.Add(values2[values2.Count - 1]);
}
2 голосов
/ 26 ноября 2009

Зачем вам все-таки клонировать код? Типы значений должны обычно быть неизменяемыми в любом случае, и это не изменяется боксом. Таким образом, хорошо разработанный тип значения не требует клонирования.

2 голосов
/ 26 ноября 2009
    private static T CloneUnboxed<T>(object o) where T : struct
    {
        return (T)o;
    }

    private static object CloneBoxed<T>(object o) where T : struct
    {
        return (object)(T)o;
    }

Хотя я сомневаюсь в необходимости того или другого, учитывая, что тип значения должен быть неизменным.

1 голос
/ 26 ноября 2009

Если вы приведете объект к ValueType, разве это не приведет к созданию клона? Это может быть перезаписано:

int i = 3;
object b = i; // box it
ValueType c = (ValueType) b; // unbox it
object d = c; // box it, effectively creating a clone

Итак, я думаю, я бы сказал, что эффективная методология клонирования будет:

object clone = (ValueType) boxed;
...