// ERROR: 'PdaItem. _Name' is inaccessible // due to its protection level //contact._Name = "Inigo Montoya"; //uncomment this line and it will not compile } }
protected访问修饰符
受保护成员在其所在的类中可由派生类实例访问。
只有在通过派生类类型进行访问时,基类的受保护成员在派生类中才是可访问的。A protected member of a base class is accessible in a derived class only if the access occurs through the derived class type.
classB : A { staticvoidMain() { A a = new A(); B b = new B();
// Error CS1540, because x can only be accessed by // classes derived from A. // a.x = 10;
// OK, because this class derives from A. b.x = 10; } }
语句 a.x = 10 生成错误,因为它是在静态方法 Main 中生成的,而不是类 B 的实例。The statement a.x = 10 generates an error because it is made within the static method Main, and not an instance of class B.
无法保护结构成员,因为无法继承结构。
在此示例中,DerivedPoint 类是从 Point 派生的。In this example, the class DerivedPoint is derived from Point. 因此,可以从派生类直接访问基类的受保护成员。Therefore, you can access the protected members of the base class directly from the derived class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classPoint { protectedint x; protectedint y; }
classDerivedPoint: Point { staticvoidMain() { DerivedPoint dpoint = new DerivedPoint();
// Direct access to protected members: dpoint.x = 10; dpoint.y = 15; Console.WriteLine("x = {0}, y = {1}", dpoint.x, dpoint.y); } } // Output: x = 10, y = 15
classMyBaseClass { // virtual auto-implemented property. Overrides can only // provide specialized behavior if they implement get and set accessors. publicvirtualstring Name { get; set; }
// ordinary virtual property with backing field privateint num; publicvirtualint Number { get { return num; } set { num = value; } } }
// Override auto-implemented property with ordinary property // to provide specialized accessor behavior. publicoverridestring Name { get { return name; } set { if (value != String.Empty) { name = value; } else { name = "Unknown"; } } }
publicoverridedoubleArea () { return2 * PI * x * x + 2 * PI * x * y; } }
staticvoidMain () { double r = 3.0, h = 5.0; Shape c = new Circle (r); Shape s = new Sphere (r); Shape l = new Cylinder (r, h); // Display results: Console.WriteLine ("Area of Circle = {0:F2}", c.Area ()); Console.WriteLine ("Area of Sphere = {0:F2}", s.Area ()); Console.WriteLine ("Area of Cylinder = {0:F2}", l.Area ()); } } /* Output: Area of Circle = 28.27 Area of Sphere = 113.10 Area of Cylinder = 150.80 */
classProgram { staticvoidMain (string[] args) { BaseClass bc = new BaseClass (); DerivedClass dc = new DerivedClass (); BaseClass bcdc = new DerivedClass ();
bc.Method1 (); dc.Method1 (); dc.Method2 (); bcdc.Method1 (); } // Output: // Base - Method1 // Base - Method1 // Derived - Method2 // Base - Method1 }
classProgram { staticvoidMain (string[] args) { BaseClass bc = new BaseClass (); DerivedClass dc = new DerivedClass (); BaseClass bcdc = new DerivedClass ();
bc.Method1 (); bc.Method2 (); dc.Method1 (); dc.Method2 (); bcdc.Method1 (); bcdc.Method2 (); } // Output: // Base - Method1 // Base - Method2 // Base - Method1 // Derived - Method2 // Base - Method1 // Base - Method2 }
classProgram { staticvoidMain (string[] args) { BaseClass bc = new BaseClass (); DerivedClass dc = new DerivedClass (); BaseClass bcdc = new DerivedClass ();
bc.Method1 (); bc.Method2 (); dc.Method1 (); dc.Method2 (); bcdc.Method1 (); bcdc.Method2 (); } // Output: // Base - Method1 // Base - Method2 // Base - Method1 // Derived - Method2 // Base - Method1 // Base - Method2 }
输出结果与上例不使用 new 修饰符是一样的,只是不再有警告。就CIL来说,new修饰符对编译器生成的代码没有任何影响。从 C# 的角度看,它唯一的作用就是移除编译器警告。
classProgram { staticvoidMain (string[] args) { BaseClass bc = new BaseClass (); DerivedClass dc = new DerivedClass (); BaseClass bcdc = new DerivedClass ();
publicabstractclassPdaItem { publicPdaItem (string name) { Name = name; }
publicvirtualstring Name { get; set; } }
publicclassProgram { publicstaticvoidMain () { PdaItem item; // ERROR: Cannot create an instance of the abstract class //item = new PdaItem("Inigo Montoya"); //uncomment this line and it will not compile } }
在运行时,在方法参数和集合或数组等位置,派生类的对象可以作为基类的对象处理。At run time, objects of a derived class may be treated as objects of a base class in places such as method parameters and collections or arrays. 发生此情况时,该对象的声明类型不再与运行时类型相同。When this occurs, the object’s declared type is no longer identical to its run-time type.
publicclassShape { // A few example members publicint X { get; privateset; } publicint Y { get; privateset; } publicint Height { get; set; } publicint Width { get; set; }
// Virtual method publicvirtualvoidDraw () { Console.WriteLine ("Performing base class drawing tasks"); } }
classCircle : Shape { publicoverridevoidDraw () { // Code to draw a circle... Console.WriteLine ("Drawing a circle"); base.Draw (); } } classRectangle : Shape { publicoverridevoidDraw () { // Code to draw a rectangle... Console.WriteLine ("Drawing a rectangle"); base.Draw (); } } classTriangle : Shape { publicoverridevoidDraw () { // Code to draw a triangle... Console.WriteLine ("Drawing a triangle"); base.Draw (); } }
classProgram { staticvoidMain (string[] args) { // Polymorphism at work #1: a Rectangle, Triangle and Circle // can all be used whereever a Shape is expected. No cast is // required because an implicit conversion exists from a derived // class to its base class. var shapes = new List<Shape> { new Rectangle (), new Triangle (), new Circle () };
// Polymorphism at work #2: the virtual method Draw is // invoked on each of the derived classes, not the base class. foreach (var shape in shapes) { shape.Draw (); }
// Keep the console open in debug mode. Console.WriteLine ("Press any key to exit."); Console.ReadKey (); }
}
/* Output: Drawing a rectangle Performing base class drawing tasks Drawing a triangle Performing base class drawing tasks Drawing a circle Performing base class drawing tasks */
publicclassBase { publicvirtualvoidDoWork() {/*...*/ } } publicclassDerived : Base { publicoverridevoidDoWork() { //Perform Derived's work here //... // Call DoWork on base class base.DoWork(); } }
publicclassExample { publicstaticvoidMain() { var cl1 = new Class1(); Console.WriteLine(cl1 is IFormatProvider); Console.WriteLine(cl1 is Object); Console.WriteLine(cl1 is Class1); Console.WriteLine(cl1 is Class2); Console.WriteLine();
var cl2 = new Class2(); Console.WriteLine(cl2 is IFormatProvider); Console.WriteLine(cl2 is Class2); Console.WriteLine(cl2 is Class1); Console.WriteLine();
Class1 cl = cl2; Console.WriteLine(cl is Class1); Console.WriteLine(cl is Class2); } } // The example displays the following output: // True // True // True // False // // True // True // True // // True // True
publicclassEmployee : IComparable { public String Name { get; set; } publicint Id { get; set; }
publicintCompareTo(Object o) { var e = o as Employee; if (e == null) { thrownew ArgumentException("o is not an Employee object."); } return Name.CompareTo(e.Name); } }
if (o is Dice d && d.Roll() is HIGH_ROLL) Console.WriteLine($"The value is {HIGH_ROLL}!"); else Console.WriteLine($"The dice roll is not a {HIGH_ROLL}!"); } } // The example displays output like the following: // The value is 6!
classPerson { publicPerson(string name) { Name = name; }
publicstring Name { get; set; }
publicoverridestringToString() { return Name; } } // The example displays the following output: // Type: Book, Value: The Tempest // Type: Person, Value: John
for (int i = 0; i < objArray.Length; ++i) { string s = objArray[i] asstring; Console.Write ("{0}:", i); if (s != null) { Console.WriteLine ("'" + s + "'"); } else { Console.WriteLine ("not a string"); } } } } /* Output: 0:not a string 1:not a string 2:'hello' 3:not a string 4:not a string 5:not a string */