Csharp/C Sharp/Class Interface/Properties
Версия от 15:31, 26 мая 2010; (обсуждение)
Содержание
- 1 access to a private field through a property
- 2 Add Length property to FailSoftArray
- 3 A simple property example
- 4 Convert errflag into a property
- 5 Define properties for class
- 6 Delegates as Static Properties
- 7 Demonstrates the use of properties to control how values are saved in fields
- 8 enum based attribute
- 9 Error handling in property setter validating
- 10 Illustrates the use of a property
- 11 Override Properties
- 12 Properties Accessors
- 13 Properties: Side Effects When Setting Values
- 14 Properties:Static Properties
- 15 Properties: Use of Properties
- 16 Properties:Virtual Properties
- 17 The use of an abstract property
- 18 Use properties to set and get private members
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());
}
}