C# How to create special instances of a class? - c#

For some classes, ideally, I'd like to create special named instances, similar to "null." As far as I know, that's not possible, so instead, I create static instances of the class, with a static constructor, similar to this:
public class Person
{
public static Person Waldo; // a special well-known instance of Person
public string name;
static Person() // static constructor
{
Waldo = new Person("Waldo");
}
public Person(string name)
{
this.name = name;
}
}
As you can see, Person.Waldo is a special instance of the Person class, which I created because in my program, there are a lot of other classes that might want to refer to this special well-known instance.
The downside of implementing this way is that I don't know any way to make all the properties of Person.Waldo immutable, while all the properties of a "normal" Person instance should be mutable. Whenever I accidentally have a Person object referring to Waldo, and I carelessly don't check to see if it's referring to Waldo, then I accidentally clobber Waldo's properties.
Is there a better way, or even some additional alternative ways, to define special well-known instances of a class?
The only solution I know right now, is to implement the get & set accessors, and check "if ( this == Waldo) throw new ..." on each and every set. While this works, I assume C# can do a better job than me of implementing it. If only I can find some C# way to make all the properties of Waldo readonly (except during static constructor.)

Make a private class inside the Person that inherits the Person, ImmutablePerson : Person.
Make all the property setters locked up: override them with NotImplementedException for instance.
Your static Person initialization becomes this:
public static readonly Person Waldo = new ImmutablePerson("Waldo");
And static constructor may be removed, too.

Maybe you could have the following hierarchy:
class Person
{
protected string _name;
public virtual string Name{
get{
return _name;
}
}
}
class EditablePerson:Person
{
public new string Name{
get{
return _name;
}
set{
_name=value;
}
}
public Person AsPerson()
{
//either return this (and simply constrain by interface)
//or create an immutable copy
}
}

In my opinion the best is to return always a new instance on Waldo. This way the original Waldo will never be changed. But this will prevent you from using reference equality for comparison, therefore you will have to override Equals and GetHashCode.

Thanks to all your suggestions - Here is the solution. I needed to make string virtual, override the accessors in a public derivative class, and use a bool flag to permit modification.
It's important to note, that "name" is a reference type, and although I've prevented changing what "name" refers to, if it were something other than a string, such as a class that contains a self-modification method, it could still be possible to modify the contents of the object, despite having prevented modification to the object reference.
class Program
{
static void Main(string[] args)
{
Person myPerson = new Person("Wenda");
System.Console.WriteLine("myPerson is " + myPerson.name); // Prints "myPerson is Wenda"
if (myPerson == Person.Waldo)
System.Console.WriteLine("Found Waldo (first attempt)"); // doesn't happen
else
System.Console.WriteLine("Still trying to find Waldo..."); // Prints "Still trying to find Waldo..."
myPerson.name = "Bozo";
System.Console.WriteLine("myPerson is now " + myPerson.name); // Prints "myPerson is now Bozo"
myPerson = Person.Waldo;
if (myPerson == Person.Waldo)
System.Console.WriteLine("Found Waldo (second attempt)"); // Prints "Found Waldo (second attempt)"
System.Console.WriteLine("myPerson is " + myPerson.name); // Prints "myPerson is Waldo"
System.Console.WriteLine("Now changing to The Joker..."); // Prints "Now changing to The Joker"
try
{
myPerson.name = "The Joker"; // throws ImmutablePersonModificationAttemptException
}
catch (ImmutablePersonModificationAttemptException)
{
System.Console.WriteLine("Failed to change"); // Prints "Failed to change"
}
System.Console.WriteLine("myPerson is now " + myPerson.name); // Prints "myPerson is now Waldo"
Thread.Sleep(int.MaxValue); // keep the console alive long enough for me to see the result.
}
}
public class Person
{
public static readonly ImmutablePerson Waldo = new ImmutablePerson("Waldo");
public virtual string name { get; set; }
public Person() // empty base constructor required by ImmutablePerson(string) constructor
{ }
public Person(string name)
{
this.name = name;
}
}
public class ImmutablePersonModificationAttemptException : Exception
{ }
public class ImmutablePerson : Person
{
private bool allowMutation;
protected string _name;
public override string name
{
get
{
return _name;
}
set
{
if (allowMutation)
_name = value;
else
throw new ImmutablePersonModificationAttemptException();
}
}
public ImmutablePerson(string name)
: base()
{
allowMutation = true;
this.name = name;
allowMutation = false;
}
}

Related

Auto-property initialization [duplicate]

How do you give a C# auto-property an initial value?
I either use the constructor, or revert to the old syntax.
Using the Constructor:
class Person
{
public Person()
{
Name = "Initial Name";
}
public string Name { get; set; }
}
Using normal property syntax (with an initial value)
private string name = "Initial Name";
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
Is there a better way?
In C# 5 and earlier, to give auto implemented properties an initial value, you have to do it in a constructor.
Since C# 6.0, you can specify initial value in-line. The syntax is:
public int X { get; set; } = x; // C# 6 or higher
DefaultValueAttribute is intended to be used by the VS designer (or any other consumer) to specify a default value, not an initial value. (Even if in designed object, initial value is the default value).
At compile time DefaultValueAttribute will not impact the generated IL and it will not be read to initialize the property to that value (see DefaultValue attribute is not working with my Auto Property).
Example of attributes that impact the IL are ThreadStaticAttribute, CallerMemberNameAttribute, ...
Edited on 1/2/15
C# 6 :
With C# 6 you can initialize auto-properties directly (finally!), there are now other answers that describe that.
C# 5 and below:
Though the intended use of the attribute is not to actually set the values of the properties, you can use reflection to always set them anyway...
public class DefaultValuesTest
{
public DefaultValuesTest()
{
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
{
DefaultValueAttribute myAttribute = (DefaultValueAttribute)property.Attributes[typeof(DefaultValueAttribute)];
if (myAttribute != null)
{
property.SetValue(this, myAttribute.Value);
}
}
}
public void DoTest()
{
var db = DefaultValueBool;
var ds = DefaultValueString;
var di = DefaultValueInt;
}
[System.ComponentModel.DefaultValue(true)]
public bool DefaultValueBool { get; set; }
[System.ComponentModel.DefaultValue("Good")]
public string DefaultValueString { get; set; }
[System.ComponentModel.DefaultValue(27)]
public int DefaultValueInt { get; set; }
}
When you inline an initial value for a variable it will be done implicitly in the constructor anyway.
I would argue that this syntax was best practice in C# up to 5:
class Person
{
public Person()
{
//do anything before variable assignment
//assign initial values
Name = "Default Name";
//do anything after variable assignment
}
public string Name { get; set; }
}
As this gives you clear control of the order values are assigned.
As of C#6 there is a new way:
public string Name { get; set; } = "Default Name";
Sometimes I use this, if I don't want it to be actually set and persisted in my db:
class Person
{
private string _name;
public string Name
{
get
{
return string.IsNullOrEmpty(_name) ? "Default Name" : _name;
}
set { _name = value; }
}
}
Obviously if it's not a string then I might make the object nullable ( double?, int? ) and check if it's null, return a default, or return the value it's set to.
Then I can make a check in my repository to see if it's my default and not persist, or make a backdoor check in to see the true status of the backing value, before saving.
In C# 6.0 this is a breeze!
You can do it in the Class declaration itself, in the property declaration statements.
public class Coordinate
{
public int X { get; set; } = 34; // get or set auto-property with initializer
public int Y { get; } = 89; // read-only auto-property with initializer
public int Z { get; } // read-only auto-property with no initializer
// so it has to be initialized from constructor
public Coordinate() // .ctor()
{
Z = 42;
}
}
Starting with C# 6.0, We can assign default value to auto-implemented properties.
public string Name { get; set; } = "Some Name";
We can also create read-only auto implemented property like:
public string Name { get; } = "Some Name";
See: C# 6: First reactions , Initializers for automatically implemented properties - By Jon Skeet
In Version of C# (6.0) & greater, you can do :
For Readonly properties
public int ReadOnlyProp => 2;
For both Writable & Readable properties
public string PropTest { get; set; } = "test";
In current Version of C# (7.0), you can do : (The snippet rather displays how you can use expression bodied get/set accessors to make is more compact when using with backing fields)
private string label = "Default Value";
// Expression-bodied get / set accessors.
public string Label
{
get => label;
set => this.label = value;
}
In C# 9.0 was added support of init keyword - very useful and extremly sophisticated way for declaration read-only auto-properties:
Declare:
class Person
{
public string Name { get; init; } = "Anonymous user";
}
~Enjoy~ Use:
// 1. Person with default name
var anonymous = new Person();
Console.WriteLine($"Hello, {anonymous.Name}!");
// > Hello, Anonymous user!
// 2. Person with assigned value
var me = new Person { Name = "#codez0mb1e"};
Console.WriteLine($"Hello, {me.Name}!");
// > Hello, #codez0mb1e!
// 3. Attempt to re-assignment Name
me.Name = "My fake";
// > Compilation error: Init-only property can only be assigned in an object initializer
In addition to the answer already accepted, for the scenario when you want to define a default property as a function of other properties you can use expression body notation on C#6.0 (and higher) for even more elegant and concise constructs like:
public class Person{
public string FullName => $"{First} {Last}"; // expression body notation
public string First { get; set; } = "First";
public string Last { get; set; } = "Last";
}
You can use the above in the following fashion
var p = new Person();
p.FullName; // First Last
p.First = "Jon";
p.Last = "Snow";
p.FullName; // Jon Snow
In order to be able to use the above "=>" notation, the property must be read only, and you do not use the get accessor keyword.
Details on MSDN
In C# 6 and above you can simply use the syntax:
public object Foo { get; set; } = bar;
Note that to have a readonly property simply omit the set, as so:
public object Foo { get; } = bar;
You can also assign readonly auto-properties from the constructor.
Prior to this I responded as below.
I'd avoid adding a default to the constructor; leave that for dynamic assignments and avoid having two points at which the variable is assigned (i.e. the type default and in the constructor). Typically I'd simply write a normal property in such cases.
One other option is to do what ASP.Net does and define defaults via an attribute:
http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx
My solution is to use a custom attribute that provides default value property initialization by constant or using property type initializer.
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class InstanceAttribute : Attribute
{
public bool IsConstructorCall { get; private set; }
public object[] Values { get; private set; }
public InstanceAttribute() : this(true) { }
public InstanceAttribute(object value) : this(false, value) { }
public InstanceAttribute(bool isConstructorCall, params object[] values)
{
IsConstructorCall = isConstructorCall;
Values = values ?? new object[0];
}
}
To use this attribute it's necessary to inherit a class from special base class-initializer or use a static helper method:
public abstract class DefaultValueInitializer
{
protected DefaultValueInitializer()
{
InitializeDefaultValues(this);
}
public static void InitializeDefaultValues(object obj)
{
var props = from prop in obj.GetType().GetProperties()
let attrs = prop.GetCustomAttributes(typeof(InstanceAttribute), false)
where attrs.Any()
select new { Property = prop, Attr = ((InstanceAttribute)attrs.First()) };
foreach (var pair in props)
{
object value = !pair.Attr.IsConstructorCall && pair.Attr.Values.Length > 0
? pair.Attr.Values[0]
: Activator.CreateInstance(pair.Property.PropertyType, pair.Attr.Values);
pair.Property.SetValue(obj, value, null);
}
}
}
Usage example:
public class Simple : DefaultValueInitializer
{
[Instance("StringValue")]
public string StringValue { get; set; }
[Instance]
public List<string> Items { get; set; }
[Instance(true, 3,4)]
public Point Point { get; set; }
}
public static void Main(string[] args)
{
var obj = new Simple
{
Items = {"Item1"}
};
Console.WriteLine(obj.Items[0]);
Console.WriteLine(obj.Point);
Console.WriteLine(obj.StringValue);
}
Output:
Item1
(X=3,Y=4)
StringValue
little complete sample:
using System.ComponentModel;
private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
get { return bShowGroup; }
set { bShowGroup = value; }
}
You can simple put like this
public sealed class Employee
{
public int Id { get; set; } = 101;
}
In the constructor. The constructor's purpose is to initialized it's data members.
private string name;
public string Name
{
get
{
if(name == null)
{
name = "Default Name";
}
return name;
}
set
{
name = value;
}
}
Have you tried using the DefaultValueAttribute or ShouldSerialize and Reset methods in conjunction with the constructor? I feel like one of these two methods is necessary if you're making a class that might show up on the designer surface or in a property grid.
Use the constructor because "When the constructor is finished, Construction should be finished". properties are like states your classes hold, if you had to initialize a default state, you would do that in your constructor.
To clarify, yes, you need to set default values in the constructor for class derived objects. You will need to ensure the constructor exists with the proper access modifier for construction where used. If the object is not instantiated, e.g. it has no constructor (e.g. static methods) then the default value can be set by the field. The reasoning here is that the object itself will be created only once and you do not instantiate it.
#Darren Kopp - good answer, clean, and correct. And to reiterate, you CAN write constructors for Abstract methods. You just need to access them from the base class when writing the constructor:
Constructor at Base Class:
public BaseClassAbstract()
{
this.PropertyName = "Default Name";
}
Constructor at Derived / Concrete / Sub-Class:
public SubClass() : base() { }
The point here is that the instance variable drawn from the base class may bury your base field name. Setting the current instantiated object value using "this." will allow you to correctly form your object with respect to the current instance and required permission levels (access modifiers) where you are instantiating it.
public Class ClassName{
public int PropName{get;set;}
public ClassName{
PropName=0; //Default Value
}
}
This is old now, and my position has changed. I'm leaving the original answer for posterity only.
Personally, I don't see the point of making it a property at all if you're not going to do anything at all beyond the auto-property. Just leave it as a field. The encapsulation benefit for these item are just red herrings, because there's nothing behind them to encapsulate. If you ever need to change the underlying implementation you're still free to refactor them as properties without breaking any dependent code.
Hmm... maybe this will be the subject of it's own question later
class Person
{
/// Gets/sets a value indicating whether auto
/// save of review layer is enabled or not
[System.ComponentModel.DefaultValue(true)]
public bool AutoSaveReviewLayer { get; set; }
}
I know this is an old question, but it came up when I was looking for how to have a default value that gets inherited with the option to override, I came up with
//base class
public class Car
{
public virtual string FuelUnits
{
get { return "gasoline in gallons"; }
protected set { }
}
}
//derived
public class Tesla : Car
{
public override string FuelUnits => "ampere hour";
}
I think this would do it for ya givng SomeFlag a default of false.
private bool _SomeFlagSet = false;
public bool SomeFlag
{
get
{
if (!_SomeFlagSet)
SomeFlag = false;
return SomeFlag;
}
set
{
if (!_SomeFlagSet)
_SomeFlagSet = true;
SomeFlag = value;
}
}

Property never null c#

When refactoring code, I come up with instances like the following
private string _property = string.Empty;
public string Property
{
set { _property = value ?? string.Empty); }
}
Later on in a method I see the following:
if (_property != null)
{
//...
}
Assuming that _property is only set by the setter of Property, is this code redundant?
I.e is there any way, through reflection wizardry or other methods that _property can ever be null?
Assuming that _property is only set by the setter of Property, is this
code redundant?
Exactly, it is redundant. This is the actual purpose of Properties. We shouldn't access the fields of a class directly. We should access them using a Property. So in the corresponding setter, we can embed any logic and we can rest assure that each time we try to set a value this logic would be verified once more.This argument holds even for the methods of a class. In a method we must use the properties and not the actual fields. Furthermore, when we want to read the value of a field, we should make use of the corresponding getter.
In general, properties enhances the concept of encapsulation, which is one of the pillars of object oriented programming OOP.
Many times there isn't any logic that should be applied when we want to set a value. Take for instance the following example:
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
We have declared a class for representing a Customer. A Customer object should have three properties an Id, a FirstName and a LastName.
An immediate question, when someones read this class is why should someone make use of properties here?
The answer is again the same, they provide a mechanism of encapsulation. But let's consider how can this help us in the long run. Let's say that one day someone decides that the first name of a customer should be a string of length less than 20. If the above class had been declared as below:
public class Customer
{
public int Id;
public string FirstName;
public string LastName;
}
then we should check for the length of FirstName in each instance we had created ! Otherwise, if we had picked the declaration with the properties, we could just easily make use of Data Annotations
public class Customer
{
public int Id { get; set; }
[StringLength(20)]
public string FirstName { get; set; }
public string LastName { get; set; }
}
and that's it. Another approach it could be the following:
public class Customer
{
public int Id { get; set; }
private string firstName;
public string FirstName
{
get { return firstName }
set
{
if(value!=null && value.length<20)
{
firstName = value;
}
else
{
throw new ArgumentException("The first name must have at maxium 20 characters", "value");
}
}
}
public string LastName { get; set; }
}
Consider both of the above approaches with having to revisit all your codebase and make this check. It's crystal clear that properties win.
Yes, it is possible through reflection. Nevertheless, I wouldn't worry about reflection -- people using reflection to defeat the design of your class is not something I worry about.
There is, however, something I do worry about: the phrase "Assuming that _property is only set by the setter of Property" is key. You are preventing users of your class from setting property to null.
You do not prevent, however, yourself or some other maintainer of your class from forgetting to only use the property INSIDE your class. In fact, your example has some one checking the field from inside the class rather than the property itself.... which means that, within your class, access comes from both the field and the property.
In most cases (where the problem could only come from inside the class) I would use an assertion and assert the field is not null.
If I really, really, really wanted to make sure that it wasn't null (barring reflection or people hell-bent on breaking things), you could try something like this:
internal class Program
{
static void Main()
{
string example = "Spencer the Cat";
UsesNeverNull neverNullUser = new UsesNeverNull(example);
Console.WriteLine(neverNullUser.TheString);
neverNullUser.TheString = null;
Debug.Assert(neverNullUser.TheString != null);
Console.WriteLine(neverNullUser.TheString);
neverNullUser.TheString = "Maximus the Bird";
Console.WriteLine(neverNullUser.TheString);
}
}
public class UsesNeverNull
{
public string TheString
{
get { return _stringValue.Value; }
set { _stringValue.Value = value; }
}
public UsesNeverNull(string s)
{
TheString = s;
}
private readonly NeverNull<string> _stringValue = new NeverNull<string>(string.Empty, str => str ?? string.Empty);
}
public class NeverNull<T> where T : class
{
public NeverNull(T initialValue, Func<T, T> nullProtector)
{
if (nullProtector == null)
{
var ex = new ArgumentNullException(nameof(nullProtector));
throw ex;
}
_value = nullProtector(initialValue);
_nullProtector = nullProtector;
}
public T Value
{
get { return _nullProtector(_value); }
set { _value = _nullProtector(value); }
}
private T _value;
private readonly Func<T, T> _nullProtector;
}
It is basically redundant. However, if it were mission critical or if for some reason it caused terrible side effects, it could remain. It is hard to tell, but part of your question was "can reflection change this value to null" to which the answer is yes and can be seen here in this linqpad demo
void Main()
{
var test = new Test();
test.Property = "5";
Console.WriteLine(test.Property);//5
FieldInfo fieldInfo = test.GetType().GetField("_property",BindingFlags.NonPublic | BindingFlags.Instance);
fieldInfo.SetValue(test, null);
Console.WriteLine(test.Property);//null
}
public class Test
{
private string _property = string.Empty;
public string Property
{
get { return _property; }
set { _property = value ?? string.Empty; }
}
}
I know this question is old, but look, I needed that one of my string properties never came up in null.
So I did this, and It worked for me
public string Operation { get; set; } = string.Empty;
In this way the default value is a string empty, but never null.

How to create a "pointer-like" class, easily exposing functions of member?

What I am trying to do is find the most elegant way to create a "pointer-like" class for a specific object/class type that I have in a project.
What I mean is a little confusing without an example. Take this really simple class:
public class MyClass
{
private string _name;
public string GetName() { return _name; }
public void SetName(string name) { _name = name; }
}
I want to create a second class which is like a pointer to it like this:
public class MyClassPtr
{
private MyClass _obj;
public bool IsValid = false;
public MyClassPtr(MyClass obj) { _obj = obj; IsValid = true; }
public void InvalidatePtr()
{
IsValid = false;
obj = null;
}
// SOME MAGIC HERE?
}
The challenge: The key is that I want to elegantly have MyClassPtr provide an interface to all of the public methods/members in MyClass without writing wrappers and/or accessors around each method/member.
I know that I could do this:
public class MyClassPtr
{
public string GetName() { return _obj.GetName(); }
...
}
But that's what I want to avoid. Is there some fundamental abstraction that I don't know of that I can apply to MyClassPtr to allow it to easily re-expose the methods/members in MyClass directed through _obj? I do NOT want MyClassPtr to inherit MyClass. Should MyClassPtr be a type instead, and some trick with accessors to expose the methods/members of MyClass?
Edit: More context on why I am looking for such a design through an example. Here is the overall goal. Imagine a platform that parses through data about people and when it finds information about a person, it creates an instance of Person with that information. You could get a handle to that person like:
Person person1 = platform.GetPerson(based_on_data);
Now, imagine the platform had two instances of Person that it thought were different people, but all of a sudden information came in that strongly suggested those two instances actually refer to the same person. So, the platform wants to merge the instances together in to a new object, let's call it personX.
Now, floating around in the platform someone had a copy of one of those two instances that got merged, which was person1. What I want to do is on-the-fly replace person1 with personX. Literally, I want person1==personX to be true, NOT just that they are two different objects with the same data. This is important since the platform could make a change to personX and unless the two objects are literally equal, a change to personX would not be automatically reflected in person1.
Since I can't on-the-fly replace person1 with personX I had that idea that I wouldn't give direct access to Person, instead I would give access to PersonPtr which the platform (on-the-fly) can change what Person it is pointing to. This would insurance that once person1ptr gets updated to point to personX, if a change is made in personX it will be seen in person1ptr
You could of course use something like
public class MyClassWrapper
{
MyClass _obj;
public MyClassWrapper(MyClass obj)
{
_obj = obj;
}
public void Invoke(Action<MyClass> action)
{
action(_obj);
}
public U Invoke<U>(Func<MyClass, U> func)
{
return func(_obj);
}
public void ChangeTo(MyClass obj)
{
_obj = obj;
}
}
Given your class looks like
public class MyClass
{
public string Name { get; set; }
}
Example:
var person1 = new MyClass { Name = "Instance1" };
var person2 = new MyClass { Name = "Instance2" };
var wrapper = new MyClassWrapper(person1);
wrapper.Invoke(x => x.Name += "original");
var x = wrapper.Invoke(x => x.Name); // Instance1original
wrapper.ChangeTo(person2);
var y = wrapper.Invoke(x => x.Name); // Instance2
but it has a major drawback: you can't access members directly, so you can't bind the data (to a DataTable or a Control).
It would be better to implement all members of your class also in your wrapper class. If you're afraid changes in your class will be forgotten to be implemented in your wrapper, just use an interface:
public interface IMyClass
{
string Name { get; set; }
}
public class MyClass : IMyClass
{
public string Name { get; set; }
}
public class MyClassWrapper: IMyClass
{
MyClass _obj;
public MyClassWrapper(MyClass obj)
{
_obj = obj;
}
public string Name
{
get { return _obj.Name; }
set { _obj.Name = value; }
}
}
Note that regardless which approach you use, you'll have to always keep a reference to the wrapper instance to actually change the underlying instance (using something like static aside).
Also, changing the underlying instance of such a wrapper without telling the component using it that it changed don't seem to be a good idea. Maybe your system is simple enough to get away with a wrapper; that's something you have to decide for yourself.
Maybe your wrapper should simply have an Invalid flag (and/or use an event to signal a change of the underlying object.). Once the underlying object is merged, it is set to true and each member access should throw an exception. This would force the component using the wrapper to deliberately react to changes and to reload the data from your service.
All in all, I think using such a wrapper will just clutter up your code and be error prone (just imagine adding multithreading to the mix). Think twice if you really need this wrapper.
Why not just simply ask your service for a new instance of your class everytime you use it (the service can simply use a cache)? Sure, you can't prevent that someone somewhere keeps a reference; but at least you'll keep your sanity.

Temporarily disable code contracts inside a block

Is it possible to disable run time (and compile time) checks on a class using a method call or similar? I am having trouble with my classes with invariants and using them with external libraries that construct instances dynamically. I would like to wrap those calls inside my own calls, which take a potentially partially constructed object, and returns one that is always valid.
Eg consider this code:
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace ConsoleApp
{
class Person
{
public string Name { get; set; }
public string Email { get; set; }
public string JobTitle { get; set; }
public Person(string name, string email, string title)
{
Name = name;
Email = email;
JobTitle = title;
}
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(Name != null);
Contract.Invariant(JobTitle != null);
}
}
public static class ObjectBuilder
{
// Just a sample method for building an object dynamically. In my actual code, code using
// elastic search, NEST, serializion or entity framework has similar problems.
public static T BuildFromDictionary<T>(Dictionary<string, object> dict)
{
Contract.Requires(dict != null);
T result = (T)System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof (T));
foreach (var pair in dict)
{
string propName = pair.Key;
var property = typeof (T).GetProperty(propName);
property.SetValue(result, pair.Value);
}
return result;
}
}
class Program
{
public static Person CreatePerson()
{
Dictionary<string, object> personData = new Dictionary<string, object>();
personData["Name"] = "Fred";
personData["Email"] = "email#example.com";
Person person = ObjectBuilder.BuildFromDictionary<Person>(personData);
person.JobTitle = "Programmer";
return person;
}
static void Main(string[] args)
{
Person person1 = new Person("Bob", "Bob#example.com", "Hacker");
Person person = CreatePerson();
Console.WriteLine(person.Name);
}
}
}
This compiles correctly, however will throw an exception on the property.SetValue(result, pair.Value); line. This is because it will call the Name setter, and at that stage Email and JobTitle are null.
What I would like to do is to disable contracts within a code section. Eg, replacing the CreatePerson method with something like this:
public static Person CreatePerson()
{
Dictionary<string, object> personData = new Dictionary<string, object>();
personData["Name"] = "Fred";
personData["Email"] = "email#example.com";
Person person;
Contract.DisableRunTimeChecks(() =>
{
person = ObjectBuilder.BuildFromDictionary<Person>(personData);
person.JobTitle = "Programmer";
});
Contract.CheckInvariants(person);
return person;
}
Where Contract.DisableRunTimeChecks disables run time checks for all code within that code block (and any calls made within), and Contract.CheckInvariants runs the ContractInvariantMethod for the given object.
Is this possible to implement somehow, or is there another solution?
One solution I have seen which I don't want to do is to introduce an _initialized field on Person, and making the invariant method check if that is true before doing any checks. This is because the object should always be valid except for one or two of these constructor methods.
The problem is with the way the invariants are defined. I posted an answer to a similar question here. Please read the answer to the question for the details, but here's a quick couple of paragraphs from that answer that's at the root of the issue here:
From the Code Contracts manual:
Object invariants are conditions that should hold true on each instance of a class whenever that object is visible to a client. They express conditions under which the object is in a "good" state.
There's a peculiar couple of sentences in the manual at the top of page 10:
Invariants are conditionally defined on the full-contract symbol [CONTRACT_FULL]. During runtime checking, invariants are checked at the end of each public method. If an invariant mentions a public method in the same class, then the invariant check that would normally happen at the end of that public method is disabled and checked only at the end of the outermost method call to that class. This also happens if the class is re-entered because of a call to a method on another class.
— text in brackets is mine; this is the compile time symbol the manual is referencing which is defined.
Since properties are really just syntactic sugar for T get_MyPropertyName() and void set_MyPropertyName(T), these sentences would seem to apply to properties, too. Looking in the manual, when they show an example of defining object invariants, they show using private fields in the invariant contract conditions.
So here's how you'll want to define the Person class:
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace ConsoleApp
{
class Person
{
private string _name;
private string _jobTitle;
// For consistency, I would recommend creating a
// private backing field for Email, too. But it's not
// strictly necessary.
public Person(string name, string email, string title)
{
// Are these pre-conditions strict enough??
// Maybe they are, but just asking.
Contract.Requires(name != null);
Contract.Requires(title != null);
_name = name;
_jobTitle = title;
Email = email;
}
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(_name != null);
Contract.Invariant(_jobTitle != null);
}
public string Name
{
get
{
Contract.Ensures(Contract.Result<string>() != null);
return _name;
}
set
{
Contract.Requires(value != null);
_name = value;
}
}
public string JobTitle
{
get
{
Contract.Ensures(Contract.Result<string>() != null);
return _jobTitle;
}
set
{
Contract.Requires(value != null);
_jobTitle = value;
}
}
public string Email { get; set; }
}
So to recap: Invariants only tell consumers what they can expect to be true about the object (at runtime) prior to calling any public method and upon any return from a public method. In this case, you're telling the consumer that you guarantee when they call a public method that Person.Name and Person.JobTitle will be non-null, and that when any public method returns to the caller, again, Person.Name and Person.JobTitle will be non-null. However, in order to ensure that these invariants can be maintained (and enforced), the class needs to state the pre-conditions and post-conditions when getting/setting the properties which mutate the values of the private backing fields _name and _jobTitle.

Chain-overloading constructors?

I'm trying to build a class which will initalise its self either by passing in a reference to a record in a database (with the intention that a query will be run against the database and the returned values for the objects properties will be set therein), or by specifying the values "by hand" - this no database call is required.
I've looked at a couple textbooks to discover the "Best-practice" for this functionality and sadly I've come up short.
I've written a couple sample console apps reflecting what I believe to be the two most probable solutions, but I've no Idea which is the best to implement properly?
Sample App #1 uses what most books tell me is the "preferred" way but most examples given alongside those claims do not really fit the context of my situation. I'm worried in here that the flow is not as readable as App #2.
using System;
namespace TestApp
{
public class Program
{
public static void Main(string[] args)
{
var one = new OverloadedClassTester();
var two = new OverloadedClassTester(42);
var three = new OverloadedClassTester(69, "Mike", 24);
Console.WriteLine("{0}{1}{2}", one, two, three);
Console.ReadKey();
}
}
public class OverloadedClassTester
{
public int ID { get; set; }
public string Name { get; set; }
public int age { get; set; }
public OverloadedClassTester() : this(0) { }
public OverloadedClassTester (int _ID) : this (_ID, "", 0)
{
this.age = 14; // Pretend that this was sourced from a database
this.Name = "Steve"; // Pretend that this was sourced from a database
}
public OverloadedClassTester(int _ID, string _Name, int _age)
{
this.ID = _ID;
this.Name = _Name;
this.age = _age;
}
public override string ToString()
{
return String.Format("ID: {0}\nName: {1}\nAge: {2}\n\n", this.ID, this.Name, this.age);
}
}
}
This Sample (App #2) "appears" more readable - in that I think it's easier to see the flow of operation. However it does appear efficient in terms of characters saved :p. Also, is it not dangerous that it calls a method of the object before it's fully initialised, or is this not a concern?
using System;
namespace TestApp
{
public class Program
{
public static void Main(string[] args)
{
var one = new OverloadedClassTester();
var two = new OverloadedClassTester(42);
var three = new OverloadedClassTester(69, "Mike", 24);
Console.WriteLine("{0}{1}{2}", one, two, three);
Console.ReadKey();
}
}
public class OverloadedClassTester
{
public int ID { get; set; }
public string Name { get; set; }
public int age { get; set; }
public OverloadedClassTester()
{
initialise(0, "", 21); // use defaults.
}
public OverloadedClassTester (int _ID)
{
var age = 14; // Pretend that this was sourced from a database (from _ID)
var Name = "Steve"; // Pretend that this was sourced from a database (from _ID)
initialise(_ID, Name, age);
}
public OverloadedClassTester(int _ID, string _Name, int _age)
{
initialise(_ID, _Name, _age);
}
public void initialise(int _ID, string _Name, int _age)
{
this.ID = _ID;
this.Name = _Name;
this.age = _age;
}
public override string ToString()
{
return String.Format("ID: {0}\nName: {1}\nAge: {2}\n\n", this.ID, this.Name, this.age);
}
}
}
What is the "correct" way to solve this problem, and why?
Thanks,
I would definitely chain the constructors, so that only one of them does the "real work". That means you only have to do the real work in one place, so if that work changes (e.g. you need to call some validation method at the end of the constructor) you only have one place where you need to change the code.
Making "simple" overloads call overloads with more parameters is a pretty common pattern IME. I find it more readable than the second version, because you can easily tell that calling one overload is going to be the same as calling the "bigger" one using the default values. With the second version, you have to compare the bodies of the constructors.
I try not to have more than one constructor which chains directly to the base class wherever possible - unless it's chaining to a different base class constructor, of course (as is typical with exceptions).
Do not use database calls in a constructor. This means your constructor is doing a lot of work. See http://misko.hevery.com/code-reviewers-guide/ (Google guide for writing testable code).
Apart from this, chaining constructors (option 2) looks good. Mostly because as you say it is readable. But why are you assigning this.Name etc in the constructor and doing it again in initialize. You could assign all values in initialize.
Maybe something like this?
public class OverloadedClassTester
{
public int Id { get; private set; }
public string Name { get; private set; }
public int Age { get; private set; }
public OverloadedClassTester (Person person)
: this (person.Id, person.Name, person.Age) { }
public OverloadedClassTester(int id, string name, int age)
{
Id = id;
Name = name;
Age = age;
}
public override string ToString()
{
return String.Format("Id: {0}\nName: {1}\nAge: {2}\n\n",
Id, Name, Age);
}
}
maybe it would be better to use optional parameters? In this case, you would create a single constructor and initialize the values to the parameters you wish to set.
More information: link text
I prefer #1, the chaining constructors, from a maintenance perspective. When someone comes back to edit the code later on, you wouldn't want them to edit the initialise() method and not realize that it is being called from a constructor. I think it is more intuitive to have all the functional parts in a constructor of some kind.
Personally, I use constructor chaining like that all the time.

Categories

Resources