Конструктор или Явное приведение - PullRequest
4 голосов
/ 10 апреля 2010

При работе с Linq to Sql я создаю отдельный класс для передачи данных на веб-страницу. Чтобы упростить создание этих объектов парома, я использую либо специализированный конструктор, либо явный оператор преобразования. У меня два вопроса.

Во-первых, какой подход лучше с точки зрения читабельности?

Во-вторых, хотя генерируемый код clr ​​мне показался одинаковым, существуют ли ситуации, когда компилятором (в лямбда-коде или тому подобном) один из них будет трактоваться иначе, чем другой.

Пример кода (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 ]

6 голосов
/ 10 апреля 2010

Я не большой поклонник конверсий по большей части - будь то явных или неявных. Тот же синтаксис: (TypeName) expression используется для различных преобразований, и может быть немного странно знать, к какому типу применяется компилятор.

Статический фабричный метод, такой как FromDatabaseFoo, хорош, и вы можете также захотеть иметь метод экземпляра ToBusinessFoo для DatabaseFoo. На мой взгляд, оба они более понятны, чем пользовательские преобразования.

(Это не значит, что пользовательские преобразования всегда плохая идея, заметьте. Я просто опасаюсь их вообще.)

2 голосов
/ 10 апреля 2010

Я бы порекомендовал вам посмотреть AutoMapper . Это сделает ваш код более понятным и разделит отображение между этими объектами, что сделает их независимыми и более пригодными для повторного использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...