I agree and I think my code is a case of immutable objects. What I am doing
is using generics to produce strongly type Guid based object identifiers.
Basically if I declare a class A, rather than declaring an ID property as
type Guid I declare it as type Identifier<A> using the following code. This
gives me strong typing for situations where I have an overloaded method that
can act on various objects by ID but needs to know the object type as well.
Does this sound like a userful thing? I invite critisism. I like strong
typing but may be going a bit far here.
/// <summary>
/// This class encapsulates a Guid that is used as an identifier so that
strongly typed
/// Guid based identifer types can be derived from it. It is marked
abastract because
/// direct instatiation of this type would circumvent strong typing.
/// </summary>
[Serializable]
public abstract class GuidIdentifier
{
private Guid idValue;
/// <summary>
/// Creates a new GuidIdentifier object with a new Guid value.
/// </summary>
protected GuidIdentifier()
{
this.idValue = Guid.NewGuid();
}
/// <summary>
/// Creates a new GuidIdentifier object with the provided Guid as
its underlying value.
/// </summary>
/// <param name="value">The Guid value to which to intitialize the
identifer.</param>
protected GuidIdentifier( Guid value )
{
this.idValue = value;
}
/// <summary>
/// Returns the actual Guid value of the identifier.
/// </summary>
public Guid Value { get { return idValue; } }
public override bool Equals( object obj )
{
if ( obj.GetType() == this.GetType() )
return GuidIdentifier.Equals( this , (
GuidIdentifier )obj );
else
return false;
}
public override int GetHashCode()
{
return this.Value.GetHashCode();
}
public override string ToString()
{
return string.Format( "ID: {0:B}" , idValue );
}
public static bool operator ==( GuidIdentifier a , GuidIdentifier
b )
{
return GuidIdentifier.Equals( a , b );
}
public static bool operator !=( GuidIdentifier a , GuidIdentifier
b )
{
return !GuidIdentifier.Equals( a , b );
}
/// <summary>
/// Compares two GuidIdentifiers, returns true if their underlying
Guid values are the same.
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns>True if GuidIdentifier a.Value == GuidIdentifier
b.Value</returns>
public static bool Equals( GuidIdentifier a , GuidIdentifier b )
{
if ( object.Equals( a , null ) || object.Equals( b , null ) )
//will return true if both objects are null, false otherwise
return object.Equals( a , b );
else
return a.idValue == b.idValue;
}
}
/// <summary>
/// This class is a generic implementation of GuidIdentifier which
allows for
/// strongly typed Guid based identifiers that derive from a common base
class.
/// </summary>
/// <typeparam name="T">The type of the class of which
Identifier<T> identifies an instance.</typeparam>
public class Identifier<T> : GuidIdentifier where T : BusinessBase<T>
{
/// <summary>
/// Creates a new Identifier instance having a new Guid value;
/// </summary>
public Identifier() : base() { }
/// <summary>
/// Creates a new Identifier instance having the specified Guid
value;
/// </summary>
/// <param name="value">The Guid value of the identifier</param>
public Identifier( Guid value ) : base( value ) { }
}
Note I use the pattern where one defines a non-generic class that provides
for a common type for the generic sub-classes. (Is there a name for this
pattern? I see it used a lot but never see a name.)
Any comments or critisism would be appreciated.
--Ken
"Barry Kelly" <ba***********@gmail.com> wrote in message
news:g8********************************@4ax.com...
"Kenneth Baltrinic" <no***************@nowhere.xyz> wrote:
When one overrides the Equals() method of an object, one is supposed to
override GetHashCode() as well and this makes good sense. But I have
seen
lots of people who do this and do not override the == and != opperators.
Am
I missing something or when would one want to have different
implementations
for Equals and ==?
If you have a mutable reference type, it may be meaningful to compare it
with other types with (say) object.Equals(object,object), but because
the two references do not actually refer to the same object, you still
want reference-based comparison using the '==' and '!=' operators.
If you have an immutable reference type (such as System.String), it
makes much more sense to override '==' and '!='.
-- Barry