任何人都可以解释C#中的实际使用方法隐藏的一个有效的例子吗?
如果该方法是使用所定义的new
的派生类关键字,那么它不能被重写。 然后,它是相同的创建具有不同名称的新鲜方法(除了在基类中提到的一个其它)。
有没有使用任何具体的原因new
的关键字?
任何人都可以解释C#中的实际使用方法隐藏的一个有效的例子吗?
如果该方法是使用所定义的new
的派生类关键字,那么它不能被重写。 然后,它是相同的创建具有不同名称的新鲜方法(除了在基类中提到的一个其它)。
有没有使用任何具体的原因new
的关键字?
C#不仅支持方法重载,而且方法隐藏。 简单地说,如果方法不重写衍生方法,它是隐藏它。 阿瞒方法必须使用new关键字来声明。 在第二个上市的正确类的定义是这样的:
using System;
namespace Polymorphism
{
class A
{
public void Foo() { Console.WriteLine("A::Foo()"); }
}
class B : A
{
public new void Foo() { Console.WriteLine("B::Foo()"); }
}
class Test
{
static void Main(string[] args)
{
A a;
B b;
a = new A();
b = new B();
a.Foo(); // output --> "A::Foo()"
b.Foo(); // output --> "B::Foo()"
a = new B();
a.Foo(); // output --> "A::Foo()"
}
}
}
有一点我有时有新的关键字是在parallell继承树“穷芒财产协方差”。 考虑下面这个例子:
public interface IDependency
{
}
public interface ConcreteDependency1 : IDependency
{
}
public class Base
{
protected Base(IDependency dependency)
{
MyDependency = dependency;
}
protected IDependency MyDependency {get; private set;}
}
public class Derived1 : Base // Derived1 depends on ConcreteDependency1
{
public Derived1(ConcreteDependency1 dependency) : base(dependency) {}
// the new keyword allows to define a property in the derived class
// that casts the base type to the correct concrete type
private new ConcreteDependency1 MyDependency {get {return (ConcreteDependency1)base.MyDependency;}}
}
继承树Derived1:基地对ConcreteDependency1一个“parallell依赖”:IDependency”。 在派生类,我知道MyDependency是类型ConcreteDependency1的,因此,我可以隐藏从基类使用新的关键字属性getter。
编辑:又见通过埃里克利珀这篇博客新关键字的一个很好的解释。
我认为ArsenMkrt的例子并不完全正确的,至少它并不能完全解释的隐藏功能。 通过在B类来自于Foo法滴新的关键字,你仍然会得到输出
A::Foo()
B::Foo()
A::Foo()
在编程语言如Java,所有的方法都是“虚拟”的,你希望得到的输出
A::Foo()
B::Foo()
B::Foo()
通过采取上述ArsenMkrt的代码中,由于提供给实例
A a;
B b;
a = new A();
b = new B();
a.Foo();
b.Foo();
a = new B(); //<< Here
a.Foo();
在他的例子但是,你仍然可以得到“A ::富()”,因为在C#方法不是通过默认的虚拟等方法B ::富()会自动隐藏A的美孚()。 为了实现多态行为人有作为,而不是下面写它:
class A
{
public virtual void Foo() { Console.WriteLine("A::Foo()"); }
}
class B : A
{
public override void Foo() { Console.WriteLine("B::Foo()"); }
}
现在是这里的“新”关键字用武之地。其实,当你离开从B ::富()的“覆盖”,然后再次将隐藏A ::富(),这意味着你没有覆盖它的默认行为和你不实现多态,也就是说你拿“A ::富()”再次作为输出。 同样可以实现 - 这里就是我做的不是100%的明白,为什么你必须把它 - 通过把像“新”的关键字..
class A
{
public virtual void Foo() { Console.WriteLine("A::Foo()"); }
}
class B : A
{
public new void Foo() { Console.WriteLine("B::Foo()"); }
}
并再次获得输出
A::Foo()
B::Foo()
A::Foo()
一个略微模糊的场景方法隐藏将是合适的,但对于一个缺乏表达它的任何清洁习惯的方法,是在基类暴露了一个protected成员可继承后裔的情况,但后代知道有没有办法任何进一步派生类可以使用该成员没有摔东西。 其中许多类应该隐藏(但很少做)的方法的一个主要例子是MemberwiseClone()
在许多情况下,如果类具有private
其期望成为唯一现存参照可变对象构件,存在通过其派生类用不完没有可能的手段MemberwiseClone()
正确。
注意保护成员的那隐藏不构成违反了LSP。 一致性与LSP需要在代码可能期待参照基类对象,但接收到一个派生类对象的引用的地方,后者的对象应会基础类工作之一。 受保护的成员,但是,是LSP的范围之内,因为每一种类型的绝对知道它的基本类型。 如果Bar
和Boz
都派生自Foo
,和Boz
隐藏了一个受保护的成员Bar
要求,这一事实Boz
隐藏的成员将不会影响Bar
,因为Bar
的基本类型的实例不可能是Boz
或其他任何比Foo
。 没有取代是可行的,因此可替代性是无关紧要的。
这可能帮助。
class Base
{
public void F() {}
}
class Derived: Base
{
public void F() {} // Warning, hiding an inherited name
}
在上述例子中,F的Derived中的声明导致报告警告。 隐藏继承的名称是专门不是一个错误,因为这会妨碍基类的独立进化。 例如,上述情况可能都讲得出,因为基地的后续版本推出的F方法,不存在在类的早期版本。 如果上述情况是一个错误,然后在单独进行版本类库基类所做的任何变化都有可能导致它的派生类变得无效。 来源: https://msdn.microsoft.com/en-us/library/aa691135%28v=vs.71%29.aspx
当你使用它们一次是当你需要添加/修改是在基类方法的属性。 例如:
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
public new event EventHandler TextChanged
{
add { base.TextChanged += value; }
remove { base.TextChanged -= value; }
}
该基地Control
类有一个TextChanged
事件,但基本事件拥有各类拍打它,防止它显示智能感知或设计了属性。 由于I类用在广泛使用两个的Text
属性和TextChanged
事件,我希望TextChanged
事件在智能感知显示出来,并在属性窗口中可见。