Brad Abrams
Good discussion on the first two.... Let's see how this goes.
FieldsXML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />
?FONT face="Times New Roman" size=1> Never use publicly exposed instance fields
?FONT face="Times New Roman" size=1> Properties offer more flexibility at minimal cost
?FONT face="Times New Roman" size=1> JIT inlines simple property access
?FONT face="Times New Roman" size=1> Easy to add cache or delay creation in the future
?FONT face="Times New Roman" size=1> For static fields, do not include a prefix on a public field name
?FONT face="Times New Roman" size=1> Example: 'g_' or 's_' to distinguish static vs. non-static fields
const
?FONT face="Times New Roman" size=1> Compile-time evaluation
?FONT face="Times New Roman" size=1> Stable across versions
?FONT face="Times New Roman" size=1> Always static
readonly
?FONT face="Times New Roman" size=1> Run-time evaluation
?FONT face="Times New Roman" size=1> Unstable across versions
?FONT face="Times New Roman" size=1> Static or instance
class Math {
public const double Pi = 3.14;
}
class Color {
public static readonly Color Red = new Color(...);
public static readonly Color Blue = new Color(...);
public static readonly Color Green = new Color(...);
}
Properties
?FONT face="Times New Roman" size=1> Smart fields
?FONT face="Times New Roman" size=1> Calling syntax like fields
?FONT face="Times New Roman" size=1> Flexibility of methods
?FONT face="Times New Roman" size=1> Use read only properties where appropriate
?FONT face="Times New Roman" size=1> Do not use write-only properties
?FONT face="Times New Roman" size=1> Consider raising PropertyChanged events
?FONT face="Times New Roman" size=1> Property getters should be simple and therefore unlikely to throw exceptions
?FONT face="Times New Roman" size=1> Properties should not have dependencies on each other
?FONT face="Times New Roman" size=1> Setting one property should not affect other properties
?FONT face="Times New Roman" size=1> Properties should be settable in any order
?FONT face="Times New Roman" size=1> Common to have read-only public access and protected write access
public class MyClass {
private string name;
public string Name {
get {
return name;
}
}
protected void SetName (string name)
{
this.name = name;
}
}
Properties versus Methods
?FONT face="Times New Roman" size=1> Do use a property:
?FONT face="Times New Roman" size=1> If the member has a logical data member
string Name {get;} //Good
string GetName() //Bad
GuidGetNext(){} //Good
Guid Next {get;} //Bad
?FONT face="Times New Roman" size=1> Do use a method:
?FONT face="Times New Roman" size=1> If the operation is a conversion, such as ToString()
?FONT face="Times New Roman" size=1> If the getter has an observable side effect
?FONT face="Times New Roman" size=1> If order of execution is important
?FONT face="Times New Roman" size=1> If the method might not return immediately
?FONT face="Times New Roman" size=1> If the member returns an array
EmployeeList l = FillList();
for (int i = 0; i < l.Length; i++) {
if (l.All[i] == x){...}
}
//calling code:
if (l.GetAll()[i]== x) {...}
?FONT face="Times New Roman" size=1> Creates a new snap shot of the array each time through the loop
?FONT face="Times New Roman" size=1> The GetAll() foRM makes this much clearer
Properties: Indexers
?FONT face="Times New Roman" size=1> Use if the logical backing store is an array
?FONT face="Times New Roman" size=1> Almost always int or string indexed
?FONT face="Times New Roman" size=1> Rare to have multiple indices
public char this[int index] {get;}
String s = "foo";
Console.WriteLine (s[i]); // calls indexer
Events
?FONT face="Times New Roman" size=1> Defining an event
public delegate void EventHandler(object sender,
EventArgs e);
public class Button: Control {
public event EventHandler Click;
protected void OnClick(EventArgs e) {
if (Click != null)
Click(this, e);
}
}
?FONT face="Times New Roman" size=1> Using an Event
void Initialize() {
Button b = new Button(...);
b.Click += new EventHandler(ButtonClick);
}
void ButtonClick(object sender, EventArgs e)
{
MessageBox.Show("You pressed the button");
}
?FONT face="Times New Roman" size=1> Events are raised, not triggered or fired
?FONT face="Times New Roman" size=1> Name events with a verb
?FONT face="Times New Roman" size=1> E.g.: Click, Paint, DrawItem, DropDown,
?FONT face="Times New Roman" size=1> Event handlers have void return type
public delegate void MouseEventHandler (
object sender,
MouseEventArgs e);
?FONT face="Times New Roman" size=1> Event handler delegates use a signature that follows the event design pattern
?FONT face="Times New Roman" size=1> Use strongly typed event data where appropriate
public class MouseEventArgs :
EventArgs { }
?FONT face="Times New Roman" size=1> Able to add new members without a breaking change
?FONT face="Times New Roman" size=1> Provide a protected method to raise the event
?FONT face="Times New Roman" size=1> Named OnEventName
?FONT face="Times New Roman" size=1> Make it virtual if extensibility is needed
public class Button {
private ButtonClickHandler onClickHandler;
protected void OnClick (ClickEventArgs e) {
if (onClickHandler != null) {
// call the delegate if non-null
onClickHandler(this, e);
}
}
}
?FONT face="Times New Roman" size=1> Events are callbacks into arbitrary user code
?FONT face="Times New Roman" size=1> Do not assume anything about the state of your object
?FONT face="Times New Roman" size=1> Code defensively
protected void DoClick() {
PaintDown(); // paint button in depressed state
try {
OnClick(); // call event handler
}
finally {
// window may be deleted in event handler
if (windowHandle != null) {
PaintUp(); // paint button in normal state
}
}
}
Static Members
?FONT face="Times New Roman" size=1> Any kind of member can be static
?FONT face="Times New Roman" size=1> Static members
?FONT face="Times New Roman" size=1> Cannot access instance state
?FONT face="Times New Roman" size=1> Cannot override or specialize
?FONT face="Times New Roman" size=1> Should be thread-safe
?FONT face="Times New Roman" size=1> Commonly used for
?FONT face="Times New Roman" size=1> Singleton pattern
?FONT face="Times New Roman" size=1> Utility methods
?FONT face="Times New Roman" size=1> Statics are the ..NET equivalent of global variables or global functions
?FONT face="Times New Roman" size=1> Not object oriented
?FONT face="Times New Roman" size=1> Same evils as global
?FONT face="Times New Roman" size=1> But can be very useful, e.g., System.Math
Singleton Pattern
?FONT face="Times New Roman" size=1> Ensures that a class has only one instance and provide a global point of access to it
?FONT face="Times New Roman" size=1> This is not exactly the GoF pattern (see threading section)
public sealed class dbNull {
private DBNull() {}
public static readonly DBNull Value = new DBNull();
// instance Methods...
}
//Calling code
if (x == DBNull.Value) {..}
?FONT face="Times New Roman" size=1> Notice this class:
?FONT face="Times New Roman" size=1> Is sealed to prevent sub-classing to add instances
?FONT face="Times New Roman" size=1> The Value is static for easy access
?FONT face="Times New Roman" size=1> The Value is readonly so it cannot be modified
?FONT face="Times New Roman" size=1> Has a private constructor
?FONT face="Times New Roman" size=1> The instance is immutable
?FONT face="Times New Roman" size=1> No methods that can mutate its state
Parameter Passing
?FONT face="Times New Roman" size=1> Value types and Reference types can both be passed by value or by reference
?FONT face="Times New Roman" size=1> A value type by value copies the value
?FONT face="Times New Roman" size=1> No side effects
?FONT face="Times New Roman" size=1> Commonly used
public int Add (int x, int y) {..}
?FONT face="Times New Roman" size=1> A value type by reference uses a pointer to the value
?FONT face="Times New Roman" size=1> Side effects possible
?FONT face="Times New Roman" size=1> Rarely used
public static int Exchange (ref int location, int value) {..}
?FONT face="Times New Roman" size=1> A reference type by value copied the reference
?FONT face="Times New Roman" size=1> Side effects are possible on mutable types
?FONT face="Times New Roman" size=1> Commonly used
public void Insert (object value) {..}
?FONT face="Times New Roman" size=1> A reference type by reference uses a pointer to the reference variable
?FONT face="Times New Roman" size=1> Side effects possible
?FONT face="Times New Roman" size=1> Almost never used
public static int Method (ref object moreData) {..}
?FONT face="Times New Roman" size=1> Using Ref and Out parameters
?FONT face="Times New Roman" size=1> Primarily used for interop
?FONT face="Times New Roman" size=1> Avoid directly exposing publicly
?FONT face="Times New Roman" size=1> May be used for extremely performance-sensitive areas
?FONT face="Times New Roman" size=1> Almost exclusively used with value types
?FONT face="Times New Roman" size=1> Ref is a CLR feature
?FONT face="Times New Roman" size=1> Out is a C# feature
?FONT face="Times New Roman" size=1> Out parameter semantics downgrade to Ref semantics in other languages
?FONT face="Times New Roman" size=1> Ref and out designs are less usable
public void GetLocation (
ref int x, out int y) {..}
//calling code
int x = 42;
int y;
b.GetLocation (ref x, out y);
public struct Point {
public int X {get;}
public int Y {get;}
}
//calling code
Point p = b.Location;
Argument Validation
?FONT face="Times New Roman" size=1> Do argument checking on every publicly exposed member
?FONT face="Times New Roman" size=1> Catches errors early (fail-fast)
?FONT face="Times New Roman" size=1> Much easier to debug
?FONT face="Times New Roman" size=1> Powerful security precaution
?FONT face="Times New Roman" size=1> Throw meaningful exceptions
?FONT face="Times New Roman" size=1> Subclasses of ArgumentException
public int Count {
get {return count;}
set {
if (value < 0 || value >= MaxValue)
throw new ArgumentException(..);
}
}
public void select (int start, int end) {
if (start < 0)
throw new ArgumentException(..);
if (end < start)
throw new ArgumentException(..);
}
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-998938/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/10752043/viewspace-998938/