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);
}
}
}
//////////////////////
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);
}
}
}
//////////////////////
Comment