In working with Linq to Sql I create a seperate class to ferry data to a web page. To simplify creating these ferry objects I either use a specialized constructor or an explicit conversion operator. I have two questions.
First which approach is better from a readibility perspective?
Second while the clr code that is generated appeared to be the same to me, are there situations where one would be treated different than the other by the compiler (in lambda's or such).
Example code (DatabaseFoo uses specialized constructor and BusinessFoo uses explicit operator):
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));
}
}
I'm not a big fan of conversions for the most part - whether explicit or implicit. The same syntax: (TypeName) expression
is used for various different kinds of conversion, and it can get a bit confusing to know which type the compiler is applying.
A static factory method like FromDatabaseFoo
is good - and you might also want to have an instance method of ToBusinessFoo
on DatabaseFoo
. Both of these are clearer than user-defined conversions in my view.
(That's not to say that custom conversions are always a bad idea, mind you. I'm just wary of them in general.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With