Как копировать между объявленными общими типами с ограничениями типов значений - PullRequest
1 голос
/ 27 февраля 2009

У меня есть универсальный метод, который копирует значения между типами значений. Следующие подходы дают ошибку времени проектирования, даже с ограничением структуры. Любая идея, как я могу скопировать или привести между значениями?

private Ttgt MyMethod<Tsrc,Ttgt>(Tsrc SourceObject) 
    where Tsrc : struct
    where Ttgt : struct
{
    //Error:cannot implictly convert type 'Tsrc' to 'Ttgt'
    Ttgt returnObject = SourceObject; 

    //Error:Cannot convert type 'Tsrc' to 'Ttgt'
    Ttgt returnObject = (Ttgt)SourceObject; 

    return returnObject;
}

Ответы [ 5 ]

3 голосов
/ 27 февраля 2009

Учитывая, что есть зарегистрированный конвертер типов для типов, которые вы пытаетесь преобразовать между небольшим отражением, магия может добиться цели:

private Ttgt MyMethod<Tsrc,Ttgt>(Tsrc sourceObject) 
    where Tsrc:struct where  Ttgt:struct    
{    
    Type targetType = typeof(Ttgt);
    TypeConverter tc = TypeDescriptor.GetConverter(targetType);
    Ttgt returnObject = (Ttgt)tc.ConvertTo(sourceObject, targetType);
    return returnObject;    
}

Но из коробки это будет очень ограниченное использование, так как нет, например, конвертера между bool и int. Какую проблему вы пытаетесь решить?

Я также обнаружил еще один вопрос с каким-то сумасшедшим кодом преобразования.

Edit: Ваш комментарий проясняет, что вы пытаетесь выполнить сопоставление объектов между объектами домена и какой-либо моделью представления / контракта. Вы смотрели на AutoMapper ?

1 голос
/ 27 февраля 2009

Два определены как разные типы. Хотя они оба являются структурами, они не являются одними и теми же типами.

Определите souce и target как один и тот же тип:

private T MyMethod<T>(T source, T target)
{
1 голос
/ 27 февраля 2009

// Ошибка: невозможно преобразовать тип 'Tsrc' в 'Ttgt'

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

0 голосов
/ 04 августа 2009

Для этой цели существует класс Convert .

private Ttgt MyMethod<Tsrc, Ttgt>(Tsrc SourceObject)
    where Tsrc : struct
    where Ttgt : struct
{
    return (Ttgt) Convert.ChangeType(SourceObject, typeof(Ttgt));
}

Также обратите внимание, что вы могли бы сделать это:

    return (Ttgt) (object) SourceObject;
0 голосов
/ 27 февраля 2009

Это «По замыслу». Вы пытаетесь привести между двумя несвязанными типами значений. Это никогда не будет успешным, и поэтому оно помечено как ошибка.

Это будет верно для всех типов значений, потому что они неявно запечатаны. Для успешного приведения между TSrc -> Ttgt должны существовать отношения иерархии классов между двумя типами. Этого не может быть, потому что все типы значений запечатаны, следовательно, нет никакого способа, которым один может извлечь из другого.

Единственный способ, которым это может быть успешным, - это если бы у каждого был собственный оператор преобразования между типами. Это может быть так. Однако при работе с универсальными типами пользовательские операторы преобразования не будут обрабатываться.

...