c#:
in a generic class, can I code the class so that I can call a static method of the generic class T? In the ConvertFrom method of the generic TypeConvert class I want to write, I have a call to the static Parse method of the conversion class. if (InValue is string) return T.Parse((string)InValue); else return base.ConvertFrom(context, culture, InValue); the compiler gives an error message saying "T is a type parameter which cannot be used in the given context. Can I call statics of the generic class? thanks, -Steve public class GenericTypeConverter<T> : TypeConverter where T:class { // this TypeConverter can convert from string. public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) { return true; } return base.CanConvertFrom(context, sourceType); } // convert from string to T public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object InValue) { if (InValue is string) return T.Parse((string)InValue); else return base.ConvertFrom(context, culture, InValue); } // Convert from T to string. public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object InValue, Type destinationType) { if (destinationType == typeof(string)) { T vlus = InValue as T ; return (vlus.ToString()); } else return base.ConvertTo(context, culture, InValue, destinationType); } }
[quoted text, click to view] Steve Richter <StephenRichter@gmail.com> wrote: > in a generic class, can I code the class so that I can call a static > method of the generic class T?
No. There's nothing you can do which will guarantee that there will be a static Parse method in T, so the compiler won't let you call it. (You could do it by reflection, of course, but that's horrible.) -- Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
[quoted text, click to view] On May 8, 1:53 am, Jon Skeet [C# MVP] <s...@pobox.com> wrote: > Steve Richter <StephenRich...@gmail.com> wrote: > > in a generic class, can I code the class so that I can call a static > > method of the generic class T? > > No. There's nothing you can do which will guarantee that there will be > a static Parse method in T, so the compiler won't let you call it.
darn! I thought that is what generics/templates were all about? The compiler plugs in the actual type and then compiles the code. Couldn't there be a where T: constraint that specifies the static methods the using class must implement? public class GenericTypeConverter<T> where T:class, new( ), static T Parse( string ) Types substituted into this generic class must be classes, be newable, and have a static method Parse that returns T and accepts a single argument of type string. -Steve
[quoted text, click to view] On May 8, 2:14 pm, Steve Richter <StephenRich...@gmail.com> wrote: > On May 8, 1:53 am, Jon Skeet [C# MVP] <s...@pobox.com> wrote: > > > Steve Richter <StephenRich...@gmail.com> wrote: > > > in a generic class, can I code the class so that I can call a static > > > method of the generic class T? > > > No. There's nothing you can do which will guarantee that there will be > > a static Parse method in T, so the compiler won't let you call it. > > darn! I thought that is what generics/templates were all about? The > compiler plugs in the actual type and then compiles the code.
That's what C++ templates are about - .NET generics aren't the same as templates. The IL is only generated for the parameterised form of the type, and then the JIT converts that into native code when it needs to (roughly speaking, once per value type and once for *all* reference types). [quoted text, click to view] > Couldn't there be a where T: constraint that specifies the static > methods the using class must implement?
It's not inconceivable that it could be in a future version of .NET, but it's not available now, certainly. Jon
On Mon, 07 May 2007 22:53:57 -0700, Jon Skeet [C# MVP] <skeet@pobox.com> [quoted text, click to view] wrote: > Steve Richter <StephenRichter@gmail.com> wrote: >> in a generic class, can I code the class so that I can call a static >> method of the generic class T? > > No. There's nothing you can do which will guarantee that there will be > a static Parse method in T, so the compiler won't let you call it. (You > could do it by reflection, of course, but that's horrible.)
Can you please elaborate on this? The thing I'm confused about is that even when you constrain T to be a class that does have Parse() method, you still get the error. I don't see a way to call static methods of a class T, even when you've constrained the class T to be a class with the specific static method. Either there's a way to call static methods in the generic class that I'm not seeing, or there's some reason you can't call static methods even when you have guaranteed the existence of the static method. Either way, I need help. :)
Steve, In addition to what Jon said, the only way I can think of to make this work would be to use the type name (through reflection) of T to figure out what method on the IConvertible implementation in the String class you should call in order to produce the value you want. -- - Nicholas Paldino [.NET/C# MVP] - mvp@spam.guard.caspershouse.com [quoted text, click to view] "Steve Richter" <StephenRichter@gmail.com> wrote in message news:1178600177.818156.309060@e51g2000hsg.googlegroups.com... > in a generic class, can I code the class so that I can call a static > method of the generic class T? > > In the ConvertFrom method of the generic TypeConvert class I want to > write, I have a call to the static Parse method of the conversion > class. > if (InValue is string) > return T.Parse((string)InValue); > else > return base.ConvertFrom(context, culture, InValue); > > the compiler gives an error message saying "T is a type parameter > which cannot be used in the given context. Can I call statics of the > generic class? > > thanks, > > -Steve > > > public class GenericTypeConverter<T> : TypeConverter where T:class > { > > // this TypeConverter can convert from string. > public override bool CanConvertFrom( > ITypeDescriptorContext context, > Type sourceType) > { > if (sourceType == typeof(string)) > { > return true; > } > return base.CanConvertFrom(context, sourceType); > } > > // convert from string to T > public override object ConvertFrom( > ITypeDescriptorContext context, > CultureInfo culture, > object InValue) > { > if (InValue is string) > return T.Parse((string)InValue); > else > return base.ConvertFrom(context, culture, InValue); > } > > // Convert from T to string. > public override object ConvertTo( > ITypeDescriptorContext context, > CultureInfo culture, > object InValue, > Type destinationType) > { > if (destinationType == typeof(string)) > { > T vlus = InValue as T ; > return (vlus.ToString()); > } > else > return base.ConvertTo(context, culture, InValue, > destinationType); > } > } >
On Tue, 08 May 2007 11:16:06 -0700, Jon Skeet [C# MVP] <skeet@pobox.com> [quoted text, click to view] wrote: > [...] >> still get the error. I don't see a way to call static methods of a >> class T, even when you've constrained the class T to be a class >> with the specific static method. > > Well, you'd constrain T to derive from a particular class which had a > specific static method; that's not quite the same thing as saying that > T itself has the static method - depending on your view of a type > "having" a static method.
To me, if a class inherits the method, it "has" the method. It may not implement it, but it has an implementation of it that you can call. So when I wrote "constrained the class T to be a class with the specific static method" I did in fact simply mean that T, either by inheritance or implementation, provides access to the static method in question. In other words, the same rules that apply to instance methods. On the face of it, I don't see any particular reason why static methods are inherently different from instance methods, at least from a syntactical point of view (I do understand the underlying implementation issues you refer to later). [quoted text, click to view] > (It's slightly easier for a void method than for a method returning T > as described by the OP - just because Foo has a static Parse method > returning Foo, that doesn't mean that every derived type will have a > static Parse method returning an instance of itself.)
True. But is that issue unique to static methods? It seems like it's more of an issue with respect to any method that returns a type the same as the generic type T. For example, a cloning method. Obviously, however the method is used in the generic class, it has to be constrained to returning something that is known to exist at compile time. But as long as that requirement is met, it should be possible. And the issue is the same whether the method is static or not. [quoted text, click to view] > Either way, there isn't a way of doing it, I'm afraid. (Well, there's > reflection, but I'm assuming we're not including that.)
Yes. I avoid reflection as much as possible, in the same way I avoid doing native Windows stuff as much as possible in .NET. I much prefer to use the .NET Framework-provided mechanisms whenever possible, and if there isn't one my next step is to try to implement what I'm doing some other way that does use .NET Framework-provided mechanisms. [quoted text, click to view] > No, there just isn't a way of calling static methods. Basically static > methods don't have any kind of polymorphism (unfortunately) and that's > a large part of what the constraints are for.
Okay, I'll bite. Maybe I've been using generics in a naive manner, but I'm missing the "that's a large part of what the constraints are for" aspect of your comment. In what way do static methods fail to provide the kind of polymorphism that is "a large part of what the constaints are for"? Can you provide an example? [quoted text, click to view] > Note that from the implementation side of things, there would be a cost > to this. Currently, I believe the JITted code for, say, List<T> is > shared for all reference types, but a separate version is required for > each value type. If static methods were allowed, you'd need a separate > version for each reference type as well, as they'd be calling different > static methods. Only in the case where the generic type *did* call any > static methods, of course...
So I guess my question is "why can't you call static methods from generic classes"? And it sounds as though the answer is simply that it would complicate the implementation of generic classes. Is that correct? It's not that it couldn't be done, but rather that it would change the underlying implementation of generics in an unfavorable way?
On Tue, 08 May 2007 12:30:44 -0700, Jon Skeet [C# MVP] <skeet@pobox.com> [quoted text, click to view] wrote: > [...] > The point (not clearly made, unfortunately) is that the OP wouldn't be > able to specify that a particular method signature were required > whether it was a static method or an instance method. It's basically a > problem with the idea of specifying methods as constraints where the > type parameter is part of the parameter list or the return type.
So he has more than one problem. :) And yes, I do see the problem with the method signature. [quoted text, click to view] > Polymorphism lets me call a method declared in a base class, knowing > that the method may be overriden by a derived class (assuming it's > virtual, of course).
I understand that much. :) And yet, I failed to apply that to the discussion. Probably because my use of generics *is* somewhat simplistic and doesn't take advantage of polymorphism. [quoted text, click to view] > [...] > - either the compiler needs to look for "extra" methods with the > appropriate signature, or you wouldn't get the pseudo-polymorphism > which is desired, and you might as well call the static method in the > class specified in the constraint.
Ah, I see. My use of generics much more often has to do with the simple type-safeness of them, and allowing me to avoid explicitly casting things in a generic collection, I've overlooked the more general uses, especially as they relate to virtual methods. And of course you're right, in C# currently there's no such thing as a virtual static method (I'm not even sure how that would work, unless you start being able to call static methods from an instance reference, or pass around an actual instance of the type). [quoted text, click to view] >> So I guess my question is "why can't you call static methods from >> generic classes"? And it sounds as though the answer is simply that >> it would complicate the implementation of generic classes. Is that >> correct? It's not that it couldn't be done, but rather that it >> would change the underlying implementation of generics in an >> unfavorable way? > > No, I think it's more than that. It would be sort of introducing > polymorphism to static methods "by the back door" *or* be not > particularly useful. Both options are quite clunky.
Well, I was thinking of more in the latter "not particularly useful" vein. I think the main thing I was missing is that you can always just call the constraint class's static method directly. So, for example, if you constrained the generic to use T where T derived from class A that has static method B, instead of writing T.B(), you could just as easily and effectively write A.B(). In hindsight, it seems like a "duh" moment. But for some reason I just wasn't putting the pieces together until now. Thanks for the help. :)
[quoted text, click to view] Peter Duniho <NpOeStPeAdM@nnowslpianmk.com> wrote: > > Steve Richter <StephenRichter@gmail.com> wrote: > >> in a generic class, can I code the class so that I can call a static > >> method of the generic class T? > > > > No. There's nothing you can do which will guarantee that there will be > > a static Parse method in T, so the compiler won't let you call it. (You > > could do it by reflection, of course, but that's horrible.) > > Can you please elaborate on this? The thing I'm confused about is that > even when you constrain T to be a class that does have Parse() method, you > still get the error. I don't see a way to call static methods of a class > T, even when you've constrained the class T to be a class with the > specific static method.
Well, you'd constrain T to derive from a particular class which had a specific static method; that's not quite the same thing as saying that T itself has the static method - depending on your view of a type "having" a static method. (It's slightly easier for a void method than for a method returning T as described by the OP - just because Foo has a static Parse method returning Foo, that doesn't mean that every derived type will have a static Parse method returning an instance of itself.) Either way, there isn't a way of doing it, I'm afraid. (Well, there's reflection, but I'm assuming we're not including that.) [quoted text, click to view] > Either there's a way to call static methods in the generic class that I'm > not seeing, or there's some reason you can't call static methods even when > you have guaranteed the existence of the static method. > > Either way, I need help. :)
No, there just isn't a way of calling static methods. Basically static methods don't have any kind of polymorphism (unfortunately) and that's a large part of what the constraints are for. Note that from the implementation side of things, there would be a cost to this. Currently, I believe the JITted code for, say, List<T> is shared for all reference types, but a separate version is required for each value type. If static methods were allowed, you'd need a separate version for each reference type as well, as they'd be calling different static methods. Only in the case where the generic type *did* call any static methods, of course... -- Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
[quoted text, click to view] Peter Duniho <NpOeStPeAdM@nnowslpianmk.com> wrote: > > Well, you'd constrain T to derive from a particular class which had a > > specific static method; that's not quite the same thing as saying that > > T itself has the static method - depending on your view of a type > > "having" a static method. > > To me, if a class inherits the method, it "has" the method. It may not > implement it, but it has an implementation of it that you can call. So > when I wrote "constrained the class T to be a class with the specific > static method" I did in fact simply mean that T, either by inheritance or > implementation, provides access to the static method in question.
Right. [quoted text, click to view] > In other words, the same rules that apply to instance methods. On the > face of it, I don't see any particular reason why static methods are > inherently different from instance methods, at least from a syntactical > point of view (I do understand the underlying implementation issues you > refer to later).
I understand - and indeed it would occasionally be helpful to be able to call static methods. [quoted text, click to view] > > (It's slightly easier for a void method than for a method returning T > > as described by the OP - just because Foo has a static Parse method > > returning Foo, that doesn't mean that every derived type will have a > > static Parse method returning an instance of itself.) > > True. But is that issue unique to static methods? It seems like it's > more of an issue with respect to any method that returns a type the same > as the generic type T. For example, a cloning method. Obviously, however > the method is used in the generic class, it has to be constrained to > returning something that is known to exist at compile time. But as long > as that requirement is met, it should be possible. And the issue is the > same whether the method is static or not.
The point (not clearly made, unfortunately) is that the OP wouldn't be able to specify that a particular method signature were required whether it was a static method or an instance method. It's basically a problem with the idea of specifying methods as constraints where the type parameter is part of the parameter list or the return type. [quoted text, click to view] > > Either way, there isn't a way of doing it, I'm afraid. (Well, there's > > reflection, but I'm assuming we're not including that.) > > Yes. I avoid reflection as much as possible, in the same way I avoid > doing native Windows stuff as much as possible in .NET. I much prefer to > use the .NET Framework-provided mechanisms whenever possible, and if there > isn't one my next step is to try to implement what I'm doing some other > way that does use .NET Framework-provided mechanisms.
:) [quoted text, click to view] > > No, there just isn't a way of calling static methods. Basically static > > methods don't have any kind of polymorphism (unfortunately) and that's > > a large part of what the constraints are for. > > Okay, I'll bite. Maybe I've been using generics in a naive manner, but > I'm missing the "that's a large part of what the constraints are for" > aspect of your comment. In what way do static methods fail to provide the > kind of polymorphism that is "a large part of what the constaints are > for"? Can you provide an example?
Polymorphism lets me call a method declared in a base class, knowing that the method may be overriden by a derived class (assuming it's virtual, of course). There's no concept in .NET of a virtual static method which can be overridden in a derived class - if there are two static methods with the same signature (one in the base class, one in the derived class), they're completely unrelated as far as the compiler is concerned. (Note that this isn't the case in Delphi, as far as I understand it.) There's therefore a difference between inserting a call to instanceOfT.SomeVirtualMethod(); and T.StaticMethod(); - either the compiler needs to look for "extra" methods with the appropriate signature, or you wouldn't get the pseudo-polymorphism which is desired, and you might as well call the static method in the class specified in the constraint. [quoted text, click to view] > > Note that from the implementation side of things, there would be a cost > > to this. Currently, I believe the JITted code for, say, List<T> is > > shared for all reference types, but a separate version is required for > > each value type. If static methods were allowed, you'd need a separate > > version for each reference type as well, as they'd be calling different > > static methods. Only in the case where the generic type *did* call any > > static methods, of course... > > So I guess my question is "why can't you call static methods from generic > classes"? And it sounds as though the answer is simply that it would > complicate the implementation of generic classes. Is that correct? It's > not that it couldn't be done, but rather that it would change the > underlying implementation of generics in an unfavorable way?
No, I think it's more than that. It would be sort of introducing polymorphism to static methods "by the back door" *or* be not particularly useful. Both options are quite clunky. Now, if true polymorphism of static methods were ever introduced somehow, then it would make a lot of sense for generics to be able to pick up on that. -- Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Don't see what you're looking for? Try a search.
|