##Reflection use case: factory pattern
Use for some common classes have the same pattern, to do operate for each class.
The code (shape factory) doesn’t require a change even if we add new classes (Triangle, Trapezoidal) that derive shape.
public interface Shape { void Draw(); } public class Square : Shape public class Circle : Shape public static class ShapeFactory |
Use for the properties in a class. The code doesn’t require a change even if we add new properties in the class.
public class Person { private int age = -1; private string name = String.Empty; public void Load() { if (File.Exists("settings.dat")) { Type type = this.GetType(); string propertyName, value; string[] temp; char[] splitChars = new char[] { '|' }; PropertyInfo propertyInfo; string[] settings = File.ReadAllLines("settings.dat"); foreach (string s in settings) { temp = s.Split(splitChars); if (temp.Length == 2) { propertyName = temp[0]; value = temp[1]; propertyInfo = type.GetProperty(propertyName); if (propertyInfo != null) this.SetProperty(propertyInfo, value); } } } } public void Save() { Type type = this.GetType(); PropertyInfo[] properties = type.GetProperties(); TextWriter tw = new StreamWriter("settings.dat"); foreach (PropertyInfo propertyInfo in properties) { tw.WriteLine(propertyInfo.Name + "|" + propertyInfo.GetValue(this, null)); } tw.Close(); } public void SetProperty(PropertyInfo propertyInfo, object value) { switch (propertyInfo.PropertyType.Name) { case "Int32": propertyInfo.SetValue(this, Convert.ToInt32(value), null); break; case "String": propertyInfo.SetValue(this, value.ToString(), null); break; } } public int Age { get { return age; } set { age = value; } } public string Name { get { return name; } set { name = value; } } } |
##Safely Cast by Using as and is Operators
Simple cast may cause InvalidCastException. That is why C# provides the is and as operators. You can use these operators to test whether a cast will succeed without causing an exception to be thrown.
void UseIsOperator(Animal a) { if (a is Mammal) { Mammal m = (Mammal)a; m.Eat(); } } void UseAsOperator(object o) { Mammal m = o as Mammal; // if cast not failed, return null pointer if (m != null) { Console.WriteLine(m.ToString()); } else { Console.WriteLine("{0} is not a Mammal", o.GetType().Name); } } void UseAsWithNullable(System.ValueType val) { int? j = val as int?; //int? is shorthand for Nullable<int>. if (j != null) { Console.WriteLine(j); } else { Console.WriteLine("Could not convert " + val.ToString()); } } |
##Params
C# | Java |
public static int add (params int[] array) { int sum = 0; foreach (int i in array) sum += i; return sum; } | public void aMethod(String... args) { for(String s : args) { System.out.println(s); } } |
##Delegate
A delegate acts like a pointer to a function.
// declare the DelegateCalculation delegate class public delegate double DelegateCalculation( double acceleration, double time ); public class MotionCalculations { // FinalSpeed() calculates the final speed public static double FinalSpeed(double acceleration, double time) { double finalSpeed = acceleration * time; return finalSpeed; } // Distance() calculates the distance traveled public static double Distance(double acceleration, double time) { double distance = acceleration * Math.Pow(time, 2) / 2; return distance; } } |
DelegateCalculation myDelegateCalculation = new DelegateCalculation(MotionCalculations.FinalSpeed); // You can then call the FinalSpeed() method through myDelegateCalculation. For example: double acceleration = 10; // meters per second per second double time = 5; // seconds double finalSpeed = myDelegateCalculation(acceleration, time); myDelegateCalculation = new DelegateCalculation(MotionCalculations.Distance); // You can then call the Distance() method using myDelegateCalculation. For example: double distance = myDelegateCalculation(acceleration, time); |