473,385 Members | 1,919 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Generic type converter class. Cant call static method of type T.

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);
}
}

May 8 '07 #1
9 5820
Steve Richter <St************@gmail.comwrote:
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 - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 8 '07 #2
On May 8, 1:53 am, Jon Skeet [C# MVP] <s...@pobox.comwrote:
Steve Richter <StephenRich...@gmail.comwrote:
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

May 8 '07 #3
On May 8, 2:14 pm, Steve Richter <StephenRich...@gmail.comwrote:
On May 8, 1:53 am, Jon Skeet [C# MVP] <s...@pobox.comwrote:
Steve Richter <StephenRich...@gmail.comwrote:
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).
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

May 8 '07 #4
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]
- mv*@spam.guard.caspershouse.com

"Steve Richter" <St************@gmail.comwrote in message
news:11**********************@e51g2000hsg.googlegr oups.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);
}
}

May 8 '07 #5
On Mon, 07 May 2007 22:53:57 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
Steve Richter <St************@gmail.comwrote:
>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. :)

Pete
May 8 '07 #6
Peter Duniho <Np*********@nnowslpianmk.comwrote:
Steve Richter <St************@gmail.comwrote:
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.)
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<Tis
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 - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 8 '07 #7
On Tue, 08 May 2007 11:16:06 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
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).
(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.
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.
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?
Note that from the implementation side of things, there would be a cost
to this. Currently, I believe the JITted code for, say, List<Tis
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?

Pete
May 8 '07 #8
Peter Duniho <Np*********@nnowslpianmk.comwrote:
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.
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.
(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.
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.
:)
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.
Note that from the implementation side of things, there would be a cost
to this. Currently, I believe the JITted code for, say, List<Tis
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 - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 8 '07 #9
On Tue, 08 May 2007 12:30:44 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
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.
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.
[...]
- 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).
>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. :)

Pete
May 8 '07 #10

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

Similar topics

17
by: Andreas Huber | last post by:
What follows is a discussion of my experience with .NET generics & the ..NET framework (as implemented in the Visual Studio 2005 Beta 1), which leads to questions as to why certain things are the...
4
by: Tom Jastrzebski | last post by:
Hello everybody, Here is the problem I came across experimenting with Generics. I would like to write a class or a struct adding integer to any other, initially undefined *numeric type*. So, my...
10
by: steve bull | last post by:
I have a class SwatchPanel which takes Swatch as a parameter type. How can I call a static function within the Swatch class? For example the code below fails on TSwatch.Exists. How can I get the...
4
by: Jethro Guo | last post by:
C++ template use constraint by signature,It's very flexible to programmer but complex for complier, and at most time programmer can not get clear error message from complier if error occur. C#...
8
by: JAL | last post by:
Here is my first attempt at a deterministic collection using Generics, apologies for C#. I will try to convert to C++/cli. using System; using System.Collections.Generic; using System.Text; ...
22
by: Adam Clauss | last post by:
OK, I have class A defined as follows: class A { A(Queue<B> queue) { ... } } Now, I then have a subclass of both classes A and B. The subclass of A (SubA), more specifically is passed a...
4
by: Charles Churchill | last post by:
I apologize if this question has been asked before, but after about half an hour of searching I haven't been able to find an answer online. My code is beloiw, with comments pertaining to my...
4
by: Andrew Ducker | last post by:
I have a collection of classes descending from a single root class (let's call it RootClass). They all currently have a property of Logical, of type Logical. However they actually return a...
26
by: raylopez99 | last post by:
Here is a good example that shows generic delegate types. Read this through and you'll have an excellent understanding of how to use these types. You might say that the combination of the generic...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
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...
0
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,...

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.