C# Advanced

来源:互联网 发布:pmp培训 知乎 编辑:程序博客网 时间:2024/06/03 20:15

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

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

public staticclass ShapeFactory
{
    public staticShape 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 sin 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 propertyInfoin 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 forNullable<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 doubleFinalSpeed(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);



0 0
原创粉丝点击