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 call to work?
Exists is a method within the Swatch class NOT the SwatchPanel class.
Is this possible?
Suggestions would be very welcome.
Thanks,
Steve
public class SwatchPanel<TSwatch> : System.Windows.Forms.Panel where TSwatch : Swatch
{
protected virtual bool SetOkButtonState()
{
if (TSwatch.Exists(ColorDescription))
do something
}
} 10 2263
steve bull <bu****@comcast.net> wrote: I have a class SwatchPanel which takes Swatch as a parameter type. How can I call a static function within the Swatch class?
Why not just call Swatch.Exists, i.e. don't use the generic argument at
all? You won't be able to use an "overridden" version of Swatch.Foo,
but then you can't override static methods anyway.
--
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
it seems to me that the implementation of generics allows nothing but the most trivial of exercises to be done - without a means of
doing anything different based on the type allows only duplication and little variation.
For example if I want to write
public class SwatchPanel<TSwatch> : System.Windows.Forms.Panel where TSwatch : Swatch
{
List<TSwatch> swatchList;
public MethodA
{
Swatch.Write(swatchList);
}
}
to have different methods for writing out the swatches based on type. the compiler does not appear to let me.
I cannot say TSwatch.Write and when I write the following under the Swatch class
public class Swatch
{
public static void Write(List<Swatch> colorSwatchList)
{
write to swatch file
}
public static void Write(List<ColorSwatch> colorSwatchList)
{
write to color swatch file
}
public static void Write(List<ShadeSwatch> shadeSwatchList)
{
write to shade swatch file
}
}
the compiler tells me
Can't convert from 'System.Collections.Generic.List<TSwatch>' to 'System.Collections.Generic.List<NewControls.Swatc h>'
it always picks up the 1st override. If I switch the Swatch override with the ColorSwatch override it will want to convert to a
ColorSwatch generic list.
Maybe I am doing something very stupid here but it appears to be very difficult to do anything of any use with generics except
cookie cutting. They are a brain dead implementation.
If I make SwatchPanel a normal class and derive classes from it I can do everything all of the above w/o problem. Then the problem
is with making the Swatch.Write work with List<Swatch> swatchList. Each child class then has to convert from List<Swatch> to
List<ColorSwatch> etc when it wants to do the actual write in the method appropriate to it.
I am sorry if this is not the place to bring this up. But the implementation seems pretty poorly thought out.
Thanks,
Steve
On Thu, 8 Dec 2005 01:56:38 -0000, Jon Skeet [C# MVP] <sk***@pobox.com> wrote: steve bull <bu****@comcast.net> wrote: I have a class SwatchPanel which takes Swatch as a parameter type. How can I call a static function within the Swatch class?
Why not just call Swatch.Exists, i.e. don't use the generic argument at all? You won't be able to use an "overridden" version of Swatch.Foo, but then you can't override static methods anyway.
steve bull <bu****@comcast.net> wrote: it seems to me that the implementation of generics allows nothing but the most trivial of exercises to be done - without a means of doing anything different based on the type allows only duplication and little variation.
That's not true at all. It doesn't allow the kind of templating C++
does, but frankly I'm glad of that.
For example if I want to write
public class SwatchPanel<TSwatch> : System.Windows.Forms.Panel where TSwatch : Swatch { List<TSwatch> swatchList;
public MethodA { Swatch.Write(swatchList); } }
to have different methods for writing out the swatches based on type. the compiler does not appear to let me. I cannot say TSwatch.Write and when I write the following under the Swatch class
<snip>
Indeed. And that would be a bad way of writing it, IMO. It looks like
you want polymorphism at that stage - either have a class which
encapsulates a list of Swatches (generically) and override the
behaviour appropriately, or have one Write method which uses
polymorphism on the Swatch class to work out how to write each entry.
Alternatively, have an instance method in SwatchPanel which writes its
list out.
Maybe I am doing something very stupid here but it appears to be very difficult to do anything of any use with generics except cookie cutting. They are a brain dead implementation.
Cookie-cutting is a good example of exactly what generics are for. The
way you're trying to do things isn't how they're intended to be used,
but that doesn't mean generics are bad. What you're trying to do breaks
object orientation in various ways - for instance, by having a set of
static methods in the base class, you're including knowledge of each of
the subclasses into Swatch into the that base class, when that
knowledge should either be in the subclasses themselves, or at worst
the specialised subclasses of SwatchPanel.
If I make SwatchPanel a normal class and derive classes from it I can do everything all of the above w/o problem. Then the problem is with making the Swatch.Write work with List<Swatch> swatchList. Each child class then has to convert from List<Swatch> to List<ColorSwatch> etc when it wants to do the actual write in the method appropriate to it.
I am sorry if this is not the place to bring this up. But the implementation seems pretty poorly thought out.
There are limitations which are genuinely problematic, but I don't
think I'd agree that anything you've brought up so far is actually a
problem with generics.
--
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
Jon wrote: steve bull <bu****@comcast.net> wrote: it seems to me that the implementation of generics allows nothing but the most trivial of exercises to be done - without a means of doing anything different based on the type allows only duplication and little variation. That's not true at all. It doesn't allow the kind of templating C++ does, but frankly I'm glad of that.
I must say I agree with Steve. Generics seem to be useful for writing
typesafe containers, avoiding casts, and not much else. They'd be
capable of so much more if only we had better constraints. If he could
write, for example:
public class SwatchPanel<TSwatch> : Panel
where TSwatch has static void Write(List<TSwatch> foo)
Then this would be no problem.
As it is, we can't even write a generic Sum() function without
resorting to all kinds of ugly hacks, because the compiler can't see
the similarity between adding two ints and adding two floats. (We can
write a generic Max(), but only because the framework designers had the
foresight to make the basic types implement IComparable.)
Indeed. And that would be a bad way of writing it, IMO. It looks like you want polymorphism at that stage - either have a class which encapsulates a list of Swatches (generically) and override the behaviour appropriately, or have one Write method which uses polymorphism on the Swatch class to work out how to write each entry.
I agree that in this case, static methods are the wrong way to go. I'd
prefer the former solution, but it has the disadvantage that the list
class can't be located and instantiated automatically by the panel
without using reflection. You'd have to either construct the list
before the panel and pass it in to the constructor, or make the list
class an additional type parameter of SwatchPanel (with a new()
constraint).
Jesse
Jesse McGrew wrote: Jon wrote: steve bull <bu****@comcast.net> wrote: it seems to me that the implementation of generics allows nothing but the most trivial of exercises to be done - without a means of doing anything different based on the type allows only duplication and little variation. That's not true at all. It doesn't allow the kind of templating C++ does, but frankly I'm glad of that.
I must say I agree with Steve. Generics seem to be useful for writing typesafe containers, avoiding casts, and not much else.
Well, I don't think that's quite true - but even if it were, isn't that
still a huge leap forward? Steve seems to be dismissing generics as
only useful in "trivial" situations, whereas I use collections the
whole time in real applications.
They'd be capable of so much more if only we had better constraints. If he could write, for example:
public class SwatchPanel<TSwatch> : Panel where TSwatch has static void Write(List<TSwatch> foo)
Then this would be no problem.
Absolutely. And the language would be a lot more complicated, which is
something I don't like.
There are all kinds of things it would be nice to have contracts for -
it would be nice if an interface could specify the constructors or
static methds which must be available, for instance, so that plugins
loaded reflectively could provide methods of being instantiated
appropriately. However, once you start putting things
As it is, we can't even write a generic Sum() function without resorting to all kinds of ugly hacks, because the compiler can't see the similarity between adding two ints and adding two floats. (We can write a generic Max(), but only because the framework designers had the foresight to make the basic types implement IComparable.)
Yes, generics fails pretty badly in terms of operators. Indeed. And that would be a bad way of writing it, IMO. It looks like you want polymorphism at that stage - either have a class which encapsulates a list of Swatches (generically) and override the behaviour appropriately, or have one Write method which uses polymorphism on the Swatch class to work out how to write each entry.
I agree that in this case, static methods are the wrong way to go. I'd prefer the former solution, but it has the disadvantage that the list class can't be located and instantiated automatically by the panel without using reflection. You'd have to either construct the list before the panel and pass it in to the constructor, or make the list class an additional type parameter of SwatchPanel (with a new() constraint).
Yes. There are certainly issues there. I'd want to take a look at the
whole problem in a larger context, however. There may well be more
elegant solutions to what actually needs to be achieved if you move
further away from the existing attempted design.
Jon
"steve bull" <bu****@comcast.net> wrote in message
news:mo********************************@4ax.com... it seems to me that the implementation of generics allows nothing but the most trivial of exercises to be done - without a means of doing anything different based on the type allows only duplication and little variation.
For example if I want to write
public class SwatchPanel<TSwatch> : System.Windows.Forms.Panel where TSwatch : Swatch { List<TSwatch> swatchList;
public MethodA { Swatch.Write(swatchList); } }
to have different methods for writing out the swatches based on type. the compiler does not appear to let me. I cannot say TSwatch.Write and when I write the following under the Swatch class
public class Swatch { public static void Write(List<Swatch> colorSwatchList) { write to swatch file }
public static void Write(List<ColorSwatch> colorSwatchList) { write to color swatch file }
public static void Write(List<ShadeSwatch> shadeSwatchList) { write to shade swatch file } }
the compiler tells me
Can't convert from 'System.Collections.Generic.List<TSwatch>' to 'System.Collections.Generic.List<NewControls.Swatc h>'
it always picks up the 1st override. If I switch the Swatch override with the ColorSwatch override it will want to convert to a ColorSwatch generic list.
Maybe I am doing something very stupid here but it appears to be very difficult to do anything of any use with generics except cookie cutting. They are a brain dead implementation.
If I make SwatchPanel a normal class and derive classes from it I can do everything all of the above w/o problem. Then the problem is with making the Swatch.Write work with List<Swatch> swatchList. Each child class then has to convert from List<Swatch> to List<ColorSwatch> etc when it wants to do the actual write in the method appropriate to it.
I am sorry if this is not the place to bring this up. But the implementation seems pretty poorly thought out.
Thanks,
Steve
The issue with what you are trying to I believe is because determining which
overload of a method should be used is determined at COMPILE time. However,
information about the generic type will not be determined until runtime, so
the compiler has no way to use the other overloads. The only determination
that can be made at compile time is that TSwatch must be a Swatch, so the
first overload is used.
--
Adam Clauss
On Thu, 8 Dec 2005 07:13:21 -0000, Jon Skeet [C# MVP] <sk***@pobox.com> wrote:
to have different methods for writing out the swatches based on type. the compiler does not appear to let me. I cannot say TSwatch.Write and when I write the following under the Swatch class <snip>
Indeed. And that would be a bad way of writing it, IMO. It looks like you want polymorphism at that stage - either have a class which encapsulates a list of Swatches (generically) and override the behaviour appropriately, or have one Write method which uses polymorphism on the Swatch class to work out how to write each entry.
the problem with this suggestion is that it just pushes the problem down a level.
e.g. if I encapsulated the swatchList as SwatchList<TSwatch> and call swatchList.Write() I would still need to get some
constant information associated with that swatch type in the new class. Which is the same problem in a different place. Alternatively, have an instance method in SwatchPanel which writes its list out.
I am not quite sure what you mean here. Do you mean write routines
Write(List<ColorSwatch) swatchList)
Write(List<ShadeSwatch> swatchList) etc?
If so it would seem to me that it would break all the reasons for using generics in the 1st place.
I still don't see any way forward with this - I seem to be better off going back to subclassing and using a non-typesafe
array. At least it avoids all these issues even though it is far from ideal.
Thanks for all the feedback.
Steve
steve bull <bu****@comcast.net> wrote: Indeed. And that would be a bad way of writing it, IMO. It looks like you want polymorphism at that stage - either have a class which encapsulates a list of Swatches (generically) and override the behaviour appropriately, or have one Write method which uses polymorphism on the Swatch class to work out how to write each entry. the problem with this suggestion is that it just pushes the problem down a level. e.g. if I encapsulated the swatchList as SwatchList<TSwatch> and call swatchList.Write() I would still need to get some constant information associated with that swatch type in the new class. Which is the same problem in a different place.
No, it's not - because then you could ask for *instance* information,
and that could be overridden. If you have ColorSwatchList which extends
SwatchList<ColorSwatch>, that could override appropriate methods to say
what headers to use etc. Alternatively, have an instance method in SwatchPanel which writes its list out.
I am not quite sure what you mean here. Do you mean write routines
Write(List<ColorSwatch) swatchList) Write(List<ShadeSwatch> swatchList) etc?
Just WriteList(), given that it would already know the list internally.
You wouldn't have different methods - you'd have one method which could
be overridden in classes which needed to.
If so it would seem to me that it would break all the reasons for using generics in the 1st place.
I still don't see any way forward with this - I seem to be better off going back to subclassing and using a non-typesafe array. At least it avoids all these issues even though it is far from ideal.
I would try looking at the problem from scratch, and try to avoid using
overloading as a poor man's form of polymorphism - that's not what it's
there for.
--
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
"steve bull" wrote: On Thu, 8 Dec 2005 07:13:21 -0000, Jon Skeet [C# MVP] <sk***@pobox.com> wrote:
to have different methods for writing out the swatches based on type. the compiler does not appear to let me. I cannot say TSwatch.Write and when I write the following under the Swatch class <snip>
Indeed. And that would be a bad way of writing it, IMO. It looks like you want polymorphism at that stage - either have a class which encapsulates a list of Swatches (generically) and override the behaviour appropriately, or have one Write method which uses polymorphism on the Swatch class to work out how to write each entry.
the problem with this suggestion is that it just pushes the problem down a level. e.g. if I encapsulated the swatchList as SwatchList<TSwatch> and call swatchList.Write() I would still need to get some constant information associated with that swatch type in the new class. Which is the same problem in a different place.
no it doesn't. here's what Jon has suggested
method1, have different speicialized swatch list classes
ColorSwatchList : SwatchList<ColorSwatch>
ShadeSwatchList : SwatchList<ShadeSwatch>
and each list will have a method Write() that knows how to write each entry
one by one.
method2, have each implementation of Swatch know how to write itself. then
the list will delegate the write operation to the individual entries.
both of which are the proper way of handle polymorphism. static methods are
not polymorphic. overloading them is not the right way to solve the problem.
Alternatively, have an instance method in SwatchPanel which writes its list out.
I am not quite sure what you mean here. Do you mean write routines
Write(List<ColorSwatch) swatchList) Write(List<ShadeSwatch> swatchList) etc?
If so it would seem to me that it would break all the reasons for using generics in the 1st place. I still don't see any way forward with this - I seem to be better off going back to subclassing and using a non-typesafe array. At least it avoids all these issues even though it is far from ideal.
Thanks for all the feedback.
Steve
Thank you for taking up so much of your time to make all these suggestions.
I don't think generics are the natural way of dealing with my problem. The way I originally developed the SwatchPanel as
a series of subclasses worked pretty well where SwatchPanel did most of the work. Thinking about what you have talked
about leads me to believe that the original reason for trying generics might be overcome with some of your suggestions.
Using subclasses only had the problem of passing around a List<Swatch> to the read/write routines which I wanted to be
cast to the swatch type appropriate to those routines. I think that encapsulating the swatchList as you described would
work there as well. What I have also works, it doesn't break any OO rules I don't think and I don't need to retest
everything again.
In fact, using generics, read/write wasn't the only problem I had - just the biggest of them. For example when I draw
the swatches on the panel they could be different sizes depending on the type of swatch and this would be a SwatchPanel
parameter really as I could decide, and have, to write other widgets which have different sizes that they would have the
swatches draw themselves.
Your explanations have been much appreciated.
Thanks,
Steve
On Thu, 8 Dec 2005 18:05:29 -0000, Jon Skeet [C# MVP] <sk***@pobox.com> wrote: steve bull <bu****@comcast.net> wrote: >Indeed. And that would be a bad way of writing it, IMO. It looks like >you want polymorphism at that stage - either have a class which >encapsulates a list of Swatches (generically) and override the >behaviour appropriately, or have one Write method which uses >polymorphism on the Swatch class to work out how to write each entry.
the problem with this suggestion is that it just pushes the problem down a level. e.g. if I encapsulated the swatchList as SwatchList<TSwatch> and call swatchList.Write() I would still need to get some constant information associated with that swatch type in the new class. Which is the same problem in a different place.
No, it's not - because then you could ask for *instance* information, and that could be overridden. If you have ColorSwatchList which extends SwatchList<ColorSwatch>, that could override appropriate methods to say what headers to use etc.
>Alternatively, have an instance method in SwatchPanel which writes its >list out.
I am not quite sure what you mean here. Do you mean write routines
Write(List<ColorSwatch) swatchList) Write(List<ShadeSwatch> swatchList) etc?
Just WriteList(), given that it would already know the list internally. You wouldn't have different methods - you'd have one method which could be overridden in classes which needed to.
If so it would seem to me that it would break all the reasons for using generics in the 1st place.
I still don't see any way forward with this - I seem to be better off going back to subclassing and using a non-typesafe array. At least it avoids all these issues even though it is far from ideal.
I would try looking at the problem from scratch, and try to avoid using overloading as a poor man's form of polymorphism - that's not what it's there for. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Justin Shen |
last post by:
you can define two class with same name but having different generic
parameters in one assembly. As below:
class Gen<T>
{
}
class Gen<T1,T2>
{
}
|
by: Tigger |
last post by:
I have an object which could be compared to a DataTable/List which I am
trying to genericify.
I've spent about a day so far in refactoring and in the process gone
through some hoops and hit some...
|
by: Bilz |
last post by:
Ok, lets say I have a generic method:
public T Testing<T>() : where T:class
{
T myT = getStuff() as T;
// Do something with myT
return myT;
}
How do I call it dynamically? The following...
|
by: Bob Rock |
last post by:
Hello,
is there a way of retrieving the type of the class containing a static
method from the method itself when it gets called?
I have this situation: an abstact class that defines a static...
|
by: gregory.lielens |
last post by:
Hello,
We are currently writing python bindings to an existing C++ library,
and we encountered
a problem that some of you may have solved (or that has found
unsolvable :( ):
A C++ class...
|
by: Steve Richter |
last post by:
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...
|
by: Steven D'Aprano |
last post by:
I have a class which is not intended to be instantiated. Instead of using
the class to creating an instance and then operate on it, I use the class
directly, with classmethods. Essentially, the...
|
by: Andrus |
last post by:
Winforms UI assembly has static FormManager.FormCreator method which creates
forms taking entity as parameter.
I need to pass this method to business objects in business assembly so that
business...
|
by: SimonDotException |
last post by:
I've written an abstract base type which uses generics to provide XML serialization and deserialization methods for use by its derived types, but I'm seemingly unable to write it in a way which...
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
|
by: tracyyun |
last post by:
Hello everyone,
I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
|
by: giovanniandrean |
last post by:
The energy model is structured as follows and uses excel sheets to give input data:
1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
|
by: nia12 |
last post by:
Hi there,
I am very new to Access so apologies if any of this is obvious/not clear.
I am creating a data collection tool for health care employees to complete. It consists of a number of...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
|
by: isladogs |
last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, Mike...
|
by: GKJR |
last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...
| |