C# Advanced

##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 void Draw()
    {
        Console.WriteLine(" _ \n|_|");
    }
}

public class Circle : Shape
{
    public void Draw()
    {
        Console.WriteLine("O");
    }
}

public static class ShapeFactory
{
    public static Shape GetShape(string shapeName)
    {
        Assembly currentAssembly = Assembly.GetExecutingAssembly();
        var currentType = currentAssembly.GetTypes().SingleOrDefault(t => t.Name == shapeName);
        return (Shape)Activator.CreateInstance(currentType);
    }
}


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);



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值