
Generics and comparison (follow on from my previous "Generics and collections" thread)
This is a multi-part message in MIME format.
------=_NextPart_000_000C_01C8967C.C0148320
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Marc has sorted my problem with the collections, however I am now in a =
new scenario; I am trying to compare a generic property value before =
setting it as shown below ...
public T Value {
get { return this.value; }
set {
if ( this.value !=3D value ) {
this.value =3D value;
this.OnValueChanged(EventArgs.Empty);
}
}
}
This code produces the Operator '=3D=3D' cannot be applied to operands =
of type 'T' and 'T' error at compile time!
I am sure that I am not the only person to have tried this, any clues as =
to the correct work around?
I have tried restricting 'T' to IComparable in a where clause and then =
casting 'this.value' and 'value' to IComparable for the comparison - the =
code then compiles but is this the right answer? It feels wrong, but I =
am quickly learning that my own understanding of generics is much lower =
than I thought it was!
Thanks in advance.
------=_NextPart_000_000C_01C8967C.C0148320
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.6000.16608" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Marc has sorted my problem with the =
collections,
however I am now in a new scenario; I am trying to compare a generic =
property
value before setting it as shown below ...</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV><FONT face=3DArial =
size=3D2><FONT
size=3D1>
<DIV></FONT><FONT color=3D#0000ff> public</FONT><FONT
size=3D1><FONT size=3D2> T Value {</FONT></DIV>
<DIV></FONT><FONT color=3D#0000ff> =
get</FONT>
{ <FONT color=3D#0000ff>return</FONT> <FONT =
color=3D#0000ff>this</FONT><FONT
size=3D1><FONT size=3D2>.value; }</FONT></DIV>
<DIV></FONT><FONT color=3D#0000ff>
set</FONT><FONT size=3D1><FONT size=3D2> {</FONT></DIV>
<DIV></FONT><FONT color=3D#0000ff>
if</FONT> ( <FONT color=3D#0000ff>this</FONT>.value =
!=3D <FONT
color=3D#0000ff>value</FONT><FONT size=3D1><FONT size=3D2> ) =
{</FONT></DIV>
<DIV></FONT><FONT color=3D#0000ff>
this</FONT>.value =3D <FONT
color=3D#0000ff>value</FONT><FONT size=3D1><FONT size=3D2>;</FONT></DIV>
<DIV></FONT><FONT color=3D#0000ff>
this</FONT>.OnValueChanged(<FONT
color=3D#2b91af>EventArgs</FONT><FONT size=3D1><FONT =
size=3D2>.Empty);</FONT></DIV>
<DIV><FONT size=3D2> =
}</FONT></DIV>
<DIV><FONT size=3D2> }</FONT></DIV>
<DIV><FONT size=3D2> }</FONT></DIV></FONT></FONT>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>This code produces the <FONT
color=3D#ff0000><EM>Operator '=3D=3D' cannot be applied to operands of =
type 'T' and
'T'</EM></FONT> error at compile time!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>I am sure that I am not the only person =
to have
tried this, any clues as to the correct work around?</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I have tried restricting 'T' to =
IComparable in a
where clause and then casting 'this.value' and 'value' to IComparable =
for the
comparison - the code then compiles but is this the right answer? It =
feels
wrong, but I am quickly learning that my own understanding of generics =
is much
lower than I thought it was!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Thanks in advance.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV></BODY></HTML>
------=_NextPart_000_000C_01C8967C.C0148320--
Re: Generics and comparison (follow on from my previous "Generics and collections" thread)
Martin Robins wrote:
> Marc has sorted my problem with the collections, however I am now in
> a new scenario; I am trying to compare a generic property value
> before setting it as shown below ...
>
> public T Value {
> get { return this.value; }
> set {
> if ( this.value != value ) {
> this.value = value;
> this.OnValueChanged(EventArgs.Empty);
> }
> }
> }
>
> This code produces the Operator '==' cannot be applied to operands of
> type 'T' and 'T' error at compile time!
You'll have to put a constraint on T (where clause), so that it only
applies to instances that implement IEquitable<T>, and then use
IEquitable<T>.Equals() to check for equality.
You can also, somehow, omit the constraint and provide the class an
instance of IComparer or IEqualityComparer, to do the work for you.
That has advantages, but also disadvantages.
--
Rudy Velthuis http://rvelthuis.de
"RAM /abr./: Rarely Adequate Memory." -- From the Jargon File
Re: Generics and comparison (follow on from my previous "Generics and collections" thread)
This is a multi-part message in MIME format.
------=_NextPart_000_005E_01C89689.9C2203E0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Though it compiles, the original IComparable idea did not work; the =
comparisons would often return incorrect results.
I have resolved it for now using "if ( this.value =3D=3D null ? value =
!=3D null : !this.value.Equals(value) )" but I am still open to a better =
way if it exists ...
Martin.
"Martin Robins" <martin at orpheus-solutions dot co dot uk> wrote in =
message news:ujRpfRnlIHA.536 [at] TK2MSFTNGP06.phx.gbl...
Marc has sorted my problem with the collections, however I am now in a =
new scenario; I am trying to compare a generic property value before =
setting it as shown below ...
public T Value {
get { return this.value; }
set {
if ( this.value !=3D value ) {
this.value =3D value;
this.OnValueChanged(EventArgs.Empty);
}
}
}
This code produces the Operator '=3D=3D' cannot be applied to operands =
of type 'T' and 'T' error at compile time!
I am sure that I am not the only person to have tried this, any clues =
as to the correct work around?
I have tried restricting 'T' to IComparable in a where clause and then =
casting 'this.value' and 'value' to IComparable for the comparison - the =
code then compiles but is this the right answer? It feels wrong, but I =
am quickly learning that my own understanding of generics is much lower =
than I thought it was!
Thanks in advance.
------=_NextPart_000_005E_01C89689.9C2203E0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.6000.16608" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Though it compiles, the original =
IComparable idea
did not work; the comparisons would often return incorrect =
results.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I have resolved it for now using "<FONT =
color=3D#0000ff>if</FONT> ( <FONT color=3D#0000ff>this</FONT>.value =
=3D=3D <FONT
color=3D#0000ff>null</FONT> ? <FONT color=3D#0000ff>value</FONT> !=3D =
<FONT
color=3D#0000ff>null</FONT> : !<FONT =
color=3D#0000ff>this</FONT>.value.Equals(<FONT
color=3D#0000ff>value</FONT>) )" but I am still open to a better way if =
it exists
....</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Martin.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<BLOCKQUOTE dir=3Dltr
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Martin Robins" <martin at orpheus-solutions dot co dot uk> =
wrote
in message <A
=
href=3D"news:ujRpfRnlIHA.536 [at] TK2MSFTNGP06.phx.gbl">news:ujRp fRnlIHA.536 [at] T=
K2MSFTNGP06.phx.gbl</A>...</DIV>
<DIV><FONT face=3DArial size=3D2>Marc has sorted my problem with the =
collections,
however I am now in a new scenario; I am trying to compare a generic =
property
value before setting it as shown below ...</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV><FONT face=3DArial =
size=3D2><FONT
size=3D1>
<DIV></FONT><FONT color=3D#0000ff> =
public</FONT><FONT
size=3D1><FONT size=3D2> T Value {</FONT></DIV>
<DIV></FONT><FONT color=3D#0000ff> =
get</FONT> { <FONT color=3D#0000ff>return</FONT> <FONT
color=3D#0000ff>this</FONT><FONT size=3D1><FONT size=3D2>.value; =
}</FONT></DIV>
<DIV></FONT><FONT color=3D#0000ff> =
set</FONT><FONT size=3D1><FONT size=3D2> {</FONT></DIV>
<DIV></FONT><FONT color=3D#0000ff> =
if</FONT> ( <FONT color=3D#0000ff>this</FONT>.value =
!=3D <FONT
color=3D#0000ff>value</FONT><FONT size=3D1><FONT size=3D2> ) =
{</FONT></DIV>
<DIV></FONT><FONT color=3D#0000ff> =
this</FONT>.value =3D <FONT
color=3D#0000ff>value</FONT><FONT size=3D1><FONT =
size=3D2>;</FONT></DIV>
<DIV></FONT><FONT color=3D#0000ff> =
this</FONT>.OnValueChanged(<FONT =
color=3D#2b91af>EventArgs</FONT><FONT size=3D1><FONT =
size=3D2>.Empty);</FONT></DIV>
<DIV><FONT size=3D2> =
}</FONT></DIV>
<DIV><FONT size=3D2> =
}</FONT></DIV>
<DIV><FONT size=3D2> }</FONT></DIV></FONT></FONT>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>This code produces the <FONT
color=3D#ff0000><EM>Operator '=3D=3D' cannot be applied to operands of =
type 'T' and
'T'</EM></FONT> error at compile time!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>I am sure that I am not the only =
person to have
tried this, any clues as to the correct work around?</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I have tried restricting 'T' to =
IComparable in a
where clause and then casting 'this.value' and 'value' to IComparable =
for the
comparison - the code then compiles but is this the right answer? It =
feels
wrong, but I am quickly learning that my own understanding of generics =
is much
lower than I thought it was!</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Thanks in advance.</FONT></DIV>
<DIV><FONT face=3DArial =
size=3D2></FONT> </DIV></BLOCKQUOTE></BODY></HTML>
------=_NextPart_000_005E_01C89689.9C2203E0--
Re: Generics and comparison (follow on from my previous "Generics and collections" thread)
Rudy,
Interesting interface (IEquatable); not seen that one before.
Will let you know if this works for me.
Thanks.
"Rudy Velthuis" <newsgroups [at] rvelthuis.de> wrote in message
news:xn0fojkh62vieo1003 [at] news.microsoft.com...
> Martin Robins wrote:
>
>> Marc has sorted my problem with the collections, however I am now in
>> a new scenario; I am trying to compare a generic property value
>> before setting it as shown below ...
>>
>> public T Value {
>> get { return this.value; }
>> set {
>> if ( this.value != value ) {
>> this.value = value;
>> this.OnValueChanged(EventArgs.Empty);
>> }
>> }
>> }
>>
>> This code produces the Operator '==' cannot be applied to operands of
>> type 'T' and 'T' error at compile time!
>
> You'll have to put a constraint on T (where clause), so that it only
> applies to instances that implement IEquitable<T>, and then use
> IEquitable<T>.Equals() to check for equality.
>
> You can also, somehow, omit the constraint and provide the class an
> instance of IComparer or IEqualityComparer, to do the work for you.
> That has advantages, but also disadvantages.
> --
> Rudy Velthuis http://rvelthuis.de
>
> "RAM /abr./: Rarely Adequate Memory." -- From the Jargon File
Re: Generics and comparison (follow on from my previous "Generics and collections" thread)
Martin Robins wrote:
> Though it compiles, the original IComparable idea did not work; the
> comparisons would often return incorrect results.
That is a problem with the implementation of the interface for that
particular instantiation of T, then. If it were correctly implemented,
that should not happen.
--
Rudy Velthuis http://rvelthuis.de
"Sailors ought never to go to church. They ought to go to hell,
where it is much more comfortable." -- HG Wells.
Re: Generics and comparison (follow on from my previous "Generics and collections" thread)
"Martin Robins" <martin at orpheus-solutions dot co dot uk> wrote:
> Marc has sorted my problem with the collections, however I am now
> in a new scenario; I am trying to compare a generic property value
> before setting it as shown below ...
>
> public T Value {
> get { return this.value; }
> set {
> if ( this.value != value ) {
> this.value = value;
> this.OnValueChanged(EventArgs.Empty);
> }
> }
> }
>
> This code produces the Operator '==' cannot be applied to operands of type
> 'T' and 'T' error at compile time!
> I am sure that I am not the only person to have tried this, any clues as
> to the correct work around?
The normal pattern for comparing values of a generic type is to use
Comparer<T>.Default (if you need ordering) or
EqualityComparer<T>.Default (if you need equality and hashing).
EqualityComparer<T>.Default delegates to an IEquatable<T> interface if
it exists, or fall back to the Object.Equals override, if any.
Then, if you deal with some T where you want to customize behaviour
(strings come to mind - do you want case-sensitive versus insensitive
behaviour?), you create an overloaded constructor which takes an
IEqualityComparer<T> instance, and pass EqualityComparer<T>.Default in
the other overload. All comparisons should be done through the cached
interface value.
For the concrete case of strings, you can then use
StringComparer.Ordinal, StringComparer.InvariantCultureIgnoreCase, as
the argument etc.
-- Barry
--
http://barrkel.blogspot.com/
Re: Generics and comparison (follow on from my previous "Generics and collections" thread)
Barry,
Thanks; that seems to have done the trick (in as much as it is providing the
correct results).
Martin.
"Barry Kelly" <barry.j.kelly [at] gmail.com> wrote in message
news:8ujdv35e4jl1jmbprf6kkppc2dg9vdpc1m [at] 4ax.com...
> "Martin Robins" <martin at orpheus-solutions dot co dot uk> wrote:
>
>> Marc has sorted my problem with the collections, however I am now
>> in a new scenario; I am trying to compare a generic property value
>> before setting it as shown below ...
>>
>> public T Value {
>> get { return this.value; }
>> set {
>> if ( this.value != value ) {
>> this.value = value;
>> this.OnValueChanged(EventArgs.Empty);
>> }
>> }
>> }
>>
>> This code produces the Operator '==' cannot be applied to operands of
>> type
>> 'T' and 'T' error at compile time!
>> I am sure that I am not the only person to have tried this, any clues as
>> to the correct work around?
>
> The normal pattern for comparing values of a generic type is to use
> Comparer<T>.Default (if you need ordering) or
> EqualityComparer<T>.Default (if you need equality and hashing).
>
> EqualityComparer<T>.Default delegates to an IEquatable<T> interface if
> it exists, or fall back to the Object.Equals override, if any.
>
> Then, if you deal with some T where you want to customize behaviour
> (strings come to mind - do you want case-sensitive versus insensitive
> behaviour?), you create an overloaded constructor which takes an
> IEqualityComparer<T> instance, and pass EqualityComparer<T>.Default in
> the other overload. All comparisons should be done through the cached
> interface value.
>
> For the concrete case of strings, you can then use
> StringComparer.Ordinal, StringComparer.InvariantCultureIgnoreCase, as
> the argument etc.
>
> -- Barry
>
> --
> http://barrkel.blogspot.com/
Re: Generics and comparison (follow on from my previous "Generics and collections" thread)
Barry,
My last message sounded really bad; sorry! Your suggestions have provided
the answer I was looking for. I particularly liked the IEqualityComparer
suggestion and this (along with the overriden constructor) is the one that I
am going with.
Martin.
"Martin Robins" <martin at orpheus-solutions dot co dot uk> wrote in message
news:OrggXiylIHA.3636 [at] TK2MSFTNGP02.phx.gbl...
> Barry,
>
> Thanks; that seems to have done the trick (in as much as it is providing
> the correct results).
>
> Martin.
>
> "Barry Kelly" <barry.j.kelly [at] gmail.com> wrote in message
> news:8ujdv35e4jl1jmbprf6kkppc2dg9vdpc1m [at] 4ax.com...
>> "Martin Robins" <martin at orpheus-solutions dot co dot uk> wrote:
>>
>>> Marc has sorted my problem with the collections, however I am now
>>> in a new scenario; I am trying to compare a generic property value
>>> before setting it as shown below ...
>>>
>>> public T Value {
>>> get { return this.value; }
>>> set {
>>> if ( this.value != value ) {
>>> this.value = value;
>>> this.OnValueChanged(EventArgs.Empty);
>>> }
>>> }
>>> }
>>>
>>> This code produces the Operator '==' cannot be applied to operands of
>>> type
>>> 'T' and 'T' error at compile time!
>>> I am sure that I am not the only person to have tried this, any clues as
>>> to the correct work around?
>>
>> The normal pattern for comparing values of a generic type is to use
>> Comparer<T>.Default (if you need ordering) or
>> EqualityComparer<T>.Default (if you need equality and hashing).
>>
>> EqualityComparer<T>.Default delegates to an IEquatable<T> interface if
>> it exists, or fall back to the Object.Equals override, if any.
>>
>> Then, if you deal with some T where you want to customize behaviour
>> (strings come to mind - do you want case-sensitive versus insensitive
>> behaviour?), you create an overloaded constructor which takes an
>> IEqualityComparer<T> instance, and pass EqualityComparer<T>.Default in
>> the other overload. All comparisons should be done through the cached
>> interface value.
>>
>> For the concrete case of strings, you can then use
>> StringComparer.Ordinal, StringComparer.InvariantCultureIgnoreCase, as
>> the argument etc.
>>
>> -- Barry
>>
>> --
>> http://barrkel.blogspot.com/
>
>