Простая вещь нужна, но не вдуплю никак, как это сделать .
Нужно написать имплисит преобразование из базового класса в производный. Для всех полей базового класса просто сделать memberwise clone, ну и пару производных полей заполнить определённым образом. Как скопировать все поля? Вариант скопировать их по одному прямо в операторе преобразования — не катит, конечно.
Поиском наткнулся на один пост, где в базовом классе определялся метод BaseClass.CloneTo<T> where T:BaseClass. Это лучший вариант?
Re: Как написать преобразование из базового в производный?
I>Поиском наткнулся на один пост, где в базовом классе определялся метод BaseClass.CloneTo<T> where T:BaseClass. Это лучший вариант?
Сорри за неточность.. метод, конечно, BaseClass.CloneTo<T>(T to) where T:BaseClass.
Но в этом методе, разумеется, всё равно присваивание полей поочерёдно.
Я к тому, что MemberwiseClone не получится-таки использовать?
Re: Как написать преобразование из базового в производный?
I>Нужно написать имплисит преобразование из базового класса в производный. Для всех полей базового класса просто сделать memberwise clone, ну и пару производных полей заполнить определённым образом.
Мда... оказывается, вообще "user-defined conversions to or from a base class are not allowed". Не совсем понятно, почему так.. почитать спецификацию, что ли .
Буду благодарен, если кто-нить по-человечески объяснит, почему... и как можно было бы решить первоначальную задачу, если бы они были allowed.
Re: Как написать преобразование из базового в производный?
Здравствуйте, imba, Вы писали:
I>Поиском наткнулся на один пост, где в базовом классе определялся метод BaseClass.CloneTo<T> where T:BaseClass. Это лучший вариант?
Почему на AssignTo(BaseClass dst)?
Re[2]: Как написать преобразование из базового в производный
Правильное название — это, конечно, хорошо
Принимаемый параметр базового типа — тоже верное исправление.
Но внутри-то что написать? Хотелось бы присобачить сюда вызов MemberwiseClone(), а не писать 20 строчек кода a=a;b=b;c=c...
Re[3]: Как написать преобразование из базового в производный
Здравствуйте, imba, Вы писали:
I>Правильное название — это, конечно, хорошо I>Принимаемый параметр базового типа — тоже верное исправление.
Я к тому, что Generic-и тут излишни.
I>Но внутри-то что написать? Хотелось бы присобачить сюда вызов MemberwiseClone(), а не писать 20 строчек кода a=a;b=b;c=c...
Reflection
Re[3]: Как написать преобразование из базового в производный
П>Может потому что базовому классу не положено знать о своих производных?
Да нет, речь шла о преобразовании из базового класса в производный, которое определяется, конечно же, в производном классе.
Я представляю, почему такое запрещено... но весьма приблизительно.
Re[3]: Как написать преобразование из базового в производный
Здравствуйте, imba, Вы писали:
L>>Почему на AssignTo(BaseClass dst)? I>Правильное название — это, конечно, хорошо I>Принимаемый параметр базового типа — тоже верное исправление. I>Но внутри-то что написать? Хотелось бы присобачить сюда вызов MemberwiseClone(), а не писать 20 строчек кода a=a;b=b;c=c...
ИМХО, если возможно, то лучше написать эти двадцать строчек. Избавишься от рефлекшена и прочего колдунства. Это самый простой способ, и потому вплоне может сойти за самый верный.
Другой путь: какой-то свой клониатор — имеет смысл воротить тогда, когда статически неизвестно содержимое объектов. ИМХО, написание всевозможных тестов и отладка-доводка такого добра — дело непростое и даже не быстрое. Поэтому, если возможет первый способ — лучше и использовать его.
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Как написать преобразование из базового в производный
Здравствуйте, imba, Вы писали:
I>Правильное название — это, конечно, хорошо I>Принимаемый параметр базового типа — тоже верное исправление. I>Но внутри-то что написать? Хотелось бы присобачить сюда вызов MemberwiseClone(), а не писать 20 строчек кода a=a;b=b;c=c...
Ну можно сделать deep copy через сериализацию.
Re[4]: Как написать преобразование из базового в производный
Здравствуйте, _FRED_, Вы писали:
_FR>ИМХО, если возможно, то лучше написать эти двадцать строчек. Избавишься от рефлекшена и прочего колдунства. Это самый простой способ, и потому вплоне может сойти за самый верный. _FR>Другой путь: какой-то свой клониатор — имеет смысл воротить тогда, когда статически неизвестно содержимое объектов. ИМХО, написание всевозможных тестов и отладка-доводка такого добра — дело непростое и даже не быстрое. Поэтому, если возможет первый способ — лучше и использовать его.
Только надо учесть как часто будет меняться класс. Если часто — то каждый раз придется подправлять и этот метод клонирования, что геморойно и чревато проблемами (можно забыть).
Re[4]: Как написать преобразование из базового в производный
Здравствуйте, Воронков Василий, Вы писали:
I>>Но внутри-то что написать? Хотелось бы присобачить сюда вызов MemberwiseClone(), а не писать 20 строчек кода a=a;b=b;c=c...
ВВ>Ну можно сделать deep copy через сериализацию.
Как можно сделать "deep copy через сериализацию" для случая когда тип целевого объекта отличается от сериализованного?
Re[5]: Как написать преобразование из базового в производный
Здравствуйте, Lloyd, Вы писали:
L>Как можно сделать "deep copy через сериализацию" для случая когда тип целевого объекта отличается от сериализованного?
Здравствуйте, MozgC, Вы писали:
_FR>>ИМХО, если возможно, то лучше написать эти двадцать строчек. Избавишься от рефлекшена и прочего колдунства. Это самый простой способ, и потому вплоне может сойти за самый верный.
… MC>Только надо учесть как часто будет меняться класс. Если часто — то каждый раз придется подправлять и этот метод клонирования, что геморойно и чревато проблемами (можно забыть).
Юнит-тесты — самое безопасное лекарство от забывчивости
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Как написать преобразование из базового в производный
Здравствуйте, imba, Вы писали:
I>Правильное название — это, конечно, хорошо I>Принимаемый параметр базового типа — тоже верное исправление. I>Но внутри-то что написать? Хотелось бы присобачить сюда вызов MemberwiseClone(), а не писать 20 строчек кода a=a;b=b;c=c...
А вообще я что-то уже запутался. Вам нужно приведение или глубокое копирование. Если первое, то можно ведь и просто сделать реинтерпретацию памяти. Типа такого:
using System;
using System.Runtime.InteropServices;
class Program
{
[StructLayout(LayoutKind.Explicit)]
struct Convert
{
[FieldOffset(0)]
public Base BaseClass;
[FieldOffset(0)]
public Derived DerivedClass;
}
public class Base
{
public string Name;
public int Id;
}
public class Derived : Base
{
public string Title;
}
static unsafe void Main()
{
var cv = new Convert();
cv.BaseClass = new Base { Name = "Basil", Id = 123 };
Console.WriteLine("Id: {0}", cv.DerivedClass.Id);
Console.WriteLine("Name: {0}", cv.DerivedClass.Name);
Console.WriteLine("Title: {0}", cv.DerivedClass.Title);
}
}
Re[6]: Как написать преобразование из базового в производный
Здравствуйте, _FRED_, Вы писали:
MC>>Только надо учесть как часто будет меняться класс. Если часто — то каждый раз придется подправлять и этот метод клонирования, что геморойно и чревато проблемами (можно забыть).
_FR>Юнит-тесты — самое безопасное лекарство от забывчивости
Не все их делают. Да и можно забыть подправить юнит-тест. Я даже тему создавал по этой проблеме, что мол иногда забываю править юнит-тесты Но тут для себя надо просто выработать жесткую привычку — сначала подправить тест, а потом уже дальше менять код.
Re[6]: Как написать преобразование из базового в производный
Здравствуйте, Воронков Василий, Вы писали:
L>>Как можно сделать "deep copy через сериализацию" для случая когда тип целевого объекта отличается от сериализованного?
ВВ>http://msdn.microsoft.com/en-us/magazine/bb985954.aspx ВВ>Figure 3
См. выделенное
Re[7]: Как написать преобразование из базового в производный
Здравствуйте, MozgC, Вы писали:
MC>>>Только надо учесть как часто будет меняться класс. Если часто — то каждый раз придется подправлять и этот метод клонирования, что геморойно и чревато проблемами (можно забыть).
_FR>>Юнит-тесты — самое безопасное лекарство от забывчивости
MC>Не все их делают. Да и можно забыть подправить юнит-тест. Я даже тему создавал по этой проблеме, что мол иногда забываю править юнит-тесты Но тут для себя надо просто выработать жесткую привычку — сначала подправить тест, а потом уже дальше менять код.
А зачем данный тест править? Тест можно написать так, что бы при добавлении новых полей не приходилось бы править тест, иначе это неправильный тест.
Если же пренебрегать хорошими практиками и рекомендациями, то начать нужно с того, что бы перестать чистить зубы и мыться. Только после этого будет иметь смысл говорить о том, что произойдёт, если не делать тесты и забывать о важном.
Help will always be given at Hogwarts to those who ask for it.
Re[7]: Как написать преобразование из базового в производный
Здравствуйте, Lloyd, Вы писали:
L>>>Как можно сделать "deep copy через сериализацию" для случая когда тип целевого объекта отличается от сериализованного? ВВ>>http://msdn.microsoft.com/en-us/magazine/bb985954.aspx ВВ>>Figure 3 L>См. выделенное
И что? Получил глубокую копию, потом делаешь реинтерпретацию памяти, как я показал в соседнем посте.
Re[4]: Как написать преобразование из базового в производный
Здравствуйте, Воронков Василий, Вы писали:
I>>Но внутри-то что написать? Хотелось бы присобачить сюда вызов MemberwiseClone(), а не писать 20 строчек кода a=a;b=b;c=c...
ВВ>А вообще я что-то уже запутался. Вам нужно приведение или глубокое копирование. Если первое, то можно ведь и просто сделать реинтерпретацию памяти. Типа такого:
Фига се! А как это работает?!! Оно память что-ли портит? Или как-то иначе?