473,473 Members | 2,120 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Generic Properties/Methods

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 subclass of
Logical (LogicalA, LogicalB). I'm currently casting them to the right
type when I retrieve them, but obviously this isn't terribly 'nice'.

I tried converting the class to be generic, and having a type parameter
that affected the type of the Logical property. But then I couldn't
have a single pointer variable that could point to any instance of the
class, as you can't cast from one generic class to another - i.e. you
can't have
RootClass<object= RootClass<TextBox>;
and some of my code depends on keeping a point to the currently active
class.

So, I thought, I'll try creating a separate method
GetLogical<LogicalTypeand then converting it from an open to a closed
type in the sublclass.

But it seems you can't close an open generic method as:
class BaseReturner
{
public virtual T GetLogical<T>() where T : new()
{
return default(T);
}

class TextBoxReturner : BaseReturner
{
public override TextBox GetLogical<Windows.Forms.TextBox>()
{
return new TextBox();
}
}

returns an error.

Is there any way of doing this, or should I just go back to casting
things back and forth?

Cheers,

Andy

Sep 29 '06 #1
4 3229
"Andrew Ducker" <an****@ducker.org.uka écrit dans le message de news:
11**********************@i42g2000cwa.googlegroups. com...

|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 subclass of
| Logical (LogicalA, LogicalB). I'm currently casting them to the right
| type when I retrieve them, but obviously this isn't terribly 'nice'.
|
| I tried converting the class to be generic, and having a type parameter
| that affected the type of the Logical property. But then I couldn't
| have a single pointer variable that could point to any instance of the
| class, as you can't cast from one generic class to another - i.e. you
| can't have
| RootClass<object= RootClass<TextBox>;
| and some of my code depends on keeping a point to the currently active
| class.

One solution is to have a non-generic base class to the generic one and put
non-type-specific properties/methods in that.

class RootClass
{
...
}

class RootClass<typeT: RootClass
{
...
}

| So, I thought, I'll try creating a separate method
| GetLogical<LogicalTypeand then converting it from an open to a closed
| type in the sublclass.
|
| But it seems you can't close an open generic method as:
| class BaseReturner
| {
| public virtual T GetLogical<T>() where T : new()
| {
| return default(T);
| }
|
| class TextBoxReturner : BaseReturner
| {
| public override TextBox GetLogical<Windows.Forms.TextBox>()
| {
| return new TextBox();
| }
| }

Try a generic static version of BaseReturner, and then you can have a
generic method that returns the appropriate object.

public static class Returner<typeTwhere typeT : new()
{
public static typeT GetLogical()
{
return new typeT();
}
}

Then you can simply call :

{
TextBox tb = Returner<TextBox>.GetLogical();
...
}

But then you might just as well have a non-virtual generic method in a
generic base class. Then the type will always be correct.

public class RootClass<typeTwhere typeT : new()
{
public typeT GetLogical()
{
return new typeT();
}

...
}

public class TextBoxRootClass : RootClass<TextBox{ }
{
RootClass test = new TextBoxRootClass();

TextBox box = test.GetLogical();

...
}

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Sep 29 '06 #2
Joanna Carter [TeamB] wrote:
But then you might just as well have a non-virtual generic method in a
generic base class. Then the type will always be correct.
But the problem is that I want to make sure that there is always a
method/property that returns a Logical, but I want the exact subtype of
Logical to be changable with the subclass that's returning it.

Let's say I'm working with different kinds of jobs (Gardener, Chef,
etc.) I have a bunch of JobPanels, each of which returns a JobInfo.

I _want_ to create a JobPanel<JobInfoType: where JobInfoType :
JobInfo.

Then I could create a class of ChefInfo : JobInfo and a ChefPanel :
JobPanel<ChefInfo>.

And in fact I _can_ do that. But I also want to know what the current
open JobPanel is. And I can't have
JobPanel currentJobPanel = ...
because there is no base class.

I suppose I could create a JobPanel, and then create a
JobPanel<JobInfoTypesubclassing from it, that merely added the
returning JobInfo. That would make sense.

Seems kinda hackish though.

Andy

Sep 29 '06 #3
"Andrew Ducker" <an****@ducker.org.uka écrit dans le message de news:
11**********************@h48g2000cwc.googlegroups. com...

| But the problem is that I want to make sure that there is always a
| method/property that returns a Logical, but I want the exact subtype of
| Logical to be changable with the subclass that's returning it.

Ok, if you want to guarantee that the type returned is always derived from a
base class, then state that in the constraints :

public abstract class RootClass<typeTwhere typeT : Logical, new()
{
public abstract typeT GetLogical();

...
}

public class TextBoxRootClass : RootClass<TextBoxLogical>
{
public override typeT GetLogical()
{
return new TextBoxLogical();
}
}
{
RootClass test = new TextBoxRootClass();

// either

Logical logical = test.GetLogical()

// or

TextBoxLogical textBoxLogical = test.GetLogical();

...
}

| Let's say I'm working with different kinds of jobs (Gardener, Chef,
| etc.) I have a bunch of JobPanels, each of which returns a JobInfo.
|
| I _want_ to create a JobPanel<JobInfoType: where JobInfoType :
| JobInfo.
|
| Then I could create a class of ChefInfo : JobInfo and a ChefPanel :
| JobPanel<ChefInfo>.
|
| And in fact I _can_ do that. But I also want to know what the current
| open JobPanel is. And I can't have
| JobPanel currentJobPanel = ...
| because there is no base class.
|
| I suppose I could create a JobPanel, and then create a
| JobPanel<JobInfoTypesubclassing from it, that merely added the
| returning JobInfo. That would make sense.

In theory, there is no need for a common base class like System.Object; all
classes could be compiled to automatically include that functionality; but
separating out such a base class allows us to put any kind of object into a
System.Object reference, even though we might not really want the
functionality that that object requires.

Using generic classes can also require a non-generic base class for the
reasons that you have found. I don't think this is particularly "hackish",
simply a separation of concerns between those parts of a class hierarchy
that need to be generic from those that don't.

C# doesn't allow co-variance of generic types because of all the problems
that this could cause; once a MyThing<intis cast to a MyThing<objectI am
now allowed to assign anything that derives from System.Object to
parameterised properties of that class, even though they are not ints...
Ouch !!

Does that help or hinder :-)

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Sep 29 '06 #4
Joanna Carter [TeamB] wrote:
C# doesn't allow co-variance of generic types because of all the problems
that this could cause; once a MyThing<intis cast to a MyThing<objectI am
now allowed to assign anything that derives from System.Object to
parameterised properties of that class, even though they are not ints...
Yeah - I reached that conclusion - GetInt would convert to GetObject
just fine, but SetInt isn't going to like being sent objects at all.
Which means it _could_ work for things that were read only, but that
sounds like a lot of work for not much reward on the part of the
language designers.

Being able to "close" an "open" generic method would still be nice, but
I can live without it.

Thanks for your help.

Andy

Sep 29 '06 #5

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

Similar topics

5
by: Richard Brown | last post by:
Ok, I've been looking through the .NET SDK docs and stuff. I'm wondering if you can provide a control extender that does generic validation or functionality just by dropping it on the form. For...
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#...
0
by: Wiktor Zychla [C# MVP] | last post by:
We do have generic classes, methods and delegates. My question is: what reason prevents us from having generic properties and indexers? // impossible public List<T> GetList<T> { get { ... }
25
by: Lars | last post by:
Hi, I have a base class holding a generic list that needs to be accessed by both the base class and its subclasses. What is the best solution to this? I am fairly new to generics, but I am...
10
by: phancey | last post by:
I'm quite new to generics. I have 2 generic classes: MyClass<Tand MyOtherClass<T>. MyClass<Thas 2 public Add methods Add(MyOtherClass<T>); Add(MyOtherClass<Wrapper<T>>); (Wrapper<Tis another...
10
by: fig000 | last post by:
HI, I'm new to generics. I've written a simple class to which I'm passing a generic list. I'm able to pass the list and even pass the type of the list so I can use it to traverse it. It's a...
4
by: =?Utf-8?B?RXRoYW4gU3RyYXVzcw==?= | last post by:
Hi, I have written a generic method which does different things depending on the type of the parameter. I got it to work, but it seems really inelegant. Is there a better way to do this? In the...
7
by: =?Utf-8?B?RXRoYW4gU3RyYXVzcw==?= | last post by:
I have a Class "Multidictionary" which I created which is basically a dictionary which can have multiple values for the same key. The class centers around private Dictionary<K,...
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: 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
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,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.