Presentation is loading. Please wait.

Presentation is loading. Please wait.

Effective C#, Chapter 1: C# Language Elements Last Updated: Fall 2011.

Similar presentations


Presentation on theme: "Effective C#, Chapter 1: C# Language Elements Last Updated: Fall 2011."— Presentation transcript:

1 Effective C#, Chapter 1: C# Language Elements Last Updated: Fall 2011

2 C# Language Elements 2 Agenda Material From Bill Wagner Effective C#: 50 Specific Ways to Improve Your C# Cover Items 6 and 9 Goal: Compare/Contrast with Java

3 C# Language Elements 3 Item 6: Distinguish Between Value Types and Reference Types Structs or Classes? Impacts both correctness and performance C++ Objects use Struct model Plus pointers… Java Objects use Class model C# Wants to have it both ways Question: Is this a good idea?

4 C# Language Elements 4 Objections to Reference Types Setters and getters need copies Storing or returning references breaks encapsulation C# value types make copies by default But value types are not polymorphic! C# requires you to decide, upfront, between value and reference type Note Bloch’s Java solution Favor Immutability

5 C# Language Elements 5 C# Structs vs. Classes // C# Value Type // No polymorphic behavior public struct Employee { private string _name; private decimal _salary; public void Pay (BankAccount b) { b.Balance += _salary }; } // C# Reference Type // Polymorphic behavior public class Employee { private string _name; private decimal _salary; public void Pay (BankAccount b) { b.Balance += _salary }; } // Client code – Note Difference of struct vs. class Employee e1 = Employees.Find(“CEO”); e1.Salary += Bonus; // Is bonus permanent addition to salary? e1.Pay(CEOBankAccount);

6 C# Language Elements 6 Item 9: Understand Relationship Among the Many Equals C# Defines 4 different equality tests You can redefine any of them But you shouldn’t Complexity is due to value type/reference type distinction Interesting bottom line in case where C# and Java overlap Wagner and Bloch disagree! We should understand why

7 C# Language Elements 7 Four Ways To Test Equality // Object Identity – Never Redefine public static bool ReferenceEquals ( object left, object right ); // Implements Equals() as Dynamic Binding – Never Redefine public static bool Equals ( object left, object right ); // Like Java equals() for C# reference types – Redefine as needed public virtual bool Equals( object right); // Equality for value types // Nothing similar in Java // Goal of redefining is simply to improve performance public static bool operator==( MyClass left, MyClass right );

8 C# Language Elements 8 First, the Easy Cases Redefining ReferenceEquals is like redefining Java’s “==“ operator Doesn’t make sense to redefine static Equals is for dynamic binding Effect is to invoke nonstatic Equals on left hand argument Doesn’t make sense to redefine

9 C# Language Elements 9 Interesting Case: virtual Equals() Same situation as Java’s Equals() method in the Object class Same set of constraint Reflexivity Symmetry Transitivity Liskov Substitution Principle? Wagner’s recipe violates this property

10 C# Language Elements 10 Wagner’s Recipe public override bool Equals( object right ) { // in class MyType // check null if (right == null) return false; // Optimization for comparison to self if (object.ReferenceEquals( this, right )) return true; // Type check that is NOT Bloch’s recipe if (this.GetType() != right.GetType()) return false; // Alternative equivalent to Bloch’s recipe // MyType rightAsMyType = right as MyType; // if (rightAsMyType == null) return false; // Compare this type's contents here // This part is equivalent to Bloch’s recipe return CompareFooMembers( this, right as Foo ); }

11 C# Language Elements 11 Why Does Wagner Use Exact Type Matches? Remember the result in Bloch: Not possible to extend an instantiable class, add abstract state, and satisfy symmetry, transitivity, and substitution principles. Bloch’s approach: Favor composition over inheritance Save inheritance for interfaces Wagner’s approach Sacrifice substitution principle

12 C# Language Elements 12 Problem with Wagner’s Recipe public static bool myCheck (List points) { Point p =... // a Point with value (1,2) return points.Contains(p) } // Suppose the list contains subclasses of Point WITHOUT client // visible state. Then the return value should be true if a // subclass of Point with state (1,2) is in the list. // Reason: This is simply the Liskov Substitution Principle. // Of course, if the list contains subclasses WITH client visible // state, then the return value CANNOT be true if Point(1,2,x) // is in the list. // Reason: Otherwise guaranteed a Symmetry or Transitivity failure. // See Bloch, page 39 for more details of this example (in Java)


Download ppt "Effective C#, Chapter 1: C# Language Elements Last Updated: Fall 2011."

Similar presentations


Ads by Google