2010-02-05 10 views
7

C'è un modo per controllare la conversione del tipo in C#? Così, per esempio, se ho due tipi con essenzialmente le stesse informazioni, ma viene utilizzato per il funzionamento interno della mia applicazione e l'altro è un DTO utilizzato per comunicare con le applicazioni non-.NET:Come controllare la conversione di tipo in C#

public sealed class Player 
{ 
    public Player(string name, long score) 
    { 
    Name = name; 
    Score = score; 
    ID = Guid.NewGuid(); 
    } 

    public string Name { get; private set; } 

    public Guid ID { get; private set; } 

    public long Score { get; private set; } 
} 

public sealed class PlayerDTO 
{ 
    public PlayerDTO(string name, long score, string id) 
    { 
    Name = name; 
    Score = score; 
    ID = id; 
    } 

    public string Name { get; private set; } 

    // the client is not .Net and doesn't have Guid 
    public string ID { get; private set; } 

    public long Score { get; private set; } 
} 

destro ora, ho bisogno di creare una nuova istanza di PlayerDTO dalla mia istanza Player ogni volta e sto cercando un modo migliore e più pulito per farlo. Un'idea che avevo era di aggiungere un metodo AsPlayerDTO() per la classe di giocatore, ma sarebbe bello se riesco a controllare il processo di tipo di conversione in modo che io possa fare questo, invece:

var playerDto = player as PlayerDTO; 

Qualcuno sa se questo è possibile e come potrei essere in grado di farlo?

Grazie,

risposta

3

È possibile implementare sia implicita o esplicita tipo di conversione: http://msdn.microsoft.com/en-us/library/ms173105.aspx.

In alternativa, se si desidera evitare che ciascuna classe debba conoscere l'altra, è possibile utilizzare la mappatura personalizzata o una libreria di mappatura esistente come AutoMapper.

+0

Il sovraccarico dell'operatore implicito/esplicito sembra funzionare per me ed è anche ragionevolmente pulito. Curioso però, questo non si applica agli array, ma AutoMapper sembra dare quell'opzione basata sul commento di Michael Meadows qui sotto. C'è un modo per implementarlo senza utilizzare terze estensioni come AutoMapper? – theburningmonk

+0

Non importa, ho trovato la risposta alla mia seconda domanda su un'altra domanda StackOverflow http://stackoverflow.com/questions/1865031/why-wont-castdouble-work-on-ienumerableint Array.ConvertAll (playerList.ToArray(), p => (PlayerDTO) p); – theburningmonk

+1

Inoltre, se stai usando Linq, puoi usare Select ... playerArray.Select (player => (PlayerDTO) player) .ToArray(); –

0

Che dire di operatore di conversione:

public static explicit operator PlayerDTO (Player value)... 
public static implicit operator PlayerDTO (Player value)... 
5

È possibile implementare un explicit convesion operator tra i due tipi.

Si potrebbe anche considerare l'utilizzo di AutoMapper per l'attività.

+0

+1 per AutoMapper – mhenrixon

+0

Anche +1 per AutoMapper. Il "Getting Started" è quasi esattamente lo scenario dell'OP. http://automapper.codeplex.com/wikipage?title=Getting%20Started&referringTitle=Documentation Utilizziamo un metodo di estensione che consente di eseguire questa operazione: var playerDto = player.MapTo (); –

0

È ancora necessario eseguire il codice per creare l'oggetto DTO, ma è possibile sovraccaricare l'operatore di cast per eseguire il cast dall'oggetto di implementazione all'oggetto DTO. Puoi persino fare un cast implicito.

vedere overloading cast e implicit

0

È possibile utilizzare explicit conversioni di tipo.

public sealed class Player { 
    public static explicit operator PlayerDTO(Player p) { 
    PlayerDTO dto; 
    // construct 
    return dto; 
    } 
} 

public sealed class PlayerDTO { 
    public static explicit operator Player(PlayerDTO dto) { 
    Player p; 
    // construct 
    return p; 
    } 
} 
0

Suona come si dovrebbe utilizzare un'interfaccia.

poi gettato all'interfaccia: Esempio di sotto

public interface IPlayer 
{ 
    string Name { get; set; } 
} 
public class Player : IPlayer 
{ 
    string Name { get; set; } 
} 

IPlayer playerDto = player as IPlayer; 
Player player = Player(playerDto); 

Si potrebbe quindi utilizzare iPlayer Come l'oggetto DTO. Presumo che ciò sia dovuto al fatto che la classe Player non esiste nell'altro assembly e non si desidera utilizzarla di più. È quindi possibile utilizzare IPlayer in un assieme condiviso ... per trasferire tra gli assiemi.

Spero che questo aiuti ... ;-)

Aggiornamento

#

il Mapper Auto è una rotta migliore! Penso che