|
using System;
using System.Collections.Generic;
// A program to test and demonstrate the difference between reference and value types when used in comparisons
// and as keys to dictionaries.
namespace refvaluetests
{
public struct AStruct
{
private readonly int i;
public int I
{
get { return i; }
}
public AStruct(int i)
{
this.i = i;
}
}
public struct AStructWithOperatorEquals
{
private readonly int i;
public AStructWithOperatorEquals(int i)
{
this.i = i;
}
public static bool operator ==(AStructWithOperatorEquals s1, AStructWithOperatorEquals s2)
{
bool ret = false;
if (((object)s1 != null) && ((object)s2 != null))
{
ret = s1.i == s2.i;
}
return ret;
}
/// <summary>
/// If one is defined, the other is required.
/// </summary>
public static bool operator !=(AStructWithOperatorEquals s1, AStructWithOperatorEquals s2)
{
return !(s1 == s2);
}
/// <summary>
/// Also this is required!
/// </summary>
public override bool Equals(object obj)
{
bool ret = false;
if (!(obj is AStructWithOperatorEquals))
{
ret = false;
}
else
{
ret = i == ((AStructWithOperatorEquals)obj).i;
}
return ret;
}
/// <summary>
/// Avoid the compiler warning by implementing this method.
/// </summary>
public override int GetHashCode()
{
return base.GetHashCode();
}
}
public class AClass
{
private readonly int i;
public int I
{
get { return i; }
}
private AClass() { }
public AClass(int i)
{
this.i = i;
}
}
public class AnEqualsClass
{
public readonly int i;
private AnEqualsClass() { }
public AnEqualsClass(int i)
{
this.i = i;
}
public override bool Equals(object obj)
{
bool ret = false;
AnEqualsClass s = obj as AnEqualsClass;
if (s == null)
{
ret = false;
}
else
{
ret = i == s.i;
}
return ret;
}
/// <summary>
/// Avoid the compiler warning by implementing this method.
/// We need this method for Equals to work with generics like lists and Dictionaries.
/// </summary>
public override int GetHashCode()
{
// This is very important!
// We return the hash code of our field, not the base algorithm.
// The base algorithm returns different values for different instances.
// RIGHT:
return i.GetHashCode();
// WRONG:
// return base.GetHashCode();
}
}
public class AnOperatorEqualClass
{
private readonly int i;
public int I
{
get { return i; }
}
private AnOperatorEqualClass() { }
public AnOperatorEqualClass(int i)
{
this.i = i;
}
public static bool operator ==(AnOperatorEqualClass s1, AnOperatorEqualClass s2)
{
bool ret = false;
if (((object)s1 != null) && ((object)s2 != null))
{
ret = s1.i == s2.i;
}
return ret;
}
/// <summary>
/// If one is defined, the other is required.
/// </summary>
public static bool operator !=(AnOperatorEqualClass s1, AnOperatorEqualClass s2)
{
return !(s1 == s2);
}
/// <summary>
/// Also this is required!
/// </summary>
public override bool Equals(object obj)
{
bool ret = false;
AnOperatorEqualClass s = obj as AnOperatorEqualClass;
if (s==null)
{
ret = false;
}
else
{
ret = i == s.i;
}
return ret;
}
/// <summary>
/// Avoid the compiler warning by implementing this method.
/// </summary>
public override int GetHashCode()
{
// This is very important!
// We return the hash code of our field, not the base algorithm.
// The base algorithm returns different values for different instances.
return i.GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
CompareStructs();
CompareStructsWithOperatorEquals();
CompareClasses();
CompareEqualsClasses();
CompareOperatorEqualClasses();
IndexStructs();
IndexClasses();
IndexEqualsClasses();
DictionaryStruct();
DictionaryClasses();
DictionaryEqualsClasses();
Console.WriteLine("\r\n");
}
static void CompareStructs()
{
Console.WriteLine("CompareStructs:");
AStruct s1 = new AStruct(10);
AStruct s2 = new AStruct(10);
Console.WriteLine("AStruct.Equals(AStruct) ? " + ((s1.Equals(s2)) ? "Yes" : "No"));
// operator == cannot be applied to operands AStruct because operator == is not implemented.
// Console.WriteLine("s1 == s2 ? " + ((s1 == s2) ? "Yes" : "No"));
}
static void CompareStructsWithOperatorEquals()
{
Console.WriteLine("\r\nCompareStructsWithOperatorEquals:");
AStructWithOperatorEquals s1 = new AStructWithOperatorEquals(10);
AStructWithOperatorEquals s2 = new AStructWithOperatorEquals(10);
Console.WriteLine("s1 == s2 ? " + ((s1 == s2) ? "Yes" : "No"));
}
static void CompareClasses()
{
Console.WriteLine("\r\nCompareClasses:");
AClass s1 = new AClass(10);
AClass s2 = new AClass(10);
Console.WriteLine("AClass.Equals(AClass) ? " + ((s1.Equals(s2)) ? "Yes" : "No"));
Console.WriteLine("s1 == s2 ? " + ((s1 == s2) ? "Yes" : "No"));
}
static void CompareEqualsClasses()
{
Console.WriteLine("\r\nCompareEqualsClasses:");
AnEqualsClass s1 = new AnEqualsClass(10);
AnEqualsClass s2 = new AnEqualsClass(10);
Console.WriteLine("AnEqualsClass.Equals(AnEqualsClass) ? " + ((s1.Equals(s2)) ? "Yes" : "No"));
Console.WriteLine("s1 == s2 ? " + ((s1 == s2) ? "Yes" : "No"));
}
static void CompareOperatorEqualClasses()
{
Console.WriteLine("\r\nCompareOperatorEqualClasses:");
AnOperatorEqualClass s1 = new AnOperatorEqualClass(10);
AnOperatorEqualClass s2 = new AnOperatorEqualClass(10);
Console.WriteLine("AnOperatorEqualsClass.Equals(AnOperatorEqualsClass) ? " + ((s1.Equals(s2)) ? "Yes" : "No"));
Console.WriteLine("s1 == s2 ? " + ((s1 == s2) ? "Yes" : "No"));
}
static void IndexStructs()
{
Console.WriteLine("\r\nIndexStructs:");
List<AStruct> list = new List<AStruct>();
AStruct s1 = new AStruct(10);
list.Add(s1);
AStruct s2 = new AStruct(10);
Console.WriteLine("List contains s2 : " + list.Contains(s2));
}
static void IndexClasses()
{
Console.WriteLine("\r\nIndexClasses:");
List<AClass> list = new List<AClass>();
AClass s1 = new AClass(10);
list.Add(s1);
AClass s2 = new AClass(10);
Console.WriteLine("List contains s2 : " + list.Contains(s2));
}
static void IndexEqualsClasses()
{
Console.WriteLine("\r\nIndexEqualsClasses:");
List<AnEqualsClass> list = new List<AnEqualsClass>();
AnEqualsClass s1 = new AnEqualsClass(10);
list.Add(s1);
AnEqualsClass s2 = new AnEqualsClass(10);
Console.WriteLine("List contains s2 : " + list.Contains(s2));
}
static void DictionaryStruct()
{
Console.WriteLine("\r\nDictionaryStruct:");
Dictionary<AStruct, int> dict = new Dictionary<AStruct, int>();
AStruct s1 = new AStruct(10);
dict[s1] = 1;
AStruct s2 = new AStruct(10);
Console.WriteLine("Dictionary contains s2 : " + dict.ContainsKey(s2));
}
static void DictionaryClasses()
{
Console.WriteLine("\r\nDictionaryClasses:");
Dictionary<AClass, int> dict = new Dictionary<AClass, int>();
AClass s1 = new AClass(10);
dict[s1] = 1;
AClass s2 = new AClass(10);
Console.WriteLine("Dictionary contains s2 : " + dict.ContainsKey(s2));
}
static void DictionaryEqualsClasses()
{
Console.WriteLine("\r\nDictionaryEqualsClasses:");
Dictionary<AnEqualsClass, int> dict = new Dictionary<AnEqualsClass, int>();
AnEqualsClass s1 = new AnEqualsClass(10);
dict[s1] = 1;
AnEqualsClass s2 = new AnEqualsClass(10);
Console.WriteLine("Dictionary contains s2 : " + dict.ContainsKey(s2));
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.