How to implement and extend Joshua's builder pattern in .net? - c#

How can we implement the Builder
pattern of Joshua's
Effective Java in C#?
Below is the code I have tried, is there a better way to do this?
public class NutritionFacts
{
public static NutritionFacts.Builder Build(string name, int servingSize, int servingsPerContainer)
{
return new NutritionFacts.Builder(name, servingSize, servingsPerContainer);
}
public sealed class Builder
{
public Builder(String name, int servingSize,
int servingsPerContainer)
{
}
public Builder totalFat(int val) { }
public Builder saturatedFat(int val) { }
public Builder transFat(int val) { }
public Builder cholesterol(int val) { }
//... 15 more setters
public NutritionFacts build()
{
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder) { }
protected NutritionFacts() { }
}
How do we extend such a class? Do
we need to write separate builder
classes for each of the derived
classes?
public class MoreNutritionFacts : NutritionFacts
{
public new static MoreNutritionFacts.Builder Build(string name, int servingSize, int servingsPerContainer)
{
return new MoreNutritionFacts.Builder(name, servingSize, servingsPerContainer);
}
public new sealed class Builder
{
public Builder(String name, int servingSize,
int servingsPerContainer) {}
public Builder totalFat(int val) { }
public Builder saturatedFat(int val) { }
public Builder transFat(int val) { }
public Builder cholesterol(int val) { }
//... 15 more setters
public Builder newProperty(int val) { }
public MoreNutritionFacts build()
{
return new MoreNutritionFacts(this);
}
}
private MoreNutritionFacts(MoreNutritionFacts.Builder builder) { }
}

In Protocol Buffers, we implement the builder pattern like this (vastly simplified):
public sealed class SomeMessage
{
public string Name { get; private set; }
public int Age { get; private set; }
// Can only be called in this class and nested types
private SomeMessage() {}
public sealed class Builder
{
private SomeMessage message = new SomeMessage();
public string Name
{
get { return message.Name; }
set { message.Name = value; }
}
public int Age
{
get { return message.Age; }
set { message.Age = value; }
}
public SomeMessage Build()
{
// Check for optional fields etc here
SomeMessage ret = message;
message = null; // Builder is invalid after this
return ret;
}
}
}
This isn't quite the same as the pattern in EJ2, but:
No data copying is required at build time. In other words, while you're setting the properties, you're doing so on the real object - you just can't see it yet. This is similar to what StringBuilder does.
The builder becomes invalid after calling Build() to guarantee immutability. This unfortunately means it can't be used as a sort of "prototype" in the way that the EJ2 version can.
We use properties instead of getters and setters, for the most part - which fits in well with C# 3's object initializers.
We do also provide setters returning this for the sake of pre-C#3 users.
I haven't really looked into inheritance with the builder pattern - it's not supported in Protocol Buffers anyway. I suspect it's quite tricky.

This blog entry might be of interest
A neat variation on the pattern in C# is the use of an implicit cast operator to make the final call to Build() unnecessary:
public class CustomerBuilder
{
......
public static implicit operator Customer( CustomerBuilder builder )
{
return builder.Build();
}
}

Edit: I used this again and simplified it to remove the redundant value-checking in setters.
I recently implemented a version that is working out nicely.
Builders are factories which cache the most recent instance. Derived builders create instances and clear the cache when anything changes.
The base class is straightforward:
public abstract class Builder<T> : IBuilder<T>
{
public static implicit operator T(Builder<T> builder)
{
return builder.Instance;
}
private T _instance;
public bool HasInstance { get; private set; }
public T Instance
{
get
{
if(!HasInstance)
{
_instance = CreateInstance();
HasInstance = true;
}
return _instance;
}
}
protected abstract T CreateInstance();
public void ClearInstance()
{
_instance = default(T);
HasInstance = false;
}
}
The problem we are solving is more subtle. Let's say we have the concept of an Order:
public class Order
{
public string ReferenceNumber { get; private set; }
public DateTime? ApprovedDateTime { get; private set; }
public void Approve()
{
ApprovedDateTime = DateTime.Now;
}
}
ReferenceNumber does not change after creation, so we model it read-only via the constructor:
public Order(string referenceNumber)
{
// ... validate ...
ReferenceNumber = referenceNumber;
}
How do we reconstitute an existing conceptual Order from, say, database data?
This is the root of the ORM disconnect: it tends to force public setters on ReferenceNumber and ApprovedDateTime for technical convenience. What was a clear truth is hidden to future readers; we could even say it is an incorrect model. (The same is true for extension points: forcing virtual removes the ability for base classes to communicate their intent.)
A Builder with special knowledge is a useful pattern. An alternative to nested types would be internal access. It enables mutability, domain behavior (POCO), and, as a bonus, the "prototype" pattern mentioned by Jon Skeet.
First, add an internal constructor to Order:
internal Order(string referenceNumber, DateTime? approvedDateTime)
{
ReferenceNumber = referenceNumber;
ApprovedDateTime = approvedDateTime;
}
Then, add a Builder with mutable properties:
public class OrderBuilder : Builder<Order>
{
private string _referenceNumber;
private DateTime? _approvedDateTime;
public override Order Create()
{
return new Order(_referenceNumber, _approvedDateTime);
}
public string ReferenceNumber
{
get { return _referenceNumber; }
set { SetField(ref _referenceNumber, value); }
}
public DateTime? ApprovedDateTime
{
get { return _approvedDateTime; }
set { SetField(ref _approvedDateTime, value); }
}
}
The interesting bit is the SetField calls. Defined by Builder, it encapsulates the pattern of "set the backing field if different, then clear the instance" that would otherwise be in the property setters:
protected bool SetField<TField>(
ref TField field,
TField newValue,
IEqualityComparer<T> equalityComparer = null)
{
equalityComparer = equalityComparer ?? EqualityComparer<TField>.Default;
var different = !equalityComparer.Equals(field, newValue);
if(different)
{
field = newValue;
ClearInstance();
}
return different;
}
We use ref to allow us to modify the backing field. We also use the default equality comparer but allow callers to override it.
Finally, when we need to reconstitute an Order, we use OrderBuilder with the implicit cast:
Order order = new OrderBuilder
{
ReferenceNumber = "ABC123",
ApprovedDateTime = new DateTime(2008, 11, 25)
};
This got really long. Hope it helps!

The reason to use Joshua Bloch's builder pattern was to create a complex object out of parts, and also to make it immutable.
In this particular case, using optional, named parameters in C# 4.0 is cleaner. You give up some flexibility in design (don't rename the parameters), but you get better maintainable code, easier.
If the NutritionFacts code is:
public class NutritionFacts
{
public int servingSize { get; private set; }
public int servings { get; private set; }
public int calories { get; private set; }
public int fat { get; private set; }
public int carbohydrate { get; private set; }
public int sodium { get; private set; }
public NutritionFacts(int servingSize, int servings, int calories = 0, int fat = 0, int carbohydrate = 0, int sodium = 0)
{
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.carbohydrate = carbohydrate;
this.sodium = sodium;
}
}
Then a client would use it as
NutritionFacts nf2 = new NutritionFacts(240, 2, calories: 100, fat: 40);
If the construction is more complex this would need to be tweaked; if the "building" of calories is more than putting in an integer, it's conceivable that other helper objects would be needed.

Related

Don't allow object to be changed

I have a read-only object but somewhere it's properties getting updated. Does C# have anything to restrict that too from direct changes as well as via reflection?
Here is the POC code
class Program
{
static void Main(string[] args)
{
ReadOnlyCreator tester = new ReadOnlyCreator();
tester.ModifyTester();
Console.ReadLine();
}
}
class ClassUnderTest
{
public string SomeProp { get; set; }
}
class ReadOnlyCreator
{
private readonly ClassUnderTest _classUnderTest;
public ReadOnlyCreator()
{
_classUnderTest = new ClassUnderTest { SomeProp = "Init" };
}
public void ModifyTester()
{
Console.WriteLine("Before: " + _classUnderTest.SomeProp);
var modifier = new Modifier(_classUnderTest);
modifier.Modify();
Console.WriteLine("After: " + _classUnderTest.SomeProp);
}
}
class Modifier
{
private ClassUnderTest _classUnderTest;
public Modifier(ClassUnderTest classUnderTest)
{
_classUnderTest = classUnderTest;
}
public void Modify()
{
_classUnderTest.SomeProp = "Modified";
}
If you want a read only object you should make it read only. i.e.
class ClassUnderTest
{
public string SomeProp { get; }
public ClassUnderTest(string someProp) => SomeProp = someProp;
}
You could also use init only setters if you are using c#9. This allow the property to be set only during construction of the object:
class ClassUnderTest
{
public string SomeProp { get; init; }
}
If you are using value types you can (and should) declare the whole type as readonly. See also Choosing Between Class and Struct
public readonly struct StructUnderTest
This does not protect against reflection or unsafe code. Using these features is deliberately circumventing the rules, so it is up to the developer to ensure it is safe.

How to combine property init and set depending on access modifier?

I want a class/record with protected set and public init access restriction?
To my knowledge this even cannot be done by explicitly implementing a "Set" interface like this:
public interface ISetData<T>
{
T Value { get; set; }
}
public class Data : ISetData<bool>
{
bool ISetData<bool>.Value { get => Value; set => Value = value; } // Error The property Value has no setter
public bool Value { get; init; }
}
Downside is, set functionality is public when using the interface. Not good. (for internal components the interface can be made internal, but that's mostly no option)
Given that only derivations of Data should be able to set data after initialization, the only solution I see is to use an backing field for the property, which is annoying.
Which looks like:
public interface ISetData<T>
{
T Value { get; set; }
}
public class Data : ISetData<bool>
{
bool ISetData<bool>.Value { get => Value; set => _value = value; } // Fine
private bool _value;
public bool Value
{
get { return _value; }
init { }
}
}
That seems odd to me. Would it not be better CLR/c# allows to use access modifiers independently of set/init this like:
public class Data
{
public bool Value { get; init; protected set; }
}
I know this would better be addressed by a feature request, but this is not what this post is about.
So what solutions are available for the scenario "public init, but protected set"?
A simple answer is none.
In C# 9.0, you could have either init or protected set, not both.
You could have a separate property that is protected set and then the public property can be based on your protected property. Example below.
using System;
public class Program
{
public static void Main()
{
var example = new Example{Test = "hello world"};
example.PrintProtectedTest();
Console.WriteLine(example.Test);
example.SetProtectedTest("goodbye world");
Console.WriteLine(example.Test);
}
}
class Example
{
public Example()
{
}
protected string ProtectedTest { get; set; }
public string Test
{
get => ProtectedTest;
init => ProtectedTest = value;
}
public void SetProtectedTest(string test)
{
ProtectedTest = test;
}
public void PrintProtectedTest()
{
Console.WriteLine(ProtectedTest);
}
}
You can run the example here https://dotnetfiddle.net/odGwDj

Assign additional attributes to types like int, float for reflection purposes

I am trying to automate the display (gathering via reflection) of my variables which are located in specific scripts in Unity. The trouble is assigning custom values (for example: "string DisplayName", "bool DisplayMe", "bool WriteMe" etc.). When it comes to my custom classes I understand how I would do it, but I would like to avoid remaking types like float, string, int etc. for this purpose.
For example, let's say I have:
public class myBaseClass
{
public string Name = "Display Name";
public bool AmReadable = true;
public bool AmWritable = true;
}
Then:
public class myDoubleFloat: myBaseClass
{
public float ValueFirst;
public float ValueSecond;
}
So in some scripts in Unity I define it:
public class SomeScriptOnGameObject : MonoBehaviour
{
public myDoubleFloat myFirstVariable{get; set;}
public float mySecondVariable{get; set;}
}
So later on with reflection I can check whether "myFirstVariable" should be read, it's display name etc. - while for "mySecondVariable" I cannot perform this check. How do I go about this without reinventing the wheel and making a class for each of these types like float, string, int, List etc.?
You can define a generic wrapper:
public class MyProperty<T>
{
private T _value;
public T Get() => _value;
public T Set(T newValue) => _value = newValue;
public string Name { get; set; }
public bool AmReadable { get; set; }
public bool AmWritable { get; set; }
}
And make your properties's getters and setter to map to some backing fields of type MyProperty<T>:
public class SomeScriptOnGameObject : MonoBehaviour
{
private MyProperty<MyDoubleFloat> _myFirstVariable;
private MyProperty<float> _mySecondVariable;
public MyDoubleFloat MyFirstVariable
{
get => _myFirstVariable.Get();
set => _myFirstVariable.Set(value);
}
public float MySecondVariable
{
get => _mySecondVariable.Get();
set => _mySecondVariable.Set(value);
}
public SomeScriptOnGameObject()
{
_myFirstVariable = new MyProperty<MyDoubleFloat>
{
//configuration
};
_mySecondVariable = new MyProperty<float>
{
//configuration
};
}
}
If you want to be fancy you can even add an implicit operator to get rid of Get() and make any T assignable from MyProperty<T>:
public class MyProperty<T>
{
private T _value;
public T Set(T newValue) => _value = newValue;
public string Name { get; set; }
public bool AmReadable { get; set; }
public bool AmWritable { get; set; }
public static implicit operator T(MyProperty<T> myProperty) =>
myProperty != null ? myProperty._value : default;
}
And:
public MyDoubleFloat MyFirstVariable
{
get => _myFirstVariable;
set => _myFirstVariable.Set(value);
}
Wrapping value objects (int, float, etc.) is probably not the best approach. Besides the additional complexity (and possibility for bugs), you are now bloating the memory footprint of your game.
(I'm intentionally avoiding newer C# syntax in these examples)
Since you are already in a reflection context, instead of wrapping your value objects, I'd suggest an attribute-based approach. For example:
public class SomeScriptOnGameObject
{
[DisplayName("First Variable"), Writable]
public float FirstVariable { get; set; }
[DisplayName("Second Variable")]
public float SecondVariable { get; set; }
[DisplayName("Some Field")]
public float Field;
public float FieldWithNoAttributes;
}
This has the advantage of keeping the metadata of the fields in the metadata, instead of carrying around a copy of everything with every instance you create.
The actual attributes are easy to create, also. I'll start with the simplest one, WritableAttribute:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public sealed class WritableAttribute : Attribute
{
}
This empty class is all that's needed to mark a field or property as "Writable". The AttributeUsage marks this as only valid on fields and properties (not, for example, a class).
The other attribute, DisplayName, is only slightly more complex:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public sealed class DisplayNameAttribute : Attribute
{
public string DisplayName { get; private set; }
public DisplayNameAttribute(string displayName)
{
DisplayName = displayName;
}
}
The main difference is the constructor with the displayName argument, and the DisplayName property. This forces the compiler to expect an argument to the attribute.
With some extension methods, you can make things very clean:
public static class AttributeExtensions
{
public static bool IsWritable(this MemberInfo memberInfo)
{
return memberInfo.GetCustomAttributes(typeof(WritableAttribute)).Any();
}
public static string DisplayName(this MemberInfo memberInfo)
{
var displayNameAttribute =
memberInfo.GetCustomAttributes(typeof(DisplayNameAttribute))
.FirstOrDefault() as DisplayNameAttribute;
return displayNameAttribute == null ? null : displayNameAttribute.DisplayName;
}
public static PropertyInfo Property<T>(this T _, string propertyName)
{
return typeof(T).GetProperty(propertyName);
}
public static FieldInfo Field<T>(this T _, string fieldName)
{
return typeof(T).GetField(fieldName);
}
}
(Since you mentioned you are already using reflection, you might not need the last two methods there.)
Finally, a simple XUnit test to demonstrate:
public class UnitTest1
{
[Fact]
public void Test1()
{
var obj = new SomeScriptOnGameObject();
Assert.True(obj.Property("FirstVariable").IsWritable());
Assert.False(obj.Property("SecondVariable").IsWritable());
Assert.False(obj.Field("Field").IsWritable());
Assert.Equal("First Variable", obj.Property("FirstVariable").DisplayName());
Assert.Equal("Second Variable", obj.Property("SecondVariable").DisplayName());
Assert.Equal("Some Field", obj.Field("Field").DisplayName());
Assert.Null(obj.Field("FieldWithNoAttributes").DisplayName());
}
}

Generic Value Object in C#

I have a VO class that contains several variables incl. a variable that can be of different types and to prevent casting later on I wonder if I can make that class generic.
public class InputVO<T>
{
public bool isEnabled;
public T value;
}
Then I want to create an array of InputVOs and a method to get a typed InputVO...
public InputVO[] Inputs { get; private set; }
public InputVO GetInput(InputType type)
{
return Inputs[(int)type];
}
How do I go about defining the array and the GetInput method so that they work with the generic InputVO? (The InputType type argument is an enum. Shouldn't really matter here, I think).
Generic type parameters are fixed at compile-time.
Whenever you use InputVO, that type parameter needs to be filled in.
public InputVO<T1>[] Inputs { get; private set; }
But what you seem to want is different InputVO objects for each datatype, and to be able to retrieve them by type at runtime:
// Base class for all InputVOs
public abstract InputVOBase
{
public bool isEnabled;
}
// InputVO for a specific data-type
public class InputVO<T> : InputVOBase
{
public T Value;
}
Now you can use a dictionary from Type to InputVOBase.
// One InputVO per datatype
public Dictionary<Type, InputVOBase> AllInputs { get; private set; }
// Return the VO for type T, or null
public InputVO<T> GetInput<T>()
{
InputVOBase vo = AllInputs[typeof(T)];
return (vo as InputVO<T>);
}
You cannot create an array of a generic class without specifying the type. However, as you have control over the base type, you can make that implement a non generic interface and have a collection of that instead:
//Empty interface
public interface IInputVO { }
//Your generic class now implements the interface
public class InputVO<T> : IInputVO
{
public bool isEnabled { get; set; }
public T Value { get; set; }
}
So now your array is of the interface type IInputVO:
IInputVO[] inputs =
{
new InputVO<int>(),
new InputVO<string>(),
new InputVO<SomeClass>(),
};
Cleaned up solution a bit. Mainly you need to collect your values in a dictionary.
void Main()
{
var a = new InputVO<string> { Value = "test" };
var b = new InputVO<int> { Value = 5 };
Inputs.Add(typeof(string), a);
Inputs.Add(typeof(int), b);
var x = GetInput<string>();
Console.WriteLine(x.Value);
var y = GetInput<int>();
Console.WriteLine(y.Value);
}
public abstract class InputVOBase
{
public bool isEnabled;
}
public class InputVO<T> : InputVOBase
{
public T Value;
}
public Dictionary<Type, InputVOBase> Inputs = new Dictionary<Type, InputVOBase>();
public InputVO<T> GetInput<T>()
{
return Inputs[typeof(T)] as InputVO<T>;
}
Thanks for the tips anyone! Phew, since there's no way getting around casting and I only need to regard a couple of types I think all the generics-based solutions are a bit overkill in my case. So I simply added casted getters to my VO ...
public class InputVO
{
public bool isEnabled;
public bool isValid;
public InputType type;
public object value;
public int IntValue { get { return (int)value; } }
public float FloatValue { get { return (float)value; } }
public bool BoolValue { get { return (bool)value; } }
public Vector2 Vector2Value { get { return (Vector2) value; } }
public Vector3 Vector3Value { get { return (Vector3)value; } }
}

C# - copying property values from one instance to another, different classes

I have two C# classes that have many of the same properties (by name and type). I want to be able to copy all non-null values from an instance of Defect into an instance of DefectViewModel. I was hoping to do it with reflection, using GetType().GetProperties(). I tried the following:
var defect = new Defect();
var defectViewModel = new DefectViewModel();
PropertyInfo[] defectProperties = defect.GetType().GetProperties();
IEnumerable<string> viewModelPropertyNames =
defectViewModel.GetType().GetProperties().Select(property => property.Name);
IEnumerable<PropertyInfo> propertiesToCopy =
defectProperties.Where(defectProperty =>
viewModelPropertyNames.Contains(defectProperty.Name)
);
foreach (PropertyInfo defectProperty in propertiesToCopy)
{
var defectValue = defectProperty.GetValue(defect, null) as string;
if (null == defectValue)
{
continue;
}
// "System.Reflection.TargetException: Object does not match target type":
defectProperty.SetValue(viewModel, defectValue, null);
}
What would be the best way to do this? Should I maintain separate lists of Defect properties and DefectViewModel properties so that I can do viewModelProperty.SetValue(viewModel, defectValue, null)?
Edit: thanks to both Jordão's and Dave's answers, I chose AutoMapper. DefectViewModel is in a WPF application, so I added the following App constructor:
public App()
{
Mapper.CreateMap<Defect, DefectViewModel>()
.ForMember("PropertyOnlyInViewModel", options => options.Ignore())
.ForMember("AnotherPropertyOnlyInViewModel", options => options.Ignore())
.ForAllMembers(memberConfigExpr =>
memberConfigExpr.Condition(resContext =>
resContext.SourceType.Equals(typeof(string)) &&
!resContext.IsSourceValueNull
)
);
}
Then, instead of all that PropertyInfo business, I just have the following line:
var defect = new Defect();
var defectViewModel = new DefectViewModel();
Mapper.Map<Defect, DefectViewModel>(defect, defectViewModel);
Take a look at AutoMapper.
There are frameworks for this, the one I know of is Automapper:
http://automapper.codeplex.com/
http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/01/22/automapper-the-object-object-mapper.aspx
Replace your erroneous line with this:
PropertyInfo targetProperty = defectViewModel.GetType().GetProperty(defectProperty.Name);
targetProperty.SetValue(viewModel, defectValue, null);
Your posted code is attempting to set a Defect-tied property on a DefectViewModel object.
In terms of organizing the code, if you don't want an external library like AutoMapper, you can use a mixin-like scheme to separate the code out like this:
class Program {
static void Main(string[] args) {
var d = new Defect() { Category = "bug", Status = "open" };
var m = new DefectViewModel();
m.CopyPropertiesFrom(d);
Console.WriteLine("{0}, {1}", m.Category, m.Status);
}
}
// compositions
class Defect : MPropertyGettable {
public string Category { get; set; }
public string Status { get; set; }
// ...
}
class DefectViewModel : MPropertySettable {
public string Category { get; set; }
public string Status { get; set; }
// ...
}
// quasi-mixins
public interface MPropertyEnumerable { }
public static class PropertyEnumerable {
public static IEnumerable<string> GetProperties(this MPropertyEnumerable self) {
return self.GetType().GetProperties().Select(property => property.Name);
}
}
public interface MPropertyGettable : MPropertyEnumerable { }
public static class PropertyGettable {
public static object GetValue(this MPropertyGettable self, string name) {
return self.GetType().GetProperty(name).GetValue(self, null);
}
}
public interface MPropertySettable : MPropertyEnumerable { }
public static class PropertySettable {
public static void SetValue<T>(this MPropertySettable self, string name, T value) {
self.GetType().GetProperty(name).SetValue(self, value, null);
}
public static void CopyPropertiesFrom(this MPropertySettable self, MPropertyGettable other) {
self.GetProperties().Intersect(other.GetProperties()).ToList().ForEach(
property => self.SetValue(property, other.GetValue(property)));
}
}
This way, all the code to achieve the property-copying is separate from the classes that use it. You just need to reference the mixins in their interface list.
Note that this is not as robust or flexible as AutoMapper, because you might want to copy properties with different names or just some sub-set of the properties. Or it might downright fail if the properties don't provide the necessary getters or setters or their types differ. But, it still might be enough for your purposes.
This is cheap and easy. It makes use of System.Web.Script.Serialization and some extention methods for ease of use:
public static class JSONExts
{
public static string ToJSON(this object o)
{
var oSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
return oSerializer.Serialize(o);
}
public static List<T> FromJSONToListOf<T>(this string jsonString)
{
var oSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
return oSerializer.Deserialize<List<T>>(jsonString);
}
public static T FromJSONTo<T>(this string jsonString)
{
var oSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
return oSerializer.Deserialize<T>(jsonString);
}
public static T1 ConvertViaJSON<T1>(this object o)
{
return o.ToJSON().FromJSONTo<T1>();
}
}
Here's some similiar but different classes:
public class Member
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsCitizen { get; set; }
public DateTime? Birthday { get; set; }
public string PetName { get; set; }
public int PetAge { get; set; }
public bool IsUgly { get; set; }
}
public class MemberV2
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsCitizen { get; set; }
public DateTime? Birthday { get; set; }
public string ChildName { get; set; }
public int ChildAge { get; set; }
public bool IsCute { get; set; }
}
And here's the methods in action:
var memberClass1Obj = new Member {
Name = "Steve Smith",
Age = 25,
IsCitizen = true,
Birthday = DateTime.Now.AddYears(-30),
PetName = "Rosco",
PetAge = 4,
IsUgly = true,
};
string br = "<br /><br />";
Response.Write(memberClass1Obj.ToJSON() + br); // just to show the JSON
var memberClass2Obj = memberClass1Obj.ConvertViaJSON<MemberV2>();
Response.Write(memberClass2Obj.ToJSON()); // valid fields are filled
For one thing I would not place that code (somewhere) external but in the constructor of the ViewModel:
class DefectViewModel
{
public DefectViewModel(Defect source) { ... }
}
And if this is the only class (or one of a few) I would not automate it further but write out the property assignments. Automating it looks nice but there may be more exceptions and special cases than you expect.
Any chance you could have both classes implement an interface that defines the shared properties?

Categories

Resources