473,327 Members | 1,967 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

What does this mean(Generics)

Hello!

It says "Another limitation that you need to be aware of is that using the
operator == and != are
only permitted when comparing a value of a type supplied to a generic type
to null.
That is, the following code works.
Here if T is a value type then it is always assumed to be non-null, so in
the above
code Compare always return true;"

The question is what does they mean with the text saying "using the operator
== and != are
only permitted when comparing a value of a type supplied to a generic type
to null."

public bool Compare(T op1, T op2)
{
if (op1 != null && op2 != null)
{
return true;
}
else
{
return false;
}
}

//Tony
Jun 27 '08 #1
14 1709
On Jun 18, 1:17*pm, "Tony" <johansson.anders...@telia.comwrote:
It says "Another limitation that you need to be aware of is that using the
operator == and != are
only permitted when comparing a value of a type supplied to a generic type
to null.
That is, the following code works.
Here if T is a value type then it is always assumed to be non-null, so in
the above
code Compare always return true;"

The question is what does they mean with the text saying "using the operator
== and != are
only permitted when comparing a value of a type supplied to a generic type
to null."
It means that if T is unconstrained you can't do:

T foo = ...;
T bar = ...;

if (foo == bar)

If you constrain T to be a reference type (i.e. use "where T : class")
then reference identity comparisons will be used and you can compare
two values

If you constrain T to be derived from a type which overloads == and !=
then those overloads will be used. This is *not* polymorphic - only
overloads the compiler can guarantee at compile-time are used. For
instance, if you had a constraint "T : IEnumerable<char>" and used
"string" then == would still mean reference identity, rather than
using the == overloaded for string.

Jon
Jun 27 '08 #2
What I find interesting about this example is that if you constrain T
to be a “struct” then you will get a compile error.

So why is it that when T its unconstrained and it can be a “class” –
or- **struct** you don’t get a compile error?
On Jun 18, 7:24*am, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
On Jun 18, 1:17*pm, "Tony" <johansson.anders...@telia.comwrote:
It says "Another limitation that you need to be aware of is that using the
operator == and != are
only permitted when comparing a value of a type supplied to a generic type
to null.
That is, the following code works.
Here if T is a value type then it is always assumed to be non-null, so in
the above
code Compare always return true;"
The question is what does they mean with the text saying "using the operator
== and != are
only permitted when comparing a value of a type supplied to a generic type
to null."

It means that if T is unconstrained you can't do:

T foo = ...;
T bar = ...;

if (foo == bar)

If you constrain T to be a reference type (i.e. use "where T : class")
then reference identity comparisons will be used and you can compare
two values

If you constrain T to be derived from a type which overloads == and !=
then those overloads will be used. This is *not* polymorphic - only
overloads the compiler can guarantee at compile-time are used. For
instance, if you had a constraint "T : IEnumerable<char>" and used
"string" then == would still mean reference identity, rather than
using the == overloaded for string.

Jon
Jun 27 '08 #3
<qg**********@mailinator.comwrote:
What I find interesting about this example is that if you constrain T
to be a =3Fstruct=3F then you will get a compile error.

So why is it that when T its unconstrained and it can be a =3Fclass=3F =3F
or- **struct** you don=3Ft get a compile error?
When it's unconstrained and at execution time T is a struct, then the
comparison with null always fails - even for default(T). (That's a
handy way of telling at execution time whether or not it *is* a struct,
in fact.)

If you explicitly constrain it to being a struct, then the comparison
is pointless as you always know the answer.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #4
I am ok with what you are saying, however, it was my impression that
the whole reason for constraining a generic parameter was so that the
compiler could resolve any issues during compiling time.

If the compiler allows the code to compile without a constraint
(therefore allowing the generic parameter to by “class” –or-
“struct”), then in my opinion it should allow it to compile with a
constraint of “struct” (whether that makes sense or not) otherwise
this is a double standard.

If I wanted to know if the generic parameter is a “class” or a
“struct” then I could use “typeof(T).IsClass”.

I am still not clear why this is allowed. Am I just not looking a this
the right way?

Thanks.

On Jun 18, 3:01*pm, Jon Skeet [C# MVP] <sk...@pobox.comwrote:
*<qglyirnyf...@mailinator.comwrote:
What I find interesting about this example is that if you constrain T
to be a =3Fstruct=3F then you will get a compile error.
So why is it that when T its unconstrained and it can be a =3Fclass=3F =3F
or- **struct** you don=3Ft get a compile error?

When it's unconstrained and at execution time T is a struct, then the
comparison with null always fails - even for default(T). (That's a
handy way of telling at execution time whether or not it *is* a struct,
in fact.)

If you explicitly constrain it to being a struct, then the comparison
is pointless as you always know the answer.

--
Jon Skeet - <sk...@pobox.com>
Web site:http://www.pobox.com/~skeet*
Blog:http://www.msmvps.com/jon.skeet
C# in Depth:http://csharpindepth.com
Jun 27 '08 #5
<qg**********@mailinator.comwrote:
I am ok with what you are saying, however, it was my impression that
the whole reason for constraining a generic parameter was so that the
compiler could resolve any issues during compiling time.
To some extent. I'd say the reasons are:

1) Allow *more* to be done by the compiler within the type/method,
because it has more information about what the type parameter might
be at execution time.

2) Constrain clients so they'll only use the type/method with
appropriate type arguments.
If the compiler allows the code to compile without a constraint
(therefore allowing the generic parameter to by =3Fclass=3F =3For-
=3Fstruct=3F), then in my opinion it should allow it to compile with a
constraint of =3Fstruct=3F (whether that makes sense or not) otherwise
this is a double standard.
No - it's using the fact that it's got more information to prohibit a
redundant comparison. The comparison *isn't* redundant when the type is
unconstrained, as it will have different results depending on the value
and the type parameter.
If I wanted to know if the generic parameter is a =3Fclass=3F or a
=3Fstruct=3F then I could use =3Ftypeof(T).IsClass=3F.
You could, but I *suspect* it takes longer. In particular, the JIT can
work out that

if (default(T) == null)

will always be false for value types and true for reference types
without knowing anything about the Type class. I would hope that it
would take advantage of that and optimise away the comparison (and
potentially the code within the subsequent block).

Now it *could* do that through knowledge of the IsClass property, but
it's a bit further away from its normal type of optimisation, IMO.
I am still not clear why this is allowed. Am I just not looking a this
the right way?
Would you rather the comparison was prohibited completely for
unconstrained type parameters? While I can't *immediately* think of a
time I've used it, I'm sure I have...

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #6
Would you rather the comparison was prohibited completely for
unconstrained type parameters?

I think it should be either *complete prohibited* or *completely
allowed* to compare value types to nulls.

Take a look at the following snippet of code:

int i = 8;
bool b = (i == null);

If you compile this code the compiler will compile it successfully and
only issue a warning to the effect that the statement is always false.
So again, it ok to let it fly here but not on the example we have been
talking about.

In my opinion, the compiler should either allow a value type be
compared to a null or not allow it (whether that makes sense or not).
It should not pick and choose sometime yes, sometimes no based on some
unknown reasoning.

But something tells me you are not ok with that or are you? :)
Jun 27 '08 #7
<qg**********@mailinator.comwrote:
Would you rather the comparison was prohibited completely for
unconstrained type parameters?

I think it should be either *complete prohibited* or *completely
allowed* to compare value types to nulls.

Take a look at the following snippet of code:

int i = 8;
bool b = (i == null);

If you compile this code the compiler will compile it successfully and
only issue a warning to the effect that the statement is always false.
So again, it ok to let it fly here but not on the example we have been
talking about.
Well, that's a somewhat completely different issue - that's doing an
implicit conversion from int to int? and then comparing *that* with
null.
In my opinion, the compiler should either allow a value type be
compared to a null or not allow it (whether that makes sense or not).
It should not pick and choose sometime yes, sometimes no based on some
unknown reasoning.
It's not unknown. It's all in the spec.
But something tells me you are not ok with that or are you? :)
I'm pretty much fine with the way it is now, although the implicit
conversion above does irritate me.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #8
Well, that's a somewhat completely different issue - that's doing an
implicit conversion from int to int? and then comparing *that* with
null.
mmm.. the plot thickens. This calls fro doing some more research… I am
looking at the IL and seeing interesting things.

Go to go home, will post later.

Thanks for the help!
Jun 27 '08 #9
If you compile this code the compiler will compile it successfully and
only issue a warning to the effect that the statement is always false.
Actually, you don't always get a warning any more:
http://connect.microsoft.com/VisualS...dbackID=348850

Marc
Jun 27 '08 #10
On Jun 19, 8:38*am, Marc Gravell <marc.grav...@gmail.comwrote:
If you compile this code the compiler will compile it successfully and
only issue a warning to the effect that the statement is always false.

Actually, you don't always get a warning any more:http://connect.microsoft.com/VisualS...Feedback.aspx?...
Eek, that's somewhat alarming. Given that it's almost always
symptomatic of a developer misunderstanding their data, it's a really
useful warning to get...

Jon
Jun 27 '08 #11
Feel free to validate it independently and click some buttons to help
escalate it, then ;-p

Marc
Jun 27 '08 #12
On Jun 19, 9:35*am, Marc Gravell <marc.grav...@gmail.comwrote:
Feel free to validate it independently and click some buttons to help
escalate it, then ;-p
Have done so - but in testing it I found that it's not quite as bad as
it might be. It occurs with custom structs such as DateTime, but if
you try it with primitive types (e.g. int) the warning is still
raised. As the primitive types are used so much more (IME) than other
structs, that's a relief - but I'd still like to see it fixed.

Jon
Jun 27 '08 #13
I observed it didn't happen with primatives, which is why I posted with
a bespoke struct - I didn't think of trying DateTime/decimal. That would
have saved some typing ;-p

Cheers,

Marc
Jun 27 '08 #14
Jon Skeet [C# MVP] wrote:
On Jun 19, 9:35 am, Marc Gravell <marc.grav...@gmail.comwrote:
>Feel free to validate it independently and click some buttons to help
escalate it, then ;-p

Have done so - but in testing it I found that it's not quite as bad as
it might be. It occurs with custom structs such as DateTime, but if
you try it with primitive types (e.g. int) the warning is still
raised. As the primitive types are used so much more (IME) than other
structs, that's a relief - but I'd still like to see it fixed.

Jon
I can't think of an example offhand, but it seems legal, right now, to
define a meaningful operator== comparison between different types, including
between a value type and a reference type.

Oh, here's the counter-example -- IntPtr. Although inspection reveals that
IntPtr.Zero == null would indeed return false. And that not producing
either a warning or the least-surprising result is more than a little
disturbing.
Jul 18 '08 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: KC | last post by:
Could some one explain to me the casting rules for sending generic lists, ex. List<Person>, to a function that accepts List<object>? I cannot get the following easy-cheesy app to work. I get the...
8
by: Chris Dunaway | last post by:
The next version of VS.Net (Whidbey) promises to add generics support to VB. I have a vague remembrance of Templates in C++, but I guess I need a refresher. What will generics allow us to do? ...
7
by: Gene Vital | last post by:
Hi all, I need some help in understanding how to use Generics. I have a class based on a user control that can be put on any Container at runtime, I want to be able to call a method on the...
13
by: Luc Vaillant | last post by:
I try to compare to values of generic value type T in a generic class as follow: public class C<T> where T : struct { private T value1; private T value2; C(T value1, T value2) {
4
by: Cedric Rogers | last post by:
I wasn't sure if I could do this. I believe I am stretching the capability of what generics can do for me but here goes. I have a generic delegate defined as public delegate bool...
9
by: James Crosswell | last post by:
I'm not sure if I'm going about this the right way - it may be that Generics might be able to help me out here... but here goes: I have three classes as follows class BaseEdit class WidgetEdit:...
3
by: psyCK0 | last post by:
Hi all! I have a problem of casting generics to their base type. In the code below I first define a BaseList class that can hold items of any type that inherits from BaseItem. I then define a...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.