【问题标题】:How to control Type conversion in C#如何在 C# 中控制类型转换
【发布时间】:2011-01-13 13:56:43
【问题描述】:

有没有办法控制 C# 中的类型转换?例如,如果我有两种类型的细节基本相同,但一种用于我的应用程序的内部工作,另一种是用于与非 .Net 应用程序通信的 DTO:

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; }
}

现在,我每次都需要从我的 Player 实例创建一个新的 PlayerDTO 实例,并且我正在寻找一种更好、更清洁的方法来执行此操作。 我的一个想法是向播放器类添加一个 AsPlayerDTO() 方法,但如果我可以控制类型转换过程,这样我就可以这样做了:

var playerDto = player as PlayerDTO; 

任何人都知道这是否可能以及我如何能够做到这一点?

谢谢,

【问题讨论】:

    标签: c# .net types type-conversion


    【解决方案1】:

    您可以实现隐式或显式类型转换:http://msdn.microsoft.com/en-us/library/ms173105.aspx

    或者,如果您想避免让每个类都必须了解其他类,您可以使用自定义映射或现有映射库,如 AutoMapper

    【讨论】:

    • 重载隐式/显式运算符似乎对我有用,而且它也相当干净。奇怪的是,这不适用于数组,但 AutoMapper 似乎根据下面 Michael Meadows 的评论提供了该选项。有没有办法在不使用 AutoMapper 之类的第三个扩展的情况下实现这一点?
    • 没关系,在另一个 stackoverflow 问题 stackoverflow.com/questions/1865031/… Array.ConvertAll(playerList.ToArray(), p => (PlayerDTO)p) 上找到了我第二个问题的答案;
    • 另外,如果你使用的是 Linq,你可以使用 Select... playerArray.Select(player => (PlayerDTO) player).ToArray();
    【解决方案2】:

    转换运算符呢:

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

    【讨论】:

      【解决方案3】:

      您可以在这两种类型之间实现explicit convesion operator

      您也可以考虑使用AutoMapper 来完成任务。

      【讨论】:

      • AutoMapper 也是 +1。 “入门”几乎正是 OP 的场景。 automapper.codeplex.com/… 我们使用了一个扩展方法,允许你这样做: var playerDto = player.MapTo();
      【解决方案4】:

      您仍然需要编写代码来创建 DTO 对象,但您可以重载强制转换运算符以从您的实现对象强制转换为 DTO 对象。你甚至可以进行隐式转换。

      overloading castimplicit

      【讨论】:

        【解决方案5】:

        您可以使用explicit 类型转换。

        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;
          }
        }
        

        【讨论】:

          【解决方案6】:

          【讨论】:

            【解决方案7】:

            听起来你应该使用接口。

            然后投射到界面上:示例如下

            public interface IPlayer 
            {
               string Name { get; set; }
            }
            public class Player : IPlayer 
            {
               string Name { get; set; }
            }
            
            IPlayer playerDto = player as IPlayer;
            Player player = Player(playerDto);
            

            然后您将使用 IPlayer 作为 DTO 对象。 我认为这是因为 Player 类在其他程序集中不存在,并且您不想更多。然后,您可以在共享程序集中使用 IPlayer...在程序集之间传输。

            希望这会有所帮助... ;-)

            更新

            #

            Auto Mapper 是一条更好的路线!我觉得

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-01-09
              • 1970-01-01
              • 2010-10-19
              • 1970-01-01
              相关资源
              最近更新 更多