Csharp/C Sharp/Class Interface/Properties — различия между версиями

Материал из .Net Framework эксперт
Перейти к: навигация, поиск
м (1 версия)
 
(нет различий)

Текущая версия на 11:39, 26 мая 2010

access to a private field through a property

/*
C# Programming Tips & Techniques
by Charles Wright, Kris Jamsa
Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/
//
//  Property.cs -- Demonstrates access to a private field through a property.
//                 Compile this program with the following command line:
//                     C:>csc Property.cs
//
namespace nsProperty
{
    using System;
    public class Property
    {
        const double radian = 57.29578;
        const double pi = 3.14159;
        int Angle
        {
            get
            {
                int angle = (int) (fAngle * radian + 0.5);
                angle = angle == 360 ? 0 : angle;
                return (angle);
            }
            set
            {
                double angle = (double) value / radian;
                if (angle < (2 * pi))
                {
                    fAngle = angle;
                    Console.WriteLine ("fAngle set to {0,0:F5}", fAngle);
                }
                else
                {
                    Console.WriteLine ("fAngle not modified");
                }
            }
        }
        double fAngle = 0.0;   //  Angle in radians
        static public int Main (string [] args)
        {
            int angle;
            try
            {
                angle = int.Parse (args[0]);
            }
            catch (IndexOutOfRangeException)
            {
                Console.WriteLine ("usage: circle [angle in degrees]");
                return (-1);
            }
            catch (FormatException)
            {
                Console.WriteLine ("Please use a number value for the angle in degrees");
                return (-1);
            }
            Property main = new Property();
            main.Angle = angle;
            Console.WriteLine ("The angle is {0} degrees", main.Angle);
            return (0);
        }
    }
}


Add Length property to FailSoftArray

/*
C#: The Complete Reference 
by Herbert Schildt 
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/
// Add Length property to FailSoftArray. 
 
using System; 
 
class FailSoftArray {  
  int[] a; // reference to underlying array  
  int len; // length of array -- underlies Length property 
 
  public bool errflag; // indicates outcome of last operation 
   
  // Construct array given its size.  
  public FailSoftArray(int size) { 
    a = new int[size]; 
    len = size;  
  } 
 
  // Read-only Length property. 
  public int Length { 
    get { 
      return len; 
    } 
  } 
 
  // This is the indexer for FailSoftArray. 
  public int this[int index] { 
    // This is the get accessor. 
    get { 
      if(ok(index)) { 
        errflag = false; 
        return a[index]; 
      } else { 
        errflag = true; 
        return 0; 
      } 
    } 
 
    // This is the set accessor 
    set { 
      if(ok(index)) { 
        a[index] = value; 
        errflag = false; 
      } 
      else errflag = true; 
    } 
  } 
 
  // Return true if index is within bounds. 
  private bool ok(int index) { 
   if(index >= 0 & index < Length) return true; 
   return false; 
  } 
}  
  
// Demonstrate the improved fail-soft array. 
public class ImprovedFSDemo {  
  public static void Main() {  
    FailSoftArray fs = new FailSoftArray(5); 
    int x; 
 
    // can read Length 
    for(int i=0; i < fs.Length; i++) 
      fs[i] = i*10; 
 
    for(int i=0; i < fs.Length; i++) { 
      x = fs[i]; 
      if(x != -1) Console.Write(x + " "); 
    } 
    Console.WriteLine(); 
 
    // fs.Length = 10; // Error, illegal! 
  } 
}


A simple property example

/*
C#: The Complete Reference 
by Herbert Schildt 
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/
// A simple property example. 
 
using System; 
 
class SimpProp {  
  int prop; // field being managed by myprop 
 
  public SimpProp() { prop = 0; } 
 
  /* This is the property that supports access to 
     the private instance variable prop.  It 
     allows only positive values. */ 
  public int myprop { 
    get { 
      return prop; 
    } 
    set { 
      if(value >= 0) prop = value; 
    }  
  } 
}  
  
// Demonstrate a property. 
public class PropertyDemo {  
  public static void Main() {  
    SimpProp ob = new SimpProp(); 
 
    Console.WriteLine("Original value of ob.myprop: " + ob.myprop); 
 
    ob.myprop = 100; // assign value 
    Console.WriteLine("Value of ob.myprop: " + ob.myprop); 
 
    // Can"t assign negative value to prop 
    Console.WriteLine("Attempting to -10 assign to ob.myprop"); 
    ob.myprop = -10; 
    Console.WriteLine("Value of ob.myprop: " + ob.myprop); 
  } 
}


Convert errflag into a property

/*
C#: The Complete Reference 
by Herbert Schildt 
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/
// Convert errflag into a property. 
 
using System; 
 
class FailSoftArray {  
  int[] a; // reference to underlying array  
  int len; // length of array 
 
  bool errflag; // now private 
   
  // Construct array given its size.  
  public FailSoftArray(int size) { 
    a = new int[size]; 
    len = size;  
  } 
 
  // Read-only Length property. 
  public int Length { 
    get { 
      return len; 
    } 
  } 
 
  // Read-only Error property. 
  public bool Error { 
    get { 
      return errflag; 
    } 
  } 
 
  // This is the indexer for FailSoftArray. 
  public int this[int index] { 
    // This is the get accessor. 
    get { 
      if(ok(index)) { 
        errflag = false; 
        return a[index]; 
      } else { 
        errflag = true; 
        return 0; 
      } 
    } 
 
    // This is the set accessor 
    set { 
      if(ok(index)) { 
        a[index] = value; 
        errflag = false; 
      } 
      else errflag = true; 
    } 
  } 
 
  // Return true if index is within bounds. 
  private bool ok(int index) { 
   if(index >= 0 & index < Length) return true; 
   return false; 
  } 
}  
  
// Demonstrate the improved fail-soft array. 
public class FinalFSDemo {  
  public static void Main() {  
    FailSoftArray fs = new FailSoftArray(5); 
 
    // use Error property 
    for(int i=0; i < fs.Length + 1; i++) { 
      fs[i] = i*10; 
      if(fs.Error)  
        Console.WriteLine("Error with index " + i); 
    } 
 
  } 
}


Define properties for class

/*
Learning C# 
by Jesse Liberty
Publisher: O"Reilly 
ISBN: 0596003765
*/
 using System;
 namespace Properties
 {
     class Time
     {
         // private member variables
         private int year;
         private int month;
         private int date;
         private int hour;
         private int minute;
         private int second;
         // create a property
         public int Hour
         {
             get
             {
                 return hour;
             }
             set
             {
                 hour = value;
             }
         }
         // public accessor methods
         public void DisplayCurrentTime()
         {
             System.Console.WriteLine(
                 "Time: {0}/{1}/{2} {3}:{4}:{5}",
                 month, date, year, hour, minute, second);
         }

         // constructors
         public Time(System.DateTime dt)
         {
             year =      dt.Year;
             month =     dt.Month;
             date =      dt.Day;
             hour =      dt.Hour;
             minute =    dt.Minute;
             second =    dt.Second;
         }

    }
    public class PropertiesTester
    {
       public void Run()
       {
           System.DateTime currentTime = System.DateTime.Now;
           Time t = new Time(currentTime);
           t.DisplayCurrentTime();
           // access the hour to a local variable
           int theHour = t.Hour;
           // display it
           System.Console.WriteLine("Retrieved the hour: {0}",
               theHour);
           // increment it
           theHour++;
           // reassign the incremented value back through
           // the property
           t.Hour = theHour;
           // display the property
           System.Console.WriteLine("Updated the hour: {0}", t.Hour);
       }
       [STAThread]
       static void Main()
       {
          PropertiesTester t = new PropertiesTester();
          t.Run();
       }
    }
 }


Delegates as Static Properties

/*
A Programmer"s Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress  L.P.
ISBN: 1-893115-62-3
*/
// 22 - Delegates\Delegates as Static Properties
// copyright 2000 Eric Gunnerson
using System;
class Container
{
    public delegate int CompareItemsCallback(object obj1, object obj2);
    public void SortItems(CompareItemsCallback compare)
    {
        // not a real sort, just shows what the
        // inner loop code might do
        int x = 0;
        int y = 1;
        object    item1 = arr[x];
        object item2 = arr[y];
        int order = compare(item1, item2);
    }
    object[]    arr;    // items in the collection
}
class Employee
{
    Employee(string name, int id)
    {
        this.name = name;
        this.id = id;
    }
    public static Container.rupareItemsCallback SortByName
    {
        get
        {
            return(new Container.rupareItemsCallback(CompareName));
        }
    }
    public static Container.rupareItemsCallback SortById
    {
        get
        {
            return(new Container.rupareItemsCallback(CompareId));
        }
    }
    static int CompareName(object obj1, object obj2)
    {
        Employee emp1 = (Employee) obj1;
        Employee emp2 = (Employee) obj2;
        return(String.rupare(emp1.name, emp2.name));
    }
    static int CompareId(object obj1, object obj2)
    {
        Employee emp1 = (Employee) obj1;
        Employee emp2 = (Employee) obj2;
        
        if (emp1.id > emp2.id)
        return(1);
        if (emp1.id < emp2.id)
        return(-1);
        else
        return(0);
    }
    string    name;
    int    id;
}
public class DelegatesasStaticProperties
{
    public static void Main()
    {
        Container employees = new Container();
        // create and add some employees here
        
        employees.SortItems(Employee.SortByName);
        // employees is now sorted by name
    }
}


Demonstrates the use of properties to control how values are saved in fields

/*
C# Programming Tips & Techniques
by Charles Wright, Kris Jamsa
Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/
//  Rect.cs - Demonstrates the use of properties to control how values are
//            saved in fields
//
//            This is a Visual Studio project. To compile outside of Visual
//            Studio, use the following command line:
//                C:>csc rect.cs
//
using System;
using System.Drawing;
namespace nsRect
{
  struct POINT
  {
    public POINT (int x, int y)
    {
      this.cx = x;
      this.cy = y;
    }
    public int cx;
    public int cy;
    public override string ToString ()
    {
      return (String.Format ("({0}, {1})", cx, cy));
    }
  }
  struct RECT
  {
    public RECT (Rectangle rc)
    {
      m_UpperLeft.cx = rc.X;
      m_UpperLeft.cy = rc.Y;
      m_LowerRight.cx = rc.X + rc.Width;
      m_LowerRight.cy = rc.Y + rc.Height;
    }
    // Define constructors
    public RECT (POINT pt1, POINT pt2)
    {
      m_UpperLeft = pt1;
      m_LowerRight = pt2;
    }
    public RECT (int x1, int y1, int x2, int y2)
    {
      m_UpperLeft.cx = x1;
      m_UpperLeft.cy = y1;
      m_LowerRight.cx = x2;
      m_LowerRight.cy = y2;
    }
    public RECT (POINT pt1, int Width, int Height)
    {
      m_UpperLeft.cx = pt1.cx;
      m_UpperLeft.cy = pt1.cy;
      m_LowerRight.cx = pt1.cx + Width;
      m_LowerRight.cy = pt1.cy + Height;
    }
    // Property to get and set the upper left point
    public POINT UpperLeft
    {
      get {return (m_UpperLeft);}
      set {m_UpperLeft = value;}
    }
    // Property to get and set the lower right point
    public POINT LowerRight
    {
      get {return (m_LowerRight);}
      set {m_LowerRight = value;}
    }
    // Property to return a normalized System.Drawing.ectangle object
    public System.Drawing.Rectangle Rectangle
    {
      get
      {
        RECT rc = Normal;
        return (new Rectangle (rc.UpperLeft.cx, rc.UpperLeft.cy,
          rc.LowerRight.cx - rc.UpperLeft.cx,
          rc.LowerRight.cy - rc.UpperLeft.cy));
      }
    }
    // Property to return a normalized copy of this rectangle
    public RECT Normal
    {
      get
      {
        return (new RECT (
          Math.Min (m_LowerRight.cx, m_UpperLeft.cx),
          Math.Min (m_LowerRight.cy, m_UpperLeft.cy),
          Math.Max (m_LowerRight.cx, m_UpperLeft.cx),
          Math.Max (m_LowerRight.cy, m_UpperLeft.cy))
          );
      }
    }
    private POINT m_UpperLeft;
    private POINT m_LowerRight;
    public override string ToString()
    {
      return (String.Format ("Upper left = {0}; Lower right = {1}",
        m_UpperLeft, m_LowerRight));
    }
  }
  public class Rect
  {
    static public void Main ()
    {
      // Define a "normal" rectangle
      POINT pt1 = new POINT (-10,30);
      POINT pt2 = new POINT (100, 100);
      RECT rc = new RECT (pt1, pt2);
      Console.WriteLine ("RECT: " + rc);
      Console.WriteLine ("Normal: " + rc.Normal);
      Console.WriteLine ("Rectangle: " + rc.Rectangle + "\n");
      // Define a rectangle with normal x but not y
      pt1.cx = 100;
      pt1.cy = 50;
      pt2.cx = 200;
      pt2.cy = 20;
      rc.UpperLeft = pt1;
      rc.LowerRight = pt2;
      Console.WriteLine ("RECT: " + rc);
      Console.WriteLine ("Normal: " + rc.Normal);
      Console.WriteLine ("Rectangle: " + rc.Rectangle + "\n");
      // Define a rectangle with normal y but not x
      pt1.cx = 200;
      pt1.cy = 50;
      pt2.cx = 100;
      pt2.cy = 80;
      rc.UpperLeft = pt1;
      rc.LowerRight = pt2;
      Console.WriteLine ("RECT: " + rc);
      Console.WriteLine ("Normal: " + rc.Normal);
      Console.WriteLine ("Rectangle: " + rc.Rectangle + "\n");
      // Define a rectangle with both values of upper left greater than the lower y
      pt1.cx = 225;
      pt1.cy = 180;
      pt2.cx = 25;
      pt2.cy = 35;
      rc.UpperLeft = pt1;
      rc.LowerRight = pt2;
      Console.WriteLine ("RECT: " + rc);
      Console.WriteLine ("Normal: " + rc.Normal);
      Console.WriteLine ("Rectangle: " + rc.Rectangle + "\n");
      // Define a rectangle with points equal
      pt1.cx = 75;
      pt1.cy = 150;
      pt2.cx = 75;
      pt2.cy = 150;
      rc.UpperLeft = pt1;
      rc.LowerRight = pt2;
      Console.WriteLine ("RECT: " + rc);
      Console.WriteLine ("Normal: " + rc.Normal);
      Console.WriteLine ("Rectangle: " + rc.Rectangle + "\n");
    }
  }
}


enum based attribute

 

using System;
public enum RemoteServers
{
    A,
    B,
    C
}
   
public class RemoteObjectAttribute : Attribute
{
    public RemoteObjectAttribute(RemoteServers Server)
    {
        this.server = Server;
    }
   
    protected RemoteServers server;
    public string Server
    {
        get 
        { 
            return RemoteServers.GetName(
                typeof(RemoteServers), this.server);
        }
    }
}
   
[RemoteObject(RemoteServers.C)]
class MyRemotableClass
{
}
class Test
{
    [STAThread]
    static void Main(string[] args)
    {
        Type type = typeof(MyRemotableClass);
        foreach (Attribute attr in type.GetCustomAttributes(true))
        {
            RemoteObjectAttribute remoteAttr = attr as RemoteObjectAttribute;
            if (null != remoteAttr)
            {
                Console.WriteLine(remoteAttr.Server);
            }
        }
    }
}


Error handling in property setter validating

 

using System;
public class Employee {
    private int prop_age;
    public int age {
        set {
            if (value < 0 || value > 120) {
                throw new ApplicationException("Not valid age!");
            }
            prop_age = value;
        }
        get {
            return prop_age;
        }
    }
}


Illustrates the use of a property

/*
Mastering Visual C# .NET
by Jason Price, Mike Gunderloy
Publisher: Sybex;
ISBN: 0782129110
*/
/*
  Example6_4.cs illustrates the use of a property
*/

// declare the Car class
class Car
{
  // declare a private field
  private string make;
  // declare a property
  public string Make
  {
    get
    {
      return make;
    }
    set
    {
      make = value;
    }
  }
}

public class Example6_4
{
  public static void Main()
  {
    // create a Car object
    System.Console.WriteLine("Creating a Car object");
    Car myCar = new Car();
    // set the Car Make
    System.Console.WriteLine("Setting the Car object"s Make property to Porsche");
    myCar.Make = "Porsche";
    System.Console.WriteLine("myCar.Make = " + myCar.Make);
  }
}


Override Properties

 
using System;
using System.Collections;
   
abstract class Employee
{
    protected Employee(int employeeId, int hoursWorked)
    {
        this.employeeId = employeeId;
        HoursWorked = hoursWorked;
    }
   
    protected int employeeId;
    public int EmployeeId
    {
        get { return employeeId; }
    }
   
    protected int HoursWorked;
   
    protected double hourlyCost = -1; // dummy init value
    public abstract double HourlyCost
    { 
        get;
    }
}
   
class ContractEmployee : Employee
{
    public ContractEmployee(int employeeId, double hourlyWage,
        int hoursWorked)
        : base(employeeId, hoursWorked)
    {
        HourlyWage = hourlyWage;
    }
   
    protected double HourlyWage;
    public override double HourlyCost
    { 
        get 
        { return HourlyWage; }
    }
}
   
class SalariedEmployee : Employee
{
    public SalariedEmployee(int employeeId, double salary,
        int hoursWorked)
        : base(employeeId, hoursWorked)
    {
        Salary = salary;
    }
   
    protected double Salary;
    public override double HourlyCost
    { 
        get 
        { 
            return (Salary / 52) / HoursWorked; 
        }
    }
}
   
class OverrideProperties
{
    public static ArrayList employees = new ArrayList();
 
    public static void PrintEmployeesHourlyCostToCompany()
    {
        foreach (Employee employee in employees)
        {
            Console.WriteLine("{0} employee (id={1}) costs {2}" +
                " per hour", employee, employee.EmployeeId,
                employee.HourlyCost);
        }
    }
   
    public static void Main()
    {
        ContractEmployee c  = new ContractEmployee(1, 50, 40);
        employees.Add(c);
   
        SalariedEmployee s =
            new SalariedEmployee(2, 100000, 65);
        employees.Add(s);
   
        PrintEmployeesHourlyCostToCompany();
   
        Console.ReadLine();
    }
}


Properties Accessors

/*
A Programmer"s Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress  L.P.
ISBN: 1-893115-62-3
*/
// 18 - Properties\Accessors
// copyright 2000 Eric Gunnerson
public class PropertiesAccessors
{
    private string name;
    
    public string Name
    {
        get 
        {
            return name;
        }
        set 
        {
            name = value;
        }
    }
}


Properties: Side Effects When Setting Values

/*
A Programmer"s Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress  L.P.
ISBN: 1-893115-62-3
*/
// 18 - Properties\Side Effects When Setting Values
// copyright 2000 Eric Gunnerson
using System;
using System.Collections;
class Basket
{
    internal void UpdateTotal()
    {
        total = 0;
        foreach (BasketItem item in items)
        {
            total += item.Total;
        }
    }
    
    ArrayList    items = new ArrayList();
    Decimal    total;
}
public class BasketItem
{
    BasketItem(Basket basket)
    {
        this.basket = basket;
    }
    public int Quantity
    {
        get
        {
            return(quantity);
        }
        set
        {
            quantity = value;
            basket.UpdateTotal();
        }
    }
    public Decimal Price
    {
        get
        {
            return(price);
        }
        set
        {
            price = value;
            basket.UpdateTotal();
        }
    }
    public Decimal Total
    {
        get
        {
            // volume discount; 10% if 10 or more are purchased
            if (quantity >= 10)
            return(quantity * price * 0.90m);
            else
            return(quantity * price); 
        }
    }
    
    int        quantity;     // count of the item
    Decimal    price;        // price of the item
    Basket     basket;       // reference back to the basket
}


Properties:Static Properties

/*
A Programmer"s Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress  L.P.
ISBN: 1-893115-62-3
*/
// 18 - Properties\Static Properties
// copyright 2000 Eric Gunnerson
class Color
{
    public Color(int red, int green, int blue)
    {
        this.red = red;
        this.green = green;
        this.blue = blue;
    }
    
    int    red;
    int    green;
    int    blue;
    
    public static Color Red
    {
        get
        {
            return(new Color(255, 0, 0));
        }
    }
    public static Color Green
    {
        get
        {
            return(new Color(0, 255, 0));
        }
    }
    public static Color Blue
    {
        get
        {
            return(new Color(0, 0, 255));
        }
    }
}
public class StaticProperties
{
    static void Main()
    {
        Color background = Color.Red;
    }
}


Properties: Use of Properties

/*
A Programmer"s Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress  L.P.
ISBN: 1-893115-62-3
*/
// 18 - Properties\Use of Properties
// copyright 2000 Eric Gunnerson
using System;
public class Auto
{
    public Auto(int id, string name)
    {
        this.id = id;
        this.name = name;
    }
    
    // query to find # produced
    public int ProductionCount
    {
        get
        {
            if (productionCount == -1)
            {
                // fetch count from database here.
            }
            return(productionCount);
        }
    }
    public int SalesCount
    {
        get
        {
            if (salesCount == -1)
            {
                // query each dealership for data
            }
            return(salesCount);
        }
    }
    string name;
    int id;
    int productionCount = -1;
    int salesCount = -1;
}


Properties:Virtual Properties

/*
A Programmer"s Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress  L.P.
ISBN: 1-893115-62-3
*/
// 18 - Properties\Virtual Properties
// copyright 2000 Eric Gunnerson
using System;
public abstract class DrawingObject
{
    public abstract string Name
    {
        get;
    }
}
class Circle: DrawingObject
{
    string name = "Circle";
    
    public override string Name
    {
        get
        {
            return(name);
        }
    }
}
public class PropertiesVirtualProperties
{
    public static void Main()
    {
        DrawingObject d = new Circle();
        Console.WriteLine("Name: {0}", d.Name);
    }
}


The use of an abstract property

/*
C# Programming Tips & Techniques
by Charles Wright, Kris Jamsa
Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/
//
// Abstract.cs -- Demonsrates the use of an abstract property.
//
//                Compile this program with the following command line:
//                    C:>csc Abstract.cs
//
namespace nsAbstract
{
    using System;
    using System.Runtime.InteropServices;
    public class AbstractPro
    {
        static public void Main ()
        {
            Console.WriteLine (clsAbstract.StaticMethod());
        }
    }
    //
    // To use the abstract modifier on a method, the class also must
    // be declared as abastract
    abstract class clsAbstract
    {
    //
    // To declare an abstract method, end the declaration with a semicolon.
    // Do not provide a body for the method.
        abstract public int AbstractMethod();
    //
    // An abstract class may contain a static method. You do not have
    // to declare an instance of the class to access a static method
        static public double StaticMethod()
        {
            return (3.14159 * 3.14159);
        }
        abstract public long Prop
        {
            get;
            set;
        }
    }
    //
    // Inherit from the abstract class. The following class implements
    // the AbstractMethod().
    // The access level of the derived class method must be the same
    // as the access level of the base class abstract method.
    class clsDerivedFromAbstract : clsAbstract
    {
        override public int AbstractMethod()
        {
            return (0);
        }
        override public long Prop
        {
            get
            {
                return (val);
            }
            set
            {
                val = value;
            }
        }
        private long val;
    }
}


Use properties to set and get private members

/*
C#: The Complete Reference 
by Herbert Schildt 
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/

// Use properties to set and get private members. 
 
using System; 
 
// A class for two-dimensional objects. 
class TwoDShape { 
  double pri_width;  // now private 
  double pri_height; // now private  
 
  // Properties for width and height. 
  public double width { 
     get { return pri_width; } 
     set { pri_width = value; } 
  } 
 
  public double height { 
     get { return pri_height; } 
     set { pri_height = value; } 
  } 
 
  public void showDim() { 
    Console.WriteLine("Width and height are " + 
                       width + " and " + height); 
  } 
} 
 
// A derived class of TwoDShape for triangles. 
class Triangle : TwoDShape { 
  public string style; // style of triangle 
   
  // Return area of triangle. 
  public double area() { 
    return width * height / 2;  
  } 
 
  // Display a triangle"s style. 
  public void showStyle() { 
    Console.WriteLine("Triangle is " + style); 
  } 
} 
 
public class Shapes2 { 
  public static void Main() { 
    Triangle t1 = new Triangle(); 
    Triangle t2 = new Triangle(); 
 
    t1.width = 4.0; 
    t1.height = 4.0; 
    t1.style = "isosceles"; 
 
    t2.width = 8.0; 
    t2.height = 12.0; 
    t2.style = "right"; 
 
    Console.WriteLine("Info for t1: "); 
    t1.showStyle(); 
    t1.showDim(); 
    Console.WriteLine("Area is " + t1.area()); 
 
    Console.WriteLine(); 
 
    Console.WriteLine("Info for t2: "); 
    t2.showStyle(); 
    t2.showDim(); 
    Console.WriteLine("Area is " + t2.area()); 
  } 
}