我在C#中阅读了一些关于方法重叠的“new”关键字的材料。但是我仍然没有看到“new”关键字的重要目的,除了修复警告“ CS0108 C#隐藏继承的成员。在Visual Studio中使用新关键字,如果隐藏了。”。 样本:
class ClassA
{
public void printInfo()
{
Console.WriteLine("I'm A");
}
}
测试案例1 :
class ClassB : ClassA
{
public void printInfo()
{
Console.WriteLine("I'm B");
}
}
class Program
{
static void Main(string[] args)
{
ClassA a = new ClassA();
a.printInfo();
ClassB b = new ClassB();
b.printInfo();
ClassA ab = new ClassB();
ab.printInfo();
Console.ReadKey();
}
}
和 测试案例2 ,带有“new”关键字:
class ClassB : ClassA
{
public new void printInfo()
{
Console.WriteLine("I'm B");
}
}
class Program
{
static void Main(string[] args)
{
ClassA a = new ClassA();
a.printInfo();
ClassB b = new ClassB();
b.printInfo();
ClassA ab = new ClassB();
ab.printInfo();
Console.ReadKey();
}
}
它们都具有相同的输出:
I'm A
I'm B
I'm A
不同之处在于“new”关键字修复了警告。
有人可以在这里向我展示更多关于“new”关键字有用的示例吗?
答案 0 :(得分:0)
主要的想法是,当你编写public new void function()
时,你告诉编译器你知道这个方法被baseclass
的方法隐藏了,警告就消失了。现在,您将能够从派生类的实例和基类的实例中使用此方法,或者将其装箱到基类。
答案 1 :(得分:0)
两个代码之间没有区别。编译器只是警告你,你可能没有意识到你正在隐藏 A.printInfo
并且它只是引起你的注意。
在大型代码库中,你甚至可能不拥有A
,在派生类中编写一个与基类中现有方法具有相同签名的方法很容易。< / p>
使用关键字new
,您可以获得三个直接优势:
答案 2 :(得分:0)
您的代码示例都给出了相同的结果,因为添加the new
modifier 并不会更改编译器的输出 - 它只是摆脱了编译器警告{{ 3}}。如果没有new
,编译器会为您添加它:
此警告通知您应使用
new
; 声明变量,就好像声明中使用了新的。
也就是说,由于CS0108,隐藏new
并覆盖不会产生相同的效果。
考虑以下情况(polymorphism):
主要课程:
public class Program
{
public static void Main()
{
Developer developer = new Developer();
PrintSalaryWithHiding(developer);
PrintSalaryWithOverriding(developer);
}
public static void PrintSalaryWithHiding(Employee employee)
{
Console.WriteLine("Salary (with hiding): " + employee.SalaryWithHiding);
}
public static void PrintSalaryWithOverriding(Employee employee)
{
Console.WriteLine("Salary (with overriding): " + employee.SalaryWithOverriding);
}
}
基类(请注意SalaryWithHiding
不是虚拟的,SalaryWithOverriding
是):
public abstract class Employee
{
public int SalaryWithHiding
{
get
{
return 10000;
}
}
public virtual int SalaryWithOverriding
{
get
{
return 10000;
}
}
}
派生类(注意new
之前的SalaryWithHiding
和override
之前的SalaryWithOverriding
:
public class Developer : Employee
{
public new int SalaryWithHiding
{
get
{
return 50000;
}
}
public override int SalaryWithOverriding
{
get
{
return 50000;
}
}
}
结果是
Salary (with hiding): 10000
Salary (with overriding): 50000
这是因为new
关键字告诉编译器,如果您有一个Developer
的实例,声明为Developer
,则调用SalaryWithHiding
方法将调用Developer
类中的一个而不是Employee
类中的一个(即隐藏类)。
当您拥有Developer
的实例,宣布为Employee
时,调用SalaryWithHiding
方法会调用Employee
中的方法类。
您可以在以下缩减示例(try it online)中看到这一点:
主要课程:
public class Program
{
public static void Main()
{
Developer developer = new Developer();
Console.WriteLine("Developer salary when declared as developer: " + developer.SalaryWithHiding);
// these are the same object!
Employee employee = developer;
Console.WriteLine("Developer salary when declared as employee: " + employee.SalaryWithHiding);
}
}
员工:
public abstract class Employee
{
public int SalaryWithHiding
{
get
{
return 10000;
}
}
}
开发:
public class Developer : Employee
{
public new int SalaryWithHiding
{
get
{
return 50000;
}
}
}
结果是:
Developer salary when declared as developer: 50000
Developer salary when declared as employee: 10000
一般来说,我会说你应该只使用new
修饰符,如果你知道你在做什么,因为它打破了多态性:正如你在你自己的例子中看到的那样,当你有
ClassA ab = new ClassB();
ab.printInfo();
它在ClassA
中调用了方法,好像您没有在ClassB
中声明一个具有不同结果的单独方法。这可能是非常令人困惑。在基础virtual
中创建方法并在派生类中重写它会更好,除非您出于某种原因需要该行为。在我的(人为的)示例中,使用new
隐藏方法会导致薪水不正确!