Reputation: 151
I have a constructor something like the following:
using Microsoft.Data.Extensions;
public class Complaint
{
public int Id {get; set;}
public int Transcript {get; set;}
//... etc. ... Lots more properties
public Complaint(int id)
{
var command = dataContext.CreateStoreCommand(
"dbo.stp_Complaint_Get",
CommandType.StoredProcedure,
new SqlParameter("Id", id));
var complaint = command.Materialize(x =>
new Complaint
{
Id = x.Field<int>("Id"),
Transcript = x.Field<string>("Transcript");
//... etc. ... Lots more fields from db
}
this.Id = complaint.Id;
this.Transcript = complaint.Transcript;
//... etc. ... Lots more properties to set
}
}
Is there a syntax in C# that would allow me to carry out the last part in one step instead of two? i.e. conceptually something like this:
this = command.Materialize(x =>
new Complaint
{
Id = x.Field<int>("Id"),
Transcript = x.Field<string>("Transcript");
}
Upvotes: 0
Views: 749
Reputation: 10552
Have the complaint object as a member variable and the get/set properties accesses the underlying complaint's properties?
Upvotes: 0
Reputation: 3655
I gather that you're trying to avoid setting all of those properties twice, because any change to the structure requires you to update the properties in two places, is that correct?. You could try to use some reflection to copy the properties from one instance to another.
var complaint = command.Materialize(x =>
new Complaint
{
Id = x.Field<int>("Id"),
Transcript = x.Field<string>("Transcript");
//... etc. ... Lots more fields from db
}
foreach (var prop in typeof(Complaint).GetProperties())
...
Upvotes: 0
Reputation: 6081
I believe you may try something like this:
var currentInstance = this;
var complaint = command.Materialize(x =>
new Complaint
{
Id = currentInstance.Id = x.Field("Id"),
Transcript = currentInstance.Transcript = x.Field("Transcript");
//... etc. ... Lots more fields from db
});
I don't think you can capture this in the closure, so using that currentInstance trick should help, however it may as well turn out to be redundant. Besides, code such as that one is sort of obfuscated compared to your current solution. I believe that your code is pretty fine as it is.
Upvotes: 0
Reputation: 1500913
Well, you could use a static method instead of a constructor:
public static Complaint FromId(int id)
{
var command = dataContext.CreateStoreCommand(
"dbo.stp_Complaint_Get",
CommandType.StoredProcedure,
new SqlParameter("Id", id));
return command.Materialize(x =>
new Complaint
{
Id = x.Field<int>("Id"),
Transcript = x.Field<string>("Transcript");
//... etc. ... Lots more fields from db
});
}
Upvotes: 3
Reputation: 46118
Not inherently. You could store the complaint object inside the class, and have all the properties point off that rather than setting them all from the constructor.
eg
public class Complaint
{
private readonly {type of complaint} m_Complaint;
public int Id
{
get { return m_Complaint.Id; }
}
// ...etc
}
You could get more complicated if you don't have a setter on m_Complaint - keeping nullable backing fields, and check that before you access the m_Complaint properties
Upvotes: 0