Generic Class example and how to use Generic Classes (format)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • raylopez99

    Generic Class example and how to use Generic Classes (format)

    Here is an example of a home grown generic class, representing a pair
    of values. Adapted from Jon Skeet's book "C# In Depth".

    The generic class is "sealed" for some reason (I think for
    performance) so you cannot derive from it, but that's optional. The
    main thing in this example is to show the right format for using these
    generic classes, which was not present in the code snippet in Skeet's
    book.

    Does anybody know why the .Equals does not work below? See //DOES NOT
    WORK--WHY? below
    I suspect it's because the equals is only compairing the shallow copy
    or references (see the hash code)

    RL

    (C) 2008 by Ray Lopez, all world rights reserved

    // Generics – from p. 84 of Jon Skeet C# in Depth
    // OUTPUT (works as expected)
    101 is: 101
    string is: Generics1.Class 1, while myClass1Pair.Fi rst.i is: 101
    myC 2: Generics1.Class 1
    myClassTwo2.myC lass1Pair.First .i: 123
    myClassTwo2.myC lass1Pair.Secon d.i: 321
    myClassTwo2.myC lass1Pair.First .j: 321
    myClassTwo2.myC lass1Pair.Secon d.j: 123
    myCl2 != myClassTwo2
    hash's are: 58225482, 54267293 //note: hash's are different so objects
    not 'equal'

    Press any key to continue . . .

    //////////////////

    using System;
    using System.Collecti ons.Generic;
    using System.Linq;
    using System.Text;

    namespace Generics1
    {
    class Program
    {
    static void Main(string[] args)
    {
    Class1 myCl1 = new Class1();
    Class2 myCl2 = new Class2();

    Console.WriteLi ne("101 is: {0}", myCl1.i);
    string s= myCl2.myClass1P air.First.ToStr ing();
    int j1 = myCl2.myClass1P air.First.i;
    Console.WriteLi ne("string is: {0}, while
    myClass1Pair.Fi rst.i is: {1}", s,j1);

    Class2 myClassTwo2 = new Class2(11.11, 123, 321);
    string s2 = myClassTwo2.myC lass1Pair.First .ToString();
    Console.WriteLi ne("myC 2: {0}", s2);
    int j2 = myClassTwo2.myC lass1Pair.First .i;
    Console.WriteLi ne("myClassTwo2 .myClass1Pair.F irst.i: {0}",
    j2);
    int j3 = myClassTwo2.myC lass1Pair.Secon d.i;
    Console.WriteLi ne("myClassTwo2 .myClass1Pair.S econd.i: {0}",
    j3);
    int j4 = myClassTwo2.myC lass1Pair.First .j;
    Console.WriteLi ne("myClassTwo2 .myClass1Pair.F irst.j: {0}",
    j4);
    int j5 = myClassTwo2.myC lass1Pair.Secon d.j;
    Console.WriteLi ne("myClassTwo2 .myClass1Pair.S econd.j: {0}",
    j5);
    if (myCl2 != myClassTwo2) Console.WriteLi ne("myCl2 !=
    myClassTwo2");
    Class2 myClassTwo22 = new Class2(11.11, 123, 321);

    if ((myClassTwo2.E quals(myClassTw o22)))
    Console.WriteLi ne("(myClassTwo 2 == myClassTwo22)") ;
    // above DOES NOT WORK--WHY? Because different references
    pointed to, even though contents equal

    int HashCode01 = myClassTwo2.Get HashCode();
    int HashCode02 = myClassTwo22.Ge tHashCode();
    Console.WriteLi ne("hash's are: {0}, {1}", HashCode01,
    HashCode02);

    }
    }
    }
    ///////////////////////////////////
    using System;
    using System.Collecti ons.Generic;
    using System.Linq;
    using System.Text;

    namespace Generics1
    {
    class Class1
    {
    public int i;
    public int j;
    Pair<int, intmyPair;

    public Class1()
    {
    myPair = new Pair<int, int>(10,10);
    i = 101;
    j = 0;
    }
    public Class1(int i, int j)
    {
    this.i = i; this.j = j;
    }
    }
    class Class2
    {
    public double d;
    public Pair<Class1, Class1myClass1P air;
    public Class2()
    {
    d = 10.0;
    myClass1Pair = new Pair<Class1, Class1>(new Class1(), new
    Class1());
    }
    public Class2(double d, int Class1Int01, int Class1Int02)
    {
    this.d = d;
    myClass1Pair = new Pair<Class1, Class1>(new
    Class1(Class1In t01, Class1Int02), new Class1(Class1In t02,
    Class1Int01));
    }
    }

    ////////// THe below is from Jon Skeet's book ////////////

    public sealed class Pair<TFirst, TSecond>
    : IEquatable<Pair <TFirst, TSecond>>
    {
    private readonly TFirst first;
    private readonly TSecond second;
    public Pair(TFirst first, TSecond second)
    {
    this.first = first;
    this.second = second;
    }
    public TFirst First
    {
    get { return first; }
    }
    public TSecond Second
    {
    get { return second; }
    }
    public bool Equals(Pair<TFi rst, TSecondother)
    {
    if (other == null)
    {
    return false;
    }
    return EqualityCompare r<TFirst>.Defau lt
    ..Equals(this.F irst, other.First) &&
    EqualityCompare r<TSecond>.Defa ult
    ..Equals(this.S econd, other.Second);
    }
    public override bool Equals(object o)
    {
    return Equals(o as Pair<TFirst, TSecond>);
    }
    public override int GetHashCode()
    {
    return EqualityCompare r<TFirst>.Defau lt
    ..GetHashCode(f irst) * 37 +
    EqualityCompare r<TSecond>.Defa ult
    ..GetHashCode(s econd);
    }
    }

    }
    //////////////////////
  • Jon Skeet [C# MVP]

    #2
    Re: Generic Class example and how to use Generic Classes (format)

    On Oct 9, 11:39 am, raylopez99 <raylope...@yah oo.comwrote:
    Here is an example of a home grown generic class, representing a pair
    of values.  Adapted from Jon Skeet's book "C# In Depth".
    >
    The generic class is "sealed" for some reason (I think for
    performance) so you cannot derive from it, but that's optional.
    The class is immutable, and immutable types are generally sealed. In
    addition, I'm a fan of the idea of sealing any class which isn't
    designed specifically to be derived from.
    > The main thing in this example is to show the right format for using these
    generic classes, which was not present in the code snippet in Skeet's
    book.
    Except you've only shown examples where TFirst = TSecond, rather than
    (say) Pair<string,int which might represent the count of a particular
    word within a corpus of text.
    Does anybody know why the .Equals does not work below?  See //DOES NOT
    WORK--WHY? below
    I suspect it's because the equals is only compairing the shallow copy
    or references (see the hash code)
    No, it's comparing them with the default equality comparer, which will
    use Equals/GetHashCode where appropriate. You haven't overridden
    either Equals or GetHashCode in Class1 or Class2, so you end up
    getting identity comparisons. Override those methods appropriately and
    all will be well.

    Jon

    Comment

    Working...