Presentation is loading. Please wait.

Presentation is loading. Please wait.

E FFECTIVE C# 50 Specific Ways to Improve Your C# Second Edition Bill Wagner محمد حسین سلطانی.

Similar presentations


Presentation on theme: "E FFECTIVE C# 50 Specific Ways to Improve Your C# Second Edition Bill Wagner محمد حسین سلطانی."— Presentation transcript:

1 E FFECTIVE C# 50 Specific Ways to Improve Your C# Second Edition Bill Wagner محمد حسین سلطانی

2 1- U SE P ROPERTIES I NSTEAD OF P UBLIC D ATA M EMBERS Properties enable you to create an interface that acts like data access but still has all the benefits of a method. Client code accesses properties as though they are accessing public fields. But the actual implementation uses methods The data binding classes in the.NET Framework support properties, not public data members. sample code: textBoxCity.DataBindings.Add("Text",address, "City");

3 Because properties are implemented with methods, adding multithreaded support is easier. Sample code: public class Customer { private object syncHandle = new object(); private string name; public string Name { get { lock (syncHandle) return name; } set { if (string.IsNullOrEmpty(value)) throw new ArgumentException("Name cannot be blank“,"Name"); lock (syncHandle) name = value; } // More Elided. }

4 Properties have all the language features of methods. Properties can be virtual: public class Customer { public virtual string Name { get; set; } You can extend properties to be abstract and define properties as part of an interface definition

5 Sample code: public interface INameValuePair { string Name { get; } T Value { get; set; } Anything you can do with member functions, you can do with properties If your type should contain indexed items as part of its interface, you can use indexers (which are parameterized properties)

6 public int this[int index] { get { return theValues[index]; } set { theValues[index] = value; } } // Accessing an indexer: int val = someObject[i]; Notice that all indexers are declared with the this keyword. You cannot name an indexer in C# Properties will not be faster than data member access, but they might not be any slower Get accessors should not have observable side effects. Set accessors do modify the state, and users should be able to see those changes All data members should be private, without exception

7 2- P REFER READONLY TO CONST C# has two different versions of constants: compile-time constants and runtime constants Compile-time constants are slightly faster, but far less flexible, than runtime constants. a slower, correct program is better than a faster, broken program // Compile time constant: public const int Millennium = 2000; // Runtime constant: public static readonly int ThisYear = 2004;

8 Compile-time constants can be declared inside methods.Read-only constants cannot be declared with method scope A compile-time constant is replaced with the value of that constant in your object code: if (myDateTime.Year == Millennium) compiled to the same IL as if you had written this: if (myDateTime.Year == 2000)

9 Compile-time constants can be used only for primitive types (built-in integral and floating-point types), enums, or strings. You cannot initialize a compile-time constant using the new operator Compile-time constants are limited to numbers and strings but runtime constants can be any type

10 I TEM 3: P REFER THE IS OR AS O PERATORS TO C ASTS The correct choice is to use the as operator whenever you can Comparing two types: Type 1: object o = Factory.GetObject(); // Version one: MyType t = o as MyType; if (t != null) { // work with t, it's a MyType. } else { // report the failure. }

11 Type 2: object o = Factory.GetObject(); // Version two: try { MyType t; t = (MyType)o; // work with T, it's a MyType. } catch (InvalidCastException) { // report the conversion failure. } the first version is simpler and easier to read. It does not have the try/catch clause. Using as, you simply check the returned reference against null. cast version must check null in addition to catching exceptions

12 The as operator does not work on value types. This statement won’t compile: object o = Factory.GetValue(); int i = o as int; // Does not compile. That’s because ints are value types and can never be null object o = Factory.GetValue(); int i = 0; try { i = (int)o; } catch (InvalidCastException) { i = 0; } You can use the is statement to remove the chance of exceptions or conversions:

13 object o = Factory.GetValue(); int i = 0; if (o is int) i = (int)o; The is operator should be used only when you cannot convert the type using as. The is operator always returns false for null arguments or not casted types If you’re about to convert a type using as, the is check is simply not necessary MyType t = null; if (o is MyType) t = o as MyType; foreach uses a cast operation to perform conversions from an object to the type used in the loop. foreach (MyType t in theCollection) t.DoStuff( ); Equals this code: IEnumerator it = theCollection.GetEnumerator(); while (it.MoveNext()) { MyType t = (MyType)it.Current; t.DoStuff(); }

14 foreach needs to use casts to support both value types and reference types The GetType() method gets the runtime type of an object Good object-oriented practice says that you should avoid converting types, but sometimes there are no alternatives. If you can’t avoid the conversions, use the language’s as and is operators to express your intent more clearly.

15 I TEM 4: U SE C ONDITIONAL A TTRIBUTES I NSTEAD OF # IF #if/#endif blocks have been used to produce different builds from the same source Use the Conditional attribute instead of #if/#endif blocks when you create conditional code blocks The StackTrace class gets the name of the calling method using Reflection The Debug.Assert method tests a condition and stops the program if that condition is false. The remaining parameters define messages The Conditional attribute tells the C# compiler that this method should be called only when the compiler detects the DEBUG environment variable.

16 [Conditional("DEBUG")] private void CheckState() { // same code as above } Whether the DEBUG environment variable is defined or not, the CheckState() method is compiled and delivered with the assembly The only cost is disk space. The CheckState() function does not get loaded into memory Multiple conditional attributes: [Conditional("DEBUG"), // in Debug or Trace Conditional("TRACE")] private void CheckState() #if ( VAR1 && VAR2 )// in Both cases #define BOTH #endif

17 Any method with a Conditional attribute must have a return type of void Any method marked with the Conditional attribute should not take any parameters

18 I TEM 5: A LWAYS P ROVIDE T O S TRING () You should write a reasonable version for all the clients of your class Every type that you create should provide a reasonable override of this method The System.Object version returns the fully qualified name of the type int[] list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; var test = new { Name = "Me", Numbers = from l in list select l }; Console.WriteLine(test); will display: { Name = Me, Numbers = System.Linq.Enumerable+WhereSelectArrayIterator`2 [System.Int32,System.Int32] }


Download ppt "E FFECTIVE C# 50 Specific Ways to Improve Your C# Second Edition Bill Wagner محمد حسین سلطانی."

Similar presentations


Ads by Google