前几天去家公司面试,有一道这样的题:写出c#中new关键字的三种用法,思前想后挖空心思也只想出了两种用法,回来查了下msdn,还真是有第三种用法:用于在泛型声明中约束可能用作类型参数的参数的类型,这是在Framework 2.0 中定义泛行时才会使用到的,自己对c# 2.0 中的支持还只是粗通皮毛,怪不得累死so many脑细胞也没能想不出这第三种来!

 
三种用法如下:
在 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();//调用DerivedB的Invoke方法,输出:2
            Console.WriteLine(b.x.ToString());//输出DerivedB的成员x值:2
            BaseA a = b;
            a.Invoke();//调用BaseA的Invoke方法,输出: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'.

c# new三种用法的更多相关文章

  1. using 的三种用法

    using 有哪三种用法? 1)引入命名空间. 2)给命名空间或者类型起别名. 3)划定作用域.自动释放资源,使用该方法的类型必须实现了 System.IDisposable接口,当对象脱离作用域之后 ...

  2. Js闭包常见三种用法

        Js闭包特性源于内部函数可以将外部函数的活动对象保存在自己的作用域链上,所以使内部函数的可以将外部函数的活动对象占为己有,可以在外部函数销毁时依然存有外部函数内的活动对象内容,这样做的好处是可 ...

  3. .NET(c#)new关键字的三种用法

    前几天去家公司面试,有一道这样的题:写出c#中new关键字的三种用法,思前想后挖空心思也只想出了两种用法,回来查了下msdn,还真是有第三种用法:用于在泛型声明中约束可能用作类型参数的参数的类型,这是 ...

  4. SQL、LINQ、Lambda 三种用法(转)

    SQL.LINQ.Lambda 三种用法颜色注释: SQL LinqToSql Lambda QA1. 查询Student表中的所有记录的Sname.Ssex和Class列.select sname, ...

  5. c# new关键字的三种用法

    三种用法如下: 在 C# 中,new 关键字可用作运算符.修饰符或约束. 1)new 运算符:用于创建对象和调用构造函数. 2)new 修饰符:在用作修饰符时,new 关键字可以显式隐藏从基类继承的成 ...

  6. java中 this 的三种用法

    Java中this的三种用法 调用属性 (1)this可以调用本类中的任何成员变量 调用方法(可省略) (2)this调用本类中的成员方法(在main方法里面没有办法通过this调用) 调用构造方法 ...

  7. 子查询。ANY三种用法。ALL两种用法。HAVING中使用子查询。SELECT中使用子查询。

    子查询存在的意义是解决多表查询带来的性能问题. 子查询返回单行多列: ANY三种用法: ALL两种用法: HAVING中的子查询返回单行单列: SELECT中使用子查询:(了解就好,避免使用这种方法! ...

  8. java中 this 关键字的三种用法

    Java中this的三种用法 调用属性 (1)this可以调用本类中的任何成员变量 调用方法(可省略) (2)this调用本类中的成员方法(在main方法里面没有办法通过this调用) 调用构造方法 ...

  9. C++学习---- virtual的三种用法

    virtual用法一:多态 #include<iostream> using namespace std; class A{ public: virtual void display(){ ...

随机推荐

  1. linux c编程:网络编程

    在网络上,通信服务都是采用C/S机制,也就是客户端/服务器机制.流程可以参考下图: 服务器端工作流程: 使用socket()函数创建服务器端通信套接口 使用bind()函数将创建的套接口与服务器地址绑 ...

  2. No provisioned iOS devices are available with a compatible iOS version. Connect an iOS device with a

    No provisioned iOS devices are available with a compatible iOS version. Connect an iOS device with a ...

  3. update module (更新模块)

    [转自http://blog.csdn.net/zhongguomao/article/details/6712568] function module:更新程序必须用一个特殊的FM(update m ...

  4. linux版本查看命令

    uname -a显示电脑以及操作系统相关信息 cat /proc/version显示正在运行的内核版本 cat /etc/issue或cat /etc/redhat-release  Linux查看版 ...

  5. BZOJ 4435 [Cerc2015]Juice Junctions 分治最小割+hash

    分治最小割的题目,要求n2. 之前用的n3的方法自然不能用了. 于是用hash,设hash[i][j]表示在最小割为i的时候,j是否与S联通. 看懂这个需要理解一下最小割树的构造. 这种题建议用EK写 ...

  6. mvc Bundling 学习记录

    因为现在的项目JS引用很多,无意中看到了MVC4的Bundling,开始的时候感觉很不错,将所有的CSS,js文件压缩成一个文件处理,画面调用也很简单 于是,花了一个下午的时候研究了一下,并且通过各种 ...

  7. golang字符串拼接性能对比

    对比 +(运算符).strings.Join.sprintf.bytes.Buffer对字符串拼接的性能 package main import ( "bytes" "f ...

  8. 吴恩达机器学习笔记(七) —— K-means算法

    主要内容: 一.K-means算法简介 二.算法过程 三.随机初始化 四.二分K-means 四.K的选择 一.K-means算法简介 1.K-means算法是一种无监督学习算法.所谓无监督式学习,就 ...

  9. jsp九大内置对象和其作用详解

    jsp九大内置对象和其作用详解 JSP中一共预先定义了9个这样的对象,分别为:request.response.session.application.out.pagecontext.config.p ...

  10. listen 59

    Different Brain Regions Handle Different Music Types (Vivaldi) versus (the Beatles) . Both great. Bu ...