博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
new Modifier (C# Reference)
阅读量:5240 次
发布时间:2019-06-14

本文共 7139 字,大约阅读时间需要 23 分钟。

When used as a declaration modifier, the new keyword explicitly hides a member that is inherited from a base class.

When you hide an inherited member, the derived version of the member replaces the base class version.

Although you can hide members without using the new modifier, you get a compiler warning.

If you use new to explicitly hide a member, it suppresses this warning.

 

To hide an inherited member, declare it in the derived class by using the same member name, and modify it with the new keyword.

For example:

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

In this example, BaseC.Invoke is hidden by DerivedC.Invoke.

The field x is not affected because it is not hidden by a similar name.

 

Name hiding through inheritance takes one of the following forms:

Generally, a constant, field, property, or type that is introduced in a class or struct hides all base class members that share its name.

There are special cases.

For example, if you declare a new field with name N to have a type that is not invocable, and a base type declares N to be a method, the new field does not hide the base declaration in invocation syntax.

See the for details (see section "Member Lookup" in section "Expressions").

 

It is an error to use both new and  on the same member, because the two modifiers have mutually exclusive meanings. The new modifier creates a new member with the same name and causes the original member to become hidden. The override modifier extends the implementation for an inherited member.

Using the new modifier in a declaration that does not hide an inherited member generates a warning.

 

 

问题:

I'm working with the .NET framework and I really want to be able to make a custom type of page that all of my website uses.

The problem comes when I am trying to access the page from a control.

I want to be able to return my specific type of page instead of the default page.

Is there any way to do this?

public class MyPage : Page{    // My own logic}public class MyControl : Control{    public MyPage Page { get; set; }}

答案:

It sounds like what you want is return type covariance. C# does not support return type covariance.

Return type covariance is where you override a base class method that returns a less-specific type with one that returns a more specific type:

class Animal        {        }        class Fish : Animal        {        }        abstract class Enclosure        {            public abstract Animal Contents();        }        class Aquarium : Enclosure        {            public new Fish Contents() { return new Fish(); }        }

 

This is safe because consumers of Contents via Enclosure expect an Animal, and Aquarium promises to not only fulfill that requirement, but moreover, to make a more strict promise: that the animal is always a fish.

 

//上面的代码会报错,因为返回类型不一致

This kind of covariance is not supported in C#, and is unlikely to ever be supported.

It is not supported by the CLR. (It is supported by C++, and by the C++/CLI implementation on the CLR; it does so by generating magical helper methods of the sort I suggest below.)

 

(Some languages support formal parameter type contravariance as well -- that you can override a method that takes a Fish with a method that takes an Animal. Again, the contract is fulfilled; the base class requires that any Fish be handled, and the derived class promises to not only handle fish, but any animal. Similarly, C# and the CLR do not support formal parameter type contravariance.)

The way you can work around this limitation is to do something like:

class Animal        {        }        class Fish : Animal        {        }        abstract class Enclosure        {            protected abstract Animal GetContents();  //子类通过重写这个方法,来返回Fish实例            public Animal Contents()            {                return this.GetContents();            }        }        class Aquarium : Enclosure        {            protected override Animal GetContents()            {                return this.Contents();            }            public new Fish Contents()            {                return new Fish();            }        }

Now you get both the benefits of overriding a virtual method, and getting stronger typing when using something of compile-time type Aquarium.

 

Enclosure enclosure = new Aquarium();                Animal animal = enclosure.Contents();                Console.WriteLine(animal.GetType());

 

 

===2017年06月30日===更新

using System;namespace PolymorphismApplication{    public abstract class Shape    {        protected int width, height;        public Shape(int a = 0, int b = 0)        {            width = a;            height = b;        }        public virtual int area()        {            Console.WriteLine("Parent class area :");            return 0;        }        public virtual int func()        {            return 2;        }    }    public class Rectangle : Shape    {        public Rectangle(int a = 0, int b = 0): base (a, b)        {        }        public override int area()        {            Console.WriteLine("Rectangle class area :");            return (width * height);        }        public new int func()        // if this class is implemented by an object declared on the base class        // e.g  Shape newShape = new Rectancle(5, 10), then the object (newShape)        // will NOT inherit this method. It will stick to the one in Shape.        // Look at the implementation of Caller and the Program/Main to see example.        {            return 6;        }    }    public class Triangle : Shape    {        public Triangle(int a = 0, int b = 0): base (a, b)        {        }        public override int area()        {            Console.WriteLine("Triangle class area :");            return (width * height / 2);        }        public override int func()        {            return 4;        }    }    public class Caller    {        public void CallArea(Shape sh)        {            int a;            a = sh.area();            Console.WriteLine("Area: {0}", a);            int c = sh.func();            Console.WriteLine("func: {0}", c);        }        public void CallArea2 (Rectangle rect)        {            int a;            a = rect.area();            Console.WriteLine("Area: {0}", a);            int c = rect.func();            Console.WriteLine("func: {0}", c);        }    }    public class Program    {        public void Main(string[] args)        {            Caller c = new Caller();            c.CallArea(new Rectangle(10, 7)); // a rectangle is being passed to CallArea's SHAPE object-variable sh            c.CallArea(new Triangle(10, 5));             c.CallArea2(new Rectangle(10, 7)); // a rectangle is being passed to CallArea2's RECTANGLE object-variable rect            // Takeaway: When you declare a rectangle as a reactangle, it will act differently from when you declare it as a shape.            // And this is because of the use of 'new' for the func method, which is only given to rects declared as Rectangles            //                     }    }}

 

 

转载于:https://www.cnblogs.com/chucklu/p/5278153.html

你可能感兴趣的文章
svn 架设
查看>>
k8s部署rocketmq 双主
查看>>
Linux SPI总线和设备驱动架构之四:SPI数据传输的队列化
查看>>
SIGPIPE并产生一个信号处理
查看>>
CentOS
查看>>
Explicit keyword
查看>>
Linux pipe函数
查看>>
java equals 小记
查看>>
Erdaicms旅游网站程序,微信扫码登录演示和示例程序
查看>>
15第十五章UDF用户自定义函数(转载)
查看>>
爬虫-通用代码框架
查看>>
2019春 软件工程实践 助教总结
查看>>
Remove '@Override' annotation错误
查看>>
YUV 格式的视频呈现
查看>>
开通了blog写一些技术blog及感悟
查看>>
Android弹出框的学习
查看>>
extjs gridpanel滚动条问题显示数据不完整
查看>>
springboot(四)设置Redis和Spring的整合
查看>>
mysql提示Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist解决方法...
查看>>
String字符串创建与存储机制
查看>>