Можно ли клонировать ValueType?
-
05-07-2019 - |
Вопрос
Можно ли клонировать объект, если известно, что он представляет собой упакованный 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());
Решение
Я не знаю, полностью ли я неправильно понял вопрос.
Вы пытаетесь это сделать?
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]);
}
Другие советы
Каждое присвоение типа значения по определению является клоном.
Редактировать:
При упаковке типа значения копия вашего типа значения будет содержаться в экземпляре ReferenceType.
В зависимости от метода клонирования я не предвижу никаких различий.
Вы можете использовать хак, используя Convert.ChangeType
:
object x = 1;
var type = x.GetType();
var clone = Convert.ChangeType(x, type);
// Make sure it works
Assert.AreNotSame(x, clone);
Результатом является копия значения, упакованного в новый объект.
Зачем вам все-таки клонировать код? Типы значений должны обычно быть неизменяемыми в любом случае, и это не изменяется боксом. Таким образом, правильно разработанный тип значения не требует клонирования.
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;
}
Хотя я сомневаюсь в необходимости того или другого, учитывая, что тип значения должен быть неизменным. Р>
Если вы приведете объект к 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;