473,544 Members | 1,955 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Generics limitation...

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)
{
this.value1 = value1;
this.value2 = value2;
}

public void SomeMethod()
{
if (value1 != value2)
DoSomething();
}
}

and I got the following message at compile time :

"Operator '!=' cannot be applied to operands of type 'T' and 'T'"

Ok, I can use the following code :

if (value1.Equals( value2) == false)
DoSomething();

but doing so, I'm loosing all the advantage of generics
==> value1 and value2 are boxed before comparison occurs...

It was already the case for variable initialisation, I need to cast a value
to Object before it can be cast back to T (see : 12/29/2005 post "Generics
limitation on .Net") :

value1 = (T)(Object)Int3 2.MinValue;

since it was used once in my class, I didn't care about extra
boxing/unboxing operation.

But value1 vs value2 comparison occurs in a loop in real situation (I mean
in my real program) :

for (Int32 i = value1.Length; i-- != 0; i++)
{
if (value1[i] != value2[i])
DoSomething();
}

The question is : Does generics really usefull in such sitautions ?

Dec 29 '05 #1
13 1673
> I try to compare to values of generic value type T in a generic class as
follow:
You should read:

I try to compare two values of generic value type T in a generic class as
follow:

;-)
"Luc Vaillant" wrote:
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)
{
this.value1 = value1;
this.value2 = value2;
}

public void SomeMethod()
{
if (value1 != value2)
DoSomething();
}
}

and I got the following message at compile time :

"Operator '!=' cannot be applied to operands of type 'T' and 'T'"

Ok, I can use the following code :

if (value1.Equals( value2) == false)
DoSomething();

but doing so, I'm loosing all the advantage of generics
==> value1 and value2 are boxed before comparison occurs...

It was already the case for variable initialisation, I need to cast a value
to Object before it can be cast back to T (see : 12/29/2005 post "Generics
limitation on .Net") :

value1 = (T)(Object)Int3 2.MinValue;

since it was used once in my class, I didn't care about extra
boxing/unboxing operation.

But value1 vs value2 comparison occurs in a loop in real situation (I mean
in my real program) :

for (Int32 i = value1.Length; i-- != 0; i++)
{
if (value1[i] != value2[i])
DoSomething();
}

The question is : Does generics really usefull in such sitautions ?

Dec 29 '05 #2
Luc,

How are you losing the advantage of generics? Generics doesn't lift the
type operators from the type. In other words, if you overload the ==
operator (or != operator in this case), that is NOT visible to your generic
class.

In order to get around it, you will have to create an interface which
exposes the operations, and performs them (instead of using == or !=).
Either that, or you assign a type to the class internally that will handle
the operations based on the type.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"Luc Vaillant" <Lu*********@di scussions.micro soft.com> wrote in message
news:88******** *************** ***********@mic rosoft.com...
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)
{
this.value1 = value1;
this.value2 = value2;
}

public void SomeMethod()
{
if (value1 != value2)
DoSomething();
}
}

and I got the following message at compile time :

"Operator '!=' cannot be applied to operands of type 'T' and 'T'"

Ok, I can use the following code :

if (value1.Equals( value2) == false)
DoSomething();

but doing so, I'm loosing all the advantage of generics
==> value1 and value2 are boxed before comparison occurs...

It was already the case for variable initialisation, I need to cast a
value
to Object before it can be cast back to T (see : 12/29/2005 post "Generics
limitation on .Net") :

value1 = (T)(Object)Int3 2.MinValue;

since it was used once in my class, I didn't care about extra
boxing/unboxing operation.

But value1 vs value2 comparison occurs in a loop in real situation (I mean
in my real program) :

for (Int32 i = value1.Length; i-- != 0; i++)
{
if (value1[i] != value2[i])
DoSomething();
}

The question is : Does generics really usefull in such sitautions ?

Dec 29 '05 #3
"Luc Vaillant" <Lu*********@di scussions.micro soft.com> a écrit dans le
message de news: 88************* *************** **...icrosof t.com...

|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)
| {
| this.value1 = value1;
| this.value2 = value2;
| }
|
| public void SomeMethod()
| {
| if (value1 != value2)
| DoSomething();
| }
| }
|
| and I got the following message at compile time :
|
| "Operator '!=' cannot be applied to operands of type 'T' and 'T'"

You cannot expect T to support the == or != operators because some types may
not have overloaded them. If you are wanting to compare two Ts in the
generic class then you need to use Equals(...)

However, if you need to compare two instances of your generic class then you
nee to supply operator overloads like this :

public class C<T> where T : struct
{
private T value;

public override bool Equals(object obj)
{
return value.Equals((( C<T>) obj).value);
}

public override int GetHashCode()
{
return value.GetHashCo de();
}

public static bool operator ==(C<T> lhs, C<T> rhs)
{
return lhs.value.Equal s(rhs.value);
}

public static bool operator !=(C<T> lhs, C<T> rhs)
{
return ! lhs.value.Equal s(rhs.value);
}
}

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Dec 29 '05 #4
Sorry, but I don't anderstand... any example ?
"Nicholas Paldino [.NET/C# MVP]" wrote:
Luc,

How are you losing the advantage of generics? Generics doesn't lift the
type operators from the type. In other words, if you overload the ==
operator (or != operator in this case), that is NOT visible to your generic
class.

In order to get around it, you will have to create an interface which
exposes the operations, and performs them (instead of using == or !=).
Either that, or you assign a type to the class internally that will handle
the operations based on the type.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"Luc Vaillant" <Lu*********@di scussions.micro soft.com> wrote in message
news:88******** *************** ***********@mic rosoft.com...
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)
{
this.value1 = value1;
this.value2 = value2;
}

public void SomeMethod()
{
if (value1 != value2)
DoSomething();
}
}

and I got the following message at compile time :

"Operator '!=' cannot be applied to operands of type 'T' and 'T'"

Ok, I can use the following code :

if (value1.Equals( value2) == false)
DoSomething();

but doing so, I'm loosing all the advantage of generics
==> value1 and value2 are boxed before comparison occurs...

It was already the case for variable initialisation, I need to cast a
value
to Object before it can be cast back to T (see : 12/29/2005 post "Generics
limitation on .Net") :

value1 = (T)(Object)Int3 2.MinValue;

since it was used once in my class, I didn't care about extra
boxing/unboxing operation.

But value1 vs value2 comparison occurs in a loop in real situation (I mean
in my real program) :

for (Int32 i = value1.Length; i-- != 0; i++)
{
if (value1[i] != value2[i])
DoSomething();
}

The question is : Does generics really usefull in such sitautions ?


Dec 29 '05 #5
> You cannot expect T to support the == or != operators because some types may
not have overloaded them. If you are wanting to compare two Ts in the
generic class then you need to use Equals(...)
So, I'm loosing (Speed) advantage of generics because of boxing operations...

I explain :

If using the two class definition bellow :

A<int> classA = new A<int>();
B classB = new B();

B.SomeCompariso n(12345) should be faster than A.SomeCompariso n(12345)
because boxing operations are already done.
Of course, class initialization is slower for class B because values are
boxed into ArrayList, but this is done only once.

public class A<T> where T : struct
{
private List<T> myList;

public A()
{
// Initializing myList...
}

public void SomeComparison( T aValue)
{
Object boxedValue = (Object)aValue;

for (int i = myList.Count; i-- != 0; )
{
if (myList[i].Equals(boxedVa lue))
DoSomething();
}
}

public class B
{
private ArrayList myList;

public B()
{
// Initializing myList...
}

public void SomeComparison( int aValue)
{
Object boxedValue = (Object)aValue;

for (int i = myList.Count; i-- != 0; )
{
if (myList[i].Equals(boxedVa lue))
DoSomething();
}
}


"Joanna Carter [TeamB]" wrote:
"Luc Vaillant" <Lu*********@di scussions.micro soft.com> a écrit dans le
message de news: 88************* *************** **...icrosof t.com...

|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)
| {
| this.value1 = value1;
| this.value2 = value2;
| }
|
| public void SomeMethod()
| {
| if (value1 != value2)
| DoSomething();
| }
| }
|
| and I got the following message at compile time :
|
| "Operator '!=' cannot be applied to operands of type 'T' and 'T'"

You cannot expect T to support the == or != operators because some types may
not have overloaded them. If you are wanting to compare two Ts in the
generic class then you need to use Equals(...)

However, if you need to compare two instances of your generic class then you
nee to supply operator overloads like this :

public class C<T> where T : struct
{
private T value;

public override bool Equals(object obj)
{
return value.Equals((( C<T>) obj).value);
}

public override int GetHashCode()
{
return value.GetHashCo de();
}

public static bool operator ==(C<T> lhs, C<T> rhs)
{
return lhs.value.Equal s(rhs.value);
}

public static bool operator !=(C<T> lhs, C<T> rhs)
{
return ! lhs.value.Equal s(rhs.value);
}
}

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer

Dec 29 '05 #6
Luc Vaillant wrote:
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)
{
this.value1 = value1;
this.value2 = value2;
}

public void SomeMethod()
{
if (value1 != value2)
DoSomething();
}
}

and I got the following message at compile time :

"Operator '!=' cannot be applied to operands of type 'T' and 'T'"

Ok, I can use the following code :

if (value1.Equals( value2) == false)
DoSomething();

but doing so, I'm loosing all the advantage of generics
==> value1 and value2 are boxed before comparison occurs...

It was already the case for variable initialisation, I need to cast a
value to Object before it can be cast back to T (see : 12/29/2005
post "Generics limitation on .Net") :

value1 = (T)(Object)Int3 2.MinValue;

since it was used once in my class, I didn't care about extra
boxing/unboxing operation.

But value1 vs value2 comparison occurs in a loop in real situation (I
mean in my real program) :

for (Int32 i = value1.Length; i-- != 0; i++)
{
if (value1[i] != value2[i])
DoSomething();
}

The question is : Does generics really usefull in such sitautions ?


answer: no.

MS didn't implement a filter spec for static defined operator
overloads so you can specify them in a where clause for the generic
type. This thus means the compiler doesn't know for sure the generic
type implements the operators used in the code.

It's unfortunate, but not solvable, you have to work around it for now.

Frans

--
------------------------------------------------------------------------
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Dec 30 '05 #7
Hi Frans,

I found a solution to my problem:

class MyComp : IComparer<short >, IComparer<int>
{
public int Compare(int x, int y) { return x - y; }
public int Compare(short x, short y) { return x - y; }
}

class GenClass<T, I> where I : IComparer<T>, new()
{
private IComparer<T> comparer = new I();

public void SomeMethod(T value1, T value2)
{
if (comparer.Compa re(value1, value2) == 0)
DoSomething();
}
}

Thanks
Luc

"Frans Bouma [C# MVP]" wrote:
Luc Vaillant wrote:
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)
{
this.value1 = value1;
this.value2 = value2;
}

public void SomeMethod()
{
if (value1 != value2)
DoSomething();
}
}

and I got the following message at compile time :

"Operator '!=' cannot be applied to operands of type 'T' and 'T'"

Ok, I can use the following code :

if (value1.Equals( value2) == false)
DoSomething();

but doing so, I'm loosing all the advantage of generics
==> value1 and value2 are boxed before comparison occurs...

It was already the case for variable initialisation, I need to cast a
value to Object before it can be cast back to T (see : 12/29/2005
post "Generics limitation on .Net") :

value1 = (T)(Object)Int3 2.MinValue;

since it was used once in my class, I didn't care about extra
boxing/unboxing operation.

But value1 vs value2 comparison occurs in a loop in real situation (I
mean in my real program) :

for (Int32 i = value1.Length; i-- != 0; i++)
{
if (value1[i] != value2[i])
DoSomething();
}

The question is : Does generics really usefull in such sitautions ?


answer: no.

MS didn't implement a filter spec for static defined operator
overloads so you can specify them in a where clause for the generic
type. This thus means the compiler doesn't know for sure the generic
type implements the operators used in the code.

It's unfortunate, but not solvable, you have to work around it for now.

Frans

--
------------------------------------------------------------------------
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------

Dec 30 '05 #8
"Luc Vaillant" <Lu*********@di scussions.micro soft.com> a écrit dans le
message de news: 8A************* *************** **...icrosof t.com...

| I found a solution to my problem:
|
| class MyComp : IComparer<short >, IComparer<int>
| {
| public int Compare(int x, int y) { return x - y; }
| public int Compare(short x, short y) { return x - y; }
| }
|
| class GenClass<T, I> where I : IComparer<T>, new()
| {
| private IComparer<T> comparer = new I();
|
| public void SomeMethod(T value1, T value2)
| {
| if (comparer.Compa re(value1, value2) == 0)
| DoSomething();
| }
| }

Well, I was obviously on the right track suggesting IComparable<T>; given
that yours is not the only question I was thinking about, at least that may
have pushed you in the direction of using IComparer<T> :-)

If you think the advice is worth taking :-), but for others benefit anyway,
you might like to take care if you wanted to apply this to floating point
numbers as they can throw unpredictable results when checking for equality
of calculated values compared with constant values.

So you see, generics did not have the limitations you thought, you just had
to get inventive and use what was available :-)

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Dec 30 '05 #9
Luc Vaillant <Lu*********@di scussions.micro soft.com> wrote:
I found a solution to my problem:

class MyComp : IComparer<short >, IComparer<int>
{
public int Compare(int x, int y) { return x - y; }
public int Compare(short x, short y) { return x - y; }
}

class GenClass<T, I> where I : IComparer<T>, new()
{
private IComparer<T> comparer = new I();

public void SomeMethod(T value1, T value2)
{
if (comparer.Compa re(value1, value2) == 0)
DoSomething();
}
}


Do you actually need to provide an IComparer<T>? int and short both
implement IComparable<the mselves>. Can't you just use:

class GenClass<T> where T : IComparable<T>,
{
public void SomeMethod(T value1, T value2)
{
if (value1.Compare To(value2) == 0)
DoSomething();
}
}

I don't believe that involves any boxing - at least, it doesn't seem to
induce any garbage collections in the following program:

using System;

class GenClass<T> where T : IComparable<T>
{
public void SomeMethod(T value1, T value2)
{
if (value1.Compare To(value2) == 0)
DoSomething();
// object o = value1;
}

void DoSomething()
{
}
}

public class Test
{
static void Main()
{
Console.WriteLi ne ("Ready?");
Console.ReadLin e();
GenClass<int> test = new GenClass<int>() ;

for (int i=0; i < 10000000; i++)
{
test.SomeMethod (1, 2);
}
Console.WriteLi ne ("Finished") ;
Console.ReadLin e();
}
}

If you uncomment the commented out line to force boxing each iteration,
you'll see lots of Gen0 collections in PerfMon. With it commented out,
you don't see any (or at least I don't).

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 30 '05 #10

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

Similar topics

2
5791
by: Hung Jung Lu | last post by:
Hi, I just downloaded rotor and gyro and am playing a bit with generics. I enclose a sample program. My question is, according to the language spec (http://msdn.microsoft.com/vcsharp/team/language/default.aspx, C# 2.0 Specification), a syntax like: public class MathEngine<T> where T: IHasX, IHasY { … }
8
1830
by: Leicester B. Ford Jr. | last post by:
I have come across a problem using generics. I want to create a Factory type that will build classes for me. Code snippet below... static public class Product<T> where T : new() { static public T New() { return new T(); } }
4
9183
by: Michael Sparks | last post by:
I started writing some code with the 2.0 beta compiler, and found out quickly that specialization is not supported with generics. For example, I want to do something like this: class number ... class integer : number ... class real : number ... class multiplier<_number> where _number : number ... class multiplier<_number> where _number...
3
1226
by: Tom Jastrzebski | last post by:
Hello everybody, Here is another problem with generics I come across. Let's say I want to implement a structure performing some operations on some numeric type. I can not than just return this expected type since the compiler is not sure what this type would be, and it does not know that the type I am trying to returned is the correct...
3
1944
by: Marshal | last post by:
/////////////////////////////////////////////////////////////////////////////////////////////// /// CONSTRAINTS ON GENERICS //////////////////////////////////////////////////// public class Node<T> where T:IComparable<T> I don't like the syntax, and would prefer something that groups the constraint along with the type that it governs...
23
2520
by: Luc Vaillant | last post by:
I need to initialise a typed parameter depending of its type in a generic class. I have tried to use the C++ template form as follow, but it doesn't work. It seems to be a limitation of generics vs C++ templates. Does anyone knows a workaround to do this ? Thx : public class C<T> { private T myValue;
8
2408
by: Kris Jennings | last post by:
Hi, I am trying to create a new generic class and am having trouble casting a generic type to a specific type. For example, public class MyClass<Twhere T : MyItemClass, new() { public MyClass() { } public void AppendItem()
8
2542
by: Gary Brown | last post by:
Hi, When I do the following public class IAmAGeneric<T> { ... public T AMember (T a, T b) { return a + b; }; }
2
138
by: =?Utf-8?B?QnJhdmVzQ2hhcm0=?= | last post by:
I am trying to convert a class I have to generics and I can't seem to find any possible why to implement it. I'm beginning to think I'm doing something I shouldn't or I hit generics limitation. Here is an example of the old way: static void Main(string args) { MonitorCenter monitor = new MonitorCenter(); monitor.SetMonitor(new...
0
7420
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
7602
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. ...
0
7764
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
7704
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
5904
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5291
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3407
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3404
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1837
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

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.