TechTalkz.com Logo

Go Back   TechTalkz.com Technology & Computer Troubleshooting Forums > Tech Support Archives > Programing Languages > C#(C Sharp)

Notices

Reply
 
Thread Tools Display Modes
Old 15-12-2007, 01:19 AM   #1
My interest
Guest
 
Posts: n/a
Generics, use +/-/* operator etc

How can I use * operator in C# generics? e.g.

class foo<T_>
{
T_ v1, v2:

public T_ squar()
{
return v1 * v2; /// wrong!
}
}

  Reply With Quote
Old 15-12-2007, 02:24 AM   #2
Peter Duniho
Guest
 
Posts: n/a
Re: Generics, use +/-/* operator etc

On Fri, 14 Dec 2007 11:25:27 -0800, My interest <myinterest@gmail.com>
wrote:

> How can I use * operator in C# generics? e.g.
>
> class foo<T_>
> {
> T_ v1, v2:
>
> public T_ squar()
> {
> return v1 * v2; /// wrong!
> }
> }


I don't think you can. To use the * operator (or any operator, for that
matter), the compiler has to know that you're dealing with types that have
a defined overload for the operator.

If you have a situation where you can constrain your generic type
parameter to one that does have a valid operator* overload, then that
would work. But without any other information from you, it seems likely
that you're looking to get this behavior with value types and of course
they don't have any inheritance relationship that would allow you to
define a useful constraint like that.

I suppose you could define overloads within your class, covering all the
types you want to handle. I haven't tried it myself, but hopefully the
compiler would be able to pick the right overload at compile time. For
example:

class foo<T_>
{
T_ v1, v2;

public static T_ squar(int t1, int t2)
{
return (T_)(t1 * t2);
}

public static T_ squar(float t1, float t2)
{
return (T_)(t1 * t2);
}

// etc.

public T_ squar()
{
return squar(v1, v2);
}
}

Actually, seeing that in code, I'm not so sure. The compiler might sitll
find something to complain about. But it's worth a try anyway.

Pete
  Reply With Quote
Old 15-12-2007, 02:24 AM   #3
Ben Voigt [C++ MVP]
Guest
 
Posts: n/a
Re: Generics, use +/-/* operator etc


"My interest" <myinterest@gmail.com> wrote in message
news:53b19d0a-5b6f-4ddd-80b1-5d07c5d78488@b40g2000prf.googlegroups.com...
> How can I use * operator in C# generics? e.g.
>
> class foo<T_>
> {
> T_ v1, v2:
>
> public T_ squar()
> {
> return v1 * v2; /// wrong!
> }
> }
>


It's a well known problem -- you can't.

Search codeproject for "C# generic arithmetic" for workarounds.

  Reply With Quote
Old 15-12-2007, 02:25 AM   #4
Jon Skeet [C# MVP]
Guest
 
Posts: n/a
Re: Generics, use +/-/* operator etc

My interest <myinterest@gmail.com> wrote:
> How can I use * operator in C# generics? e.g.
>
> class foo<T_>
> {
> T_ v1, v2:
>
> public T_ squar()
> {
> return v1 * v2; /// wrong!
> }
> }


You can't, properly - it's been the cause of a fair amount of work.

However, if you're using .NET 3.5 Marc Gravell has a very cunning way
of doing it with expression trees, which I plan to blog about at some
point...

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
  Reply With Quote
Old 15-12-2007, 02:26 AM   #5
Ben Voigt [C++ MVP]
Guest
 
Posts: n/a
Re: Generics, use +/-/* operator etc


"Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> wrote in message
newsp.t3cbxluo8jd0ej@petes-computer.local...
> On Fri, 14 Dec 2007 11:25:27 -0800, My interest <myinterest@gmail.com>
> wrote:
>
>> How can I use * operator in C# generics? e.g.
>>
>> class foo<T_>
>> {
>> T_ v1, v2:
>>
>> public T_ squar()
>> {
>> return v1 * v2; /// wrong!
>> }
>> }

>
> I don't think you can. To use the * operator (or any operator, for that
> matter), the compiler has to know that you're dealing with types that have
> a defined overload for the operator.
>
> If you have a situation where you can constrain your generic type
> parameter to one that does have a valid operator* overload, then that
> would work. But without any other information from you, it seems likely
> that you're looking to get this behavior with value types and of course
> they don't have any inheritance relationship that would allow you to
> define a useful constraint like that.
>
> I suppose you could define overloads within your class, covering all the
> types you want to handle. I haven't tried it myself, but hopefully the
> compiler would be able to pick the right overload at compile time. For
> example:
>
> class foo<T_>
> {
> T_ v1, v2;
>
> public static T_ squar(int t1, int t2)
> {
> return (T_)(t1 * t2);
> }
>
> public static T_ squar(float t1, float t2)
> {
> return (T_)(t1 * t2);
> }
>
> // etc.
>
> public T_ squar()
> {
> return squar(v1, v2);
> }
> }
>
> Actually, seeing that in code, I'm not so sure. The compiler might sitll
> find something to complain about. But it's worth a try anyway.


No, overload resolution in generics is done based on the constraints only,
not the final type. This is what lets generics be exported in MSIL form, as
opposed to C++ templates which do overload resolution for each actual
combination of type parameters but can only be shared in source form.

In the above code, you'd get an error on each return statement because the
compiler doesn't know how to cast int to T_, nor float to T_, and another
trying to resolve which squar function is being used, because the only
guarantee is that v1 and v2 derive from T_ and object, but there are no
functions accepting parameters of either T_ or object.

>
> Pete


  Reply With Quote
Old 15-12-2007, 02:28 AM   #6
Peter Duniho
Guest
 
Posts: n/a
Re: Generics, use +/-/* operator etc

On Fri, 14 Dec 2007 11:59:03 -0800, Ben Voigt [C++ MVP]
<rbv@nospam.nospam> wrote:

> [...]
> No, overload resolution in generics is done based on the constraints
> only, not the final type. This is what lets generics be exported in
> MSIL form, as opposed to C++ templates which do overload resolution for
> each actual combination of type parameters but can only be shared in
> source form.


Oh well, it was worth a try. I'm a bit confused though: I thought
that for value types, a new instance of the class was generated for each
variation of the generic class.

In other words, while I do expect the problem you're describing with
reference types, I thought there was a chance that the compiler would
resolve things early enough for value types that the overloading and
casting would be okay.

Of course, if I'd tried to compile it I'd know for sure. I'm not
questioning what you're saying, just trying to figure out why, if value
types are handled differently anyway, they aren't a work-around for this
problem.

Pete
  Reply With Quote
Old 15-12-2007, 03:26 AM   #7
Jon Skeet [C# MVP]
Guest
 
Posts: n/a
Re: Generics, use +/-/* operator etc

Peter Duniho <NpOeStPeAdM@nnowslpianmk.com> wrote:
> > [...]
> > No, overload resolution in generics is done based on the constraints
> > only, not the final type. This is what lets generics be exported in
> > MSIL form, as opposed to C++ templates which do overload resolution for
> > each actual combination of type parameters but can only be shared in
> > source form.

>
> Oh well, it was worth a try. I'm a bit confused though: I thought
> that for value types, a new instance of the class was generated for each
> variation of the generic class.


The JIT will spit out new native code for each value type, but the
compiler keeps it in a single generic type.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
  Reply With Quote
Old 15-12-2007, 03:26 AM   #8
Marc Gravell
Guest
 
Posts: n/a
Re: Generics, use +/-/* operator etc

> I'm not questioning what you're saying, just trying to figure out why, if value
> types are handled differently anyway, they aren't a work-around for this
> problem.


For info, for people using . NET 3.5 I have a usable solution for
this. It doesn't (unfortunately) offer compile-time checking, but it
provides very efficient access to all the common operators. Quick
enough to be directly comparable to regular compiled code.

Let me know if people are interested...

Marc
  Reply With Quote
Old 15-12-2007, 03:26 AM   #9
Jon Skeet [C# MVP]
Guest
 
Posts: n/a
Re: Generics, use +/-/* operator etc

Marc Gravell <marc.gravell@gmail.com> wrote:
> > I'm not questioning what you're saying, just trying to figure out why, if value
> > types are handled differently anyway, they aren't a work-around for this
> > problem.

>
> For info, for people using . NET 3.5 I have a usable solution for
> this. It doesn't (unfortunately) offer compile-time checking, but it
> provides very efficient access to all the common operators. Quick
> enough to be directly comparable to regular compiled code.


In explaining it to a friend, I think the easiest way of thinking about
them is as "duck-typed operators"

(I hasten to add that while I understand the principle of the thing, I
don't understand Marc's code...

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
  Reply With Quote
Old 15-12-2007, 03:27 AM   #10
Chris Shepherd
Guest
 
Posts: n/a
Re: Generics, use +/-/* operator etc

I've wondered this for a while now, and maybe the reasoning is blatantly
obvious and I'm a fool or it's been asked and answered before, but is
there a reason why the numeric types don't implement an interface that
defined the operators for math as required?

At least then we could use a generic constraint (amongst other things)
for issues like this.

Chris.
  Reply With Quote
Reply

Thread Tools
Display Modes


Google
 


All times are GMT +5.5. The time now is 05:45 AM.


vBulletin, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO
Copyright © 2005-2008, TechTalkz.com. All Rights Reserved - Privacy Policy
Valid XHTML 1.0 Transitional