代码之家  ›  专栏  ›  技术社区  ›  Felan

构造函数或显式转换

  •  4
  • Felan  · 技术社区  · 14 年前

    在使用linq to sql时,我创建了一个单独的类来将数据传送到web页面。为了简化这些ferry对象的创建,我要么使用专门的构造函数,要么使用显式转换运算符。我有两个问题。

    首先,从可读性的角度来看,哪种方法更好?

    其次,虽然生成的clr代码对我来说似乎是相同的,但是在某些情况下,编译器会对其中一个代码进行不同的处理(在lambda或类似代码中)。

    示例代码(databasefoo使用专用构造函数,businessfoo使用显式运算符):

    public class DatabaseFoo
    {
        private static int idCounter; // just to help with generating data
        public int Id { get; set; }
        public string Name { get; set; }
    
        public DatabaseFoo()
        {
            Id = idCounter++;
            Name = string.Format("Test{0}", Id);
        }
        public DatabaseFoo(BusinessFoo foo)
        {
            this.Id = foo.Id;
            this.Name = foo.Name;
        }
    }
    
    public class BusinessFoo
    {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public static explicit operator BusinessFoo(DatabaseFoo foo)
        {
            return FromDatabaseFoo(foo);
        }
    
    
        public static BusinessFoo FromDatabaseFoo(DatabaseFoo foo)
        {
            return new BusinessFoo {Id = foo.Id, Name = foo.Name};
        }
    }
    
    public class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Creating the initial list of DatabaseFoo");
            IEnumerable<DatabaseFoo> dafoos = new List<DatabaseFoo>() { new DatabaseFoo(), new DatabaseFoo(), new DatabaseFoo(), new DatabaseFoo(), new DatabaseFoo(), new DatabaseFoo()};
    
            foreach(DatabaseFoo dafoo in dafoos)
                Console.WriteLine(string.Format("{0}\t{1}", dafoo.Id, dafoo.Name));
    
            Console.WriteLine("Casting the list of DatabaseFoo to a list of BusinessFoo");
            IEnumerable<BusinessFoo> bufoos = from x in dafoos
                                              select (BusinessFoo) x;
    
            foreach (BusinessFoo bufoo in bufoos)
                Console.WriteLine(string.Format("{0}\t{1}", bufoo.Id, bufoo.Name));
    
            Console.WriteLine("Creating a new list of DatabaseFoo by calling the constructor taking BusinessFoo");
            IEnumerable<DatabaseFoo> fufoos = from x in bufoos
                                             select new DatabaseFoo(x);
    
            foreach(DatabaseFoo fufoo in fufoos)
                Console.WriteLine(string.Format("{0}\t{1}", fufoo.Id, fufoo.Name));
        }
    }
    
    2 回复  |  直到 14 年前
        1
  •  6
  •   Jon Skeet    14 年前

    我不太喜欢大部分的转换——无论是显式的还是隐式的。相同的语法: (TypeName) expression 用于各种不同类型的转换,如果知道编译器正在应用哪种类型,可能会有点混乱。

    静态工厂方法,如 FromDatabaseFoo 很好-而且您可能还希望有一个 ToBusinessFoo DatabaseFoo . 在我看来,这两种转换都比用户定义的转换更清晰。

    (这并不是说自定义转换是 总是 一个坏主意,当心。我只是对他们总的来说很谨慎。)

        2
  •  2
  •   Darin Dimitrov    14 年前

    我建议你看看 AutoMapper . 它将使您的代码更加清晰,并分离这些对象之间的映射,从而使它们独立并更可重用。