构造函数或显式强制转换

Fel*_*lan 4 c# linq linq-to-sql

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

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

第二,虽然生成的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));
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 6

在大多数情况下,我并不是转换的忠实粉丝 - 无论是明确的还是隐含的.相同的语法:(TypeName) expression用于各种不同类型的转换,并且知道编译器应用哪种类型会让人感到有些困惑.

像静态工厂方法FromDatabaseFoo好-你可能还需要有一个实例方法ToBusinessFooDatabaseFoo.在我看来,这两者都比用户定义的转换更清晰.

(这并不是说自定义转换总是一个坏主意,请注意.一般来说,我只是对它们保持警惕.)

  • @Felan:你总是可以把它作为DatabaseFoo上的*extension*方法......所以DatabaseFoo本身并不知道它,但看起来确实如此.说实话,构造函数或静态方法不会打扰我.静态方法具有一些优点,例如能够缓存或返回null,以及具有消除模糊参数的名称.构造函数更典型. (2认同)