473,569 Members | 2,721 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 1725
On Jun 18, 1:17*pm, "Tony" <johansson.ande rs...@telia.com wrote:
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<cha r>" 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.co mwrote:
On Jun 18, 1:17*pm, "Tony" <johansson.ande rs...@telia.com wrote:
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<cha r>" and used
"string" then == would still mean reference identity, rather than
using the == overloaded for string.

Jon
Jun 27 '08 #3
<qg**********@m ailinator.comwr ote:
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.co m>
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).IsCl ass”.

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.co mwrote:
*<qglyirnyf...@ mailinator.comw rote:
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.co m>
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**********@m ailinator.comwr ote:
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).Is Class=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.co m>
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**********@m ailinator.comwr ote:
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.co m>
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

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

Similar topics

4
25397
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 following error: Argument '1': cannot convert from 'GenericsPOC.ArticleCollection' to 'System.Collections.Generic.IList<object>' I tried casting...
8
3363
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? How do they make coding easier? Is there a resource that will give me a basic understanding of what generics are and how generics will be useful...
7
3472
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 parent class without knowing the type of the parent class, can this be done with C#? I thought this was what Generics was supposed to be all about but...
13
1679
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
2798
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 RuleDelegate<T>(T item); In my class my goal is to use a generic list collection to contain my generic delegates. This will allow me to pass this List to...
9
1680
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: BaseEdit class FooEdit: BaseEdit These are all acutally Windows Forms and BaseEdit is an abstract class (and so never gets instantiated). I'd...
3
1804
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 DerivedList that can hold items of the type DerivedItem, which inherits from BaseList. So far so good... But if I somehow get an object that I know is...
0
7695
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7612
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7922
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
1
7668
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7964
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
3637
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2111
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1209
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
936
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.