![]() |
|
|
#1 |
|
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! } } |
|
|
|
#2 |
|
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 |
|
|
|
#3 |
|
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. |
|
|
|
#4 |
|
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 |
|
|
|
#5 |
|
Guest
Posts: n/a
|
Re: Generics, use +/-/* operator etc
"Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> wrote in message news p.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 |
|
|
|
#6 |
|
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 thoughtthat 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 |
|
|
|
#7 |
|
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 |
|
|
|
#8 |
|
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 |
|
|
|
#9 |
|
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 |
|
|
|
#10 |
|
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. |
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|