• c# new


    三种用法如下:
    在 C# 中,new 关键字可用作运算符、修饰符或约束。
    1)new 运算符:用于创建对象和调用构造函数。这种大家都比较熟悉,没什么好说的了。
    2)new 修饰符:在用作修饰符时,new 关键字可以显式隐藏从基类继承的成员。
    3)new 约束:用于在泛型声明中约束可能用作类型参数的参数的类型。 
     
    关于第二种用法看下例:
    using System;
    namespace ConsoleApplication1
    {
        public class BaseA
        {
            public int x = 1;
            public void Invoke()
            {
                Console.WriteLine(x.ToString());
            }
            public int TrueValue
            {
                get { return x; }
                set { x = value; }
            }
        }
        public class DerivedB : BaseA
        {
            new public int x = 2;
            new public void Invoke()
            {
                Console.WriteLine(x.ToString());
            }
            new public int TrueValue
            {
                get { return x; }
                set { x = value; }
            }
        }
     
        class Test
        {
            static void Main(string[] args)
            {
                DerivedB b = new DerivedB();
                b.Invoke();//调用DerivedBInvoke方法,输出:2
                Console.WriteLine(b.x.ToString());//输出DerivedB的成员x值:2
                BaseA a = b;
                a.Invoke();//调用BaseAInvoke方法,输出:1
                a.TrueValue = 3;//调用BaseA属性TrueValue,修改BaseA的成员x的值
                Console.WriteLine(a.x.ToString());//输出BaseA的成员x的值:3
                Console.WriteLine(b.TrueValue.ToString());//输出DerivedB的成员x的值,仍然是:1
    //可见,要想访问被隐藏的基类的成员变量、属性或方法,办法就是将子类造型为父类,然
    //后通过基类访问被隐藏的成员变量、属性或方法。
            }
         }
    }
     
    new约束指定泛型类声明中的任何类型参数都必须具有公共的无参数构造函数.请看下例:
    using System;
    using System.Collections.Generic;
     
    namespace ConsoleApplication2
    {
        public class Employee
        {
            private string name;
            private int id;
     
            public Employee()
            {
                name = "Temp";
                id = 0;
            }
     
            public Employee(string s, int i)
            {
                name = s;
                id = i;
            }
     
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
     
            public int ID
            {
                get { return id; }
                set { id = value; }
            }
        }
     
        class ItemFactory<T> where T : new()
        {
            public T GetNewItem()
            {
                return new T();
            }
        }
     
        public class Test
        {
            public static void Main()
            {
                ItemFactory<Employee> EmployeeFactory = new ItemFactory<Employee>();
                ////此处编译器会检查Employee是否具有公有的无参构造函数。
                //若没有则会有The Employee must have a public parameterless constructor 错误。
                Console.WriteLine("{0}'ID is {1}.", EmployeeFactory.GetNewItem().Name, EmployeeFactory.GetNewItem().ID);
            }
        }
    }
     
     
    见MSDN上关于New的解释

    new 修饰符(C# 参考)

     

    在用作修饰符时,new 关键字可以显式隐藏从基类继承的成员。 隐藏继承的成员时,该成员的派生版本将替换基类版本。 虽然可以在不使用 new 修饰符的情况下隐藏成员,但会生成警告。 如果使用 new 显式隐藏成员,则会取消此警告,并记录要替换为派生版本这一事实。

    若要隐藏继承的成员,请使用相同名称在派生类中声明该成员,并使用 new 修饰符修饰该成员。 例如:

    public class BaseC
    {
        public int x;
        public void Invoke() { }
    }
    public class DerivedC : BaseC
    {
        new public void Invoke() { }
    }

    在此示例中,DerivedC.Invoke 隐藏了 BaseC.Invoke 字段 x 不受影响,因为它没有被类似名称的字段隐藏。

    通过继承隐藏名称采用下列形式之一:

    • 引入类或结构中的常数、指定、属性或类型隐藏具有相同名称的所有基类成员。

    • 引入类或结构中的方法隐藏基类中具有相同名称的属性、字段和类型。 同时也隐藏具有相同签名的所有基类方法。

    • 引入类或结构中的索引器将隐藏具有相同名称的所有基类索引器。

    对同一成员同时使用 new 和 override 是错误的做法,因为这两个修饰符的含义互斥。 new 修饰符会用同样的名称创建一个新成员并使原始成员变为隐藏的。 override 修饰符会扩展继承成员的实现。

    在不隐藏继承成员的声明中使用 new 修饰符将会生成警告。

    示例

     

    在该例中,基类 BaseC 和派生类 DerivedC 使用相同的字段名 x,从而隐藏了继承字段的值。 该示例演示了 new 修饰符的用法。 另外还演示了如何使用完全限定名访问基类的隐藏成员。

    public class BaseC
    {
        public static int x = 55;
        public static int y = 22;
    }

    public class DerivedC : BaseC
    {
        // Hide field 'x'.
        new public static int x = 100;

        static void Main()
        {
            // Display the new value of x:
            Console.WriteLine(x);

            // Display the hidden value of x:
            Console.WriteLine(BaseC.x);

            // Display the unhidden member y:
            Console.WriteLine(y);
        }
    }
    /*
    Output:
    100
    55
    22
    */

    在此示例中,嵌套类隐藏了基类中同名的类。 此示例演示了如何使用 new 修饰符来消除警告消息,以及如何使用完全限定名来访问隐藏的类成员。

     public class BaseC 
    {
        public class NestedC 
        {
            public int x = 200;
            public int y;
        }
    }

    public class DerivedC : BaseC { // Nested type hiding the base type members.
        new public class NestedC   
        {
            public int x = 100;
            public int y; 
            public int z;
        }

        static void Main() 
        {
            // Creating an object from the overlapping class:
            NestedC c1  = new NestedC();

            // Creating an object from the hidden class:
            BaseC.NestedC c2 = new BaseC.NestedC();

            Console.WriteLine(c1.x);
            Console.WriteLine(c2.x);   
        }
    }
    /*
    Output:
    100
    200
    */

    如果移除 new 修饰符,该程序仍可编译和运行,但您会收到以下警告:

    The keyword new is required on 'MyDerivedC.x' because it hides inherited member 'MyBaseC.x'.


    new关键字在我们的程序中可谓是无时不刻在用到,那么new关键字都可以用在哪些地方呢?考虑以下几个问题:

    1、new一个class对象和new一个struct或者new一个enum有什么不同?

      答:new一个class时,new完成2个内容:一是调用newobj命令为实例在托管堆中分配内存,二是调用构造函数实现对象初始化。

      new一个struct时,new运算符用于调用其构造函数,完成实例的初始化。

    2、new在.NET中除了创建对象实例外,还可以做什么?

      答:new关键字:作为运算符可以创建对象和调用构造函数;

      作为修饰符可以用于向基类成员隐藏继承成员,实现派生类中隐藏基类的virtual方法,不能和override共存;

      作为约束可以在泛型声明中约束可能用作类型参数的参数类型,即new约束指定泛型类声明中的任何类型参数都必须要有公共的无参构造函数;

      使用new关键字实现多态。

    3、new运算符可以重载吗?

      答:new运算符不可以重载。

    4、泛型中new关键字的作用?

      答:new运算符用于返回一个引用,指向系统分配的托管堆的内存地址,new分配内存失败,将引发OutOfMemoryException异常。

    5、new一个继承下来的方法和override有什么区别?

      答:new是隐藏基类方法,override是覆写基类方法。如果要访问new隐藏了的基类成员需要使用base关键字实现。

    6、int i和int i = new int()有什么不同?

      答:new一个int时,new运算符用于初始化其值为0,使构造函数完成更优越的初始化操作。

     

    通过继承隐藏名称采用下列形式之一:

    • 引入类或结构中的常数、指定、属性或类型隐藏具有相同名称的所有基类成员。

    • 引入类或结构中的方法隐藏基类中具有相同名称的属性、字段和类型。 同时也隐藏具有相同签名的所有基类方法。

    • 引入类或结构中的索引器将隐藏具有相同名称的所有基类索引器。

     
  • 相关阅读:
    nginx实现文件分享
    DataTable.Compute强大的功能
    flink学习01
    flink学习02
    ASIS TOBE
    Oracle安装
    运营与运维
    用户与租户的区别
    书的复制记录方案DP
    模拟题5
  • 原文地址:https://www.cnblogs.com/jearay/p/3642861.html
Copyright © 2020-2023  润新知