示例#1
0
        // Анонимные классы/ Приведение/
        static void F3()
        {
            var v0 = 125;
            var v1 = new { x = 0.0, y = 0.0 }; // Анонимный класс/ Тип объекта определяет
            Console.WriteLine("the type of v1 is: {0}, value is: {1}", v1.GetType(), v1);

            // v1.x = Math.PI; // Доступ к полю объекта-представителя анонимного класса для изменения значения невозможен. Поле открыто только для чтения/
            // v1 = "qwerty"; // Присовение значений других типов недопустимо.
            v1 = new { x = Math.PI, y = 0.0 }; // Изменение значений полей возможно только при создании нового объекта.
            v1 = new { x = Math.PI, y = Math.E };

            double x = 0, y = 0, z = 0;
            var v2 = new { x, y, z, name = "qwerty" }; // Анонимный класс. Объявлен именемами проиницилизированных переменных/ и парой имя поля-значение.
            Console.WriteLine("the type of v2 is: {0}, value is: {1}", v2.GetType(), v2);

            // v3 и v4 являются переменными одного и того же анонимного типа.
            var v3 = new { name = "Spectra", power = 125 };
            var v4 = new { name = "Condor", power = 35 };

            if(Type.Equals(v3.GetType(), v4.GetType()))
            {
                Console.WriteLine("{0} is equivalent to {1}", v3.GetType(), v4.GetType());
            }
            else
            {
                Console.WriteLine("{0} is NOT equivalent to {1}", v3.GetType(), v4.GetType());
            }

            v3 = v4;
            Console.WriteLine("the type of v3 is: {0}, value is: {1}", v3.GetType(), v3);

            // var v5 = new { v3.name, v4.name }; // Анонимный тип не может содержать несколько свойств с одинаковым именем
            var v5 = new { v3.name, v4.power };

            // Взаимодействие с классами (Point2D, Point3D).
            Point2D p2d = new Point2D(0, 0);
            // Присвоение значения посредством неявного приведения типа.
            v0 = p2d; // Транслятор по присвоенному значению (неявно) определил тип переменной v0.

            // Определена как ссылка на объект-представитель класса массив типа double
            var v6 = new double[] { };
            /*  Инициализация массивом значенй, которые получаются при неявном привидении объекта Point2D.
                Важно? что соответсвующий оператор implicit должен быть к этому моменту определ>н в классе Point2D.
            */
            v6 = p2d;

            // v1 представляет анонимный класс с полями x и y.
            // Мы имеем объект p2d. Можно ли изменить значения полей в v1 (конечно, создавая новый объект v1)
            // v1 = new { v1.x, v1.y }; // Так можно, но не интересно.
            // v1 = new { v1.x * 10, v1.y };// Так нельзя. Инициализатор должен быть либо простым именем, либо
            v1 = new { x = v1.x * 10, v1.y }; // Member access expression
            // v1 = new { p2d.X, v1.y };// Попытка присвоения нового значения объекту v1 - представителю анонимного класса. Проблема в несоответсвии имён полей (и свойств в классе Point2D).
            // Возможные решения:
            // 1. Явно указать имя поля объекта v1. То есть сделать member access expression
            v1 = new { x = p2d.X, v1.y };
            // 2. Объявить поле x в классе Point2D public
            v1 = new { p2d.x, v1.y };
            // 3. Объявить новый анонимный класс с названиями полей, соответсвующих названиям свойств класса Point2D
            var v7 = new { X = 0.0, Y = 0.0 };
            v7 = new { p2d.X, v7.Y };

            var v8 = new { v0, v7.Y };
        }
示例#2
0
        // Статическая и динамическая типизация
        static void F4()
        {
            // При создании неявно типизированной локальной переменной var ёё тип фиксируется в момент инициализации
            var v0 = string.Empty;
            Console.WriteLine("the type of v0 is: {0}, value is: {1}", v0.GetType(), v0);
            v0 = "qwerty";
            Console.WriteLine("the type of v0 is: {0}, value is: {1}", v0.GetType(), v0);
            // v0 = 125; // Присвоение начений другого типа недопустимо.
            v0 = 125.ToString();

            // Переменная типа object может получить начальное значение любого типа.
            // на протяжении времени существования объекта это значение может быть заменено новым значением любого типа. Почему это так?
            object obj;
            obj = "Hello!";
            Console.WriteLine("the type of obj is: {0}, value is: {1}", obj.GetType(), obj);
            obj = false;
            Console.WriteLine("the type of obj is: {0}, value is: {1}", obj.GetType(), obj);
            // Компилятором допускается изменение значения.
            // В конкретном случае - значения поля Z.
            // Даже если этого поля не было и нет! Все проблемы вознакают на этапе выполнения кода.
            // ((Point3D)obj).Z = 125.125;
            // Во избежание генерации исключения требуется:
            // 1. явное корректное приведение типа,
            // 2. по ссылке на obj должен быть объект соответсвующего типа.
            // В данном случае транслятор допустит оператор присвоения к выполнению, поскольку класс Point3D
            // объявление свойства Z типа double
            // Однако на этапе выполнения возникает исключение, посколько в данный момент obj ссылается на объект
            obj = new Point3D();
            ((Point3D)obj).Z = 125.125;
            Console.WriteLine("the type of obj is: {0}, value is: {1}", obj.GetType(), obj);

            // Объявлена переменная типа dynamic по имени t.
            // Аналогично, t может получить какое угодно начальное занчение, и на протяэении времени существования переменной это значение может быть заменено новым.
            dynamic t = "Hello!";
            Console.WriteLine("the type of t is: {0}, value is: {1}", t.GetType(), t);

            t = false;
            Console.WriteLine("the type of t is: {0}, value is: {1}", t.GetType(), t);

            t = new Point2D();
            Console.WriteLine("the type of t is: {0}, value is: {1}", t.GetType(), t);

            t.Y = Math.E;
            Console.WriteLine("the type of t is: {0}, value is: {1}", t.GetType(), t);

            try
            {
                t.qwerty = "йцукен";
            }
            catch(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ex)
            {
                Console.WriteLine(ex.Message);
            }
        }