|
use Antenna House XSL Formatter - you can use it to generate PDFs from XML
http://www.antennahouse.com/[^]
"When the only tool you have is a hammer, a sore thumb you will have."
|
|
|
|
|
Given:
class VirtualClass
{
public virtual void VirtualMethod()
{
Console.WriteLine("VirtualClass:VirtualMethod");
}
}
class OverrideClassA : VirtualClass
{
public override void VirtualMethod()
{
Console.WriteLine("OverrideClassA:VirtualMethod");
base.VirtualMethod();
}
}
class OverrideClassB : OverrideClassA
{
public override void VirtualMethod()
{
Console.WriteLine("OverrideClassB:VirtualMethod");
base.VirtualMethod();
}
}
and the instantiation:
OverrideClassB ocb=new OverrideClassB();
How can I access just the VirtualMethod in OverrideClassA? In C++, I used to be able to say ((OverrideClassA)ocb).VirtualMethod(); , but this still invokes the "B" class method in C#.
How do I do this? (A typical case might be where I have an edit control that I've derived some functionality, and in a particular case, I want to use the base class' implementation).
Thanks,
Marc
Help! I'm an AI running around in someone's f*cked up universe simulator.
|
|
|
|
|
I've not been inn this exact scenario, but typically I've used the base keyword to get at the base classes procedures.
so you would have something like this...
base.Virtualmethod();
It's been a while and I could be wrong
Mark Conger
|
|
|
|
|
base is only available in a subclass of base. You couldn't call base on an instance of an object.
Virtual methods are supposed to allow the instantiation of any of the child classes parent virtual methods. I'm sure C# provides a way to do it, and if I find it, I'll let ya know.
|
|
|
|
|
Um, I'm confused here. You say I'm wrong (I think) but your first statement says I'm right. If you go from the example code he gave, he is trying to call a function that he inherited from the parent class (sublassing). I've done something similar to this in control programming and it worked fine using the base keyword.
I'm not trying to be hostile. I'm just confused as to your response since, based on my understanding of the example, you're saying I'm right and wrong. Could you please elaborate using Marc's example to illustrate why base would not work?
Mark Conger
|
|
|
|
|
Sorry....let me see if I can clarify (based on my understanding of the original question).
From what I understood, the question was can you explicitly instantiate a virtual method of a base class from an instance of a subclass:
Quote-----
"and the instantiation:
OverrideClassB ocb=new OverrideClassB();
How can I access just the VirtualMethod in OverrideClassA? In C++, I used to be able to say ((OverrideClassA)ocb).VirtualMethod();, but this still invokes the "B" class method in C#."
ocb is an instance of OverrideClassB. In C++, you can do ((OverrideClassA)ocb).VirtualMethod() to explicitly call the virtual method of a base class on an instance of a subclass.
My response was stating the fact that the object base is only available in the class declaration. Its not available on the instance of a class. Therefor, its not possible to call base on an instance of a class, such as the instance ocb used above. Base is available in the definition of a class, not in an instance.
Example:
class BaseClass
{
public virtual void Method()
{
}
}
class DerivedClass: BaseClass
{
public override void Method()
{
base.Method()
}
}
DerivedClass dc = new DerivedClass();
dc.Method();
Hope that helps. Sorry for the misunderstanding.
|
|
|
|
|
I have a class collection which contains another collection which contains another collection etc.
-StockCollections[]
-StockCollection
-StockItems[]
-StockItem
-StockItemColours[]
-StockItemColour
-StockItemSizes[]
-StockItemSize
Pretty simple structure really, just a bit deep.
In the constructor of each collection ([]) class there is some code which queries the database and populates the collection with items.
Now this may sound stupid to you, but I just need to know something: When I construct that top level StockCollections[] collection are all other sub-items and sub-collections also "activated" and populated? Or does it only populate the sub-collections when they are "called" (for instance in a foreach loop (thanks to Nish for the IEnumerable code ).)
If that is the case then I have a problem (as you already guessed) as there may be up to 100 000 StockItems each with 10 to 20 Colour and Size options. Now if all I wanted was the titles of the items in the StockCollections[] collection then that is a huge amount of uneeded overhead.
Do you have any advice as to how you stop this happening? Or do I have to have two constructors for each collection, one which takes a parameter specifying not to load sub-items?
Any advice welcome, thanks
|
|
|
|
|
Paul,
This is what DataSets are for.
That said, if you really want to do it this way, I think you've already answered your own question:
Paul Watson wrote:
Or do I have to have two constructors for each collection, one which takes a parameter specifying not to load sub-items?
Paul
Why don't you take a good look at yourself and describe what you see - Led Zeppelin, Misty Mountain Hop
|
|
|
|
|
Paul Riley wrote:
This is what DataSets are for
Well unless you know something different about DataSets I "have" to use classes because there is going to be quite a bit of blogic involved in the handling of the data. It is not just a simple case of pull-and-display (for instance part of the database is 5 years old and has no relationships, no primary keys, no identity seeds and allows null values.... !!! And I cannot change it because a legacy system depends on the database not changing.)
|
|
|
|
|
Paul Watson wrote:
Well unless you know something different about DataSets I "have" to use classes because there is going to be quite a bit of blogic involved in the handling of the data.
Hmm... I see your problem. I see where yours and James' conversation is going and it's exactly what I'd be saying next, so I'll back off and leave you guys to it
Paul
Why don't you take a good look at yourself and describe what you see - Led Zeppelin, Misty Mountain Hop
|
|
|
|
|
One more thought, and I say it in full knowledge of the fact that the answer is probably "No", but is there no way you can have a Query/View put on the database to do the fiddling for you, making it appear to you as a simple table but to the legacy software like the hideous mess it already is?
Paul
Why don't you take a good look at yourself and describe what you see - Led Zeppelin, Misty Mountain Hop
|
|
|
|
|
Paul Watson wrote:
When I construct that top level StockCollections[] collection are all other sub-items and sub-collections also "activated" and populated? Or does it only populate the sub-collections when they are "called" (for instance in a foreach loop (thanks to Nish for the IEnumerable code ).)
That depends on how your constructor is set up, if each of the constructors automatically fill the objects underlying collection, then yes all 100 000 StockItems with all their Colour and Size options will be loaded.
What you can do to help prevent that is make each object's collection a property, in the get method for that property you can populate the collection (if you haven't done so already).
In psuedo/C#-code for how you would do this with the StockItem class (since I have a pretty good idea how that is used ).
class StockItem
{
private StockItemColour[] colours = null;
....
public StockItemColour[] StockItemColours
{
get
{
if( colours == null )
{
colours = FetchColoursFromDB();
}
return colours;
}
}
...
} HTH,
James
Sig code stolen from David Wulff
|
|
|
|
|
James T. Johnson wrote:
What you can do to help prevent that is make each object's collection a property
And with those words you made me a happy man!
That is what I have done:
public class StockCollection
{
public StockItems StockItems
{
get {return new StockItems(this);}
}...
So in essence that return new StockItems(this) bit is only actually "run" when I use that property of the class instance, right? e.g.:
StockCollections stockcollectionsTest = new StockCollections();
foreach (StockCollection stockcollectionCurrent in stockcollectionsTest)
{
Response.Write("Collection Title: " + stockcollectionCurrent.Title + "<br />");
foreach(StockItem stockitemCurrent in stockcollectionCurrent.StockItems)
{
Response.Write("StockItem Title: " + stockitemCurrent.Title + "<br />");
}
}
I guess I should have actually stated in my question that the sub-collections are exposed as get properties of the items (it is often hard to figure out at which level to pitch a question. To high and people who may have the answer you are looking for ignore it, too low and you have to go through fifty sub questions to get to the heart f the matter.)
Properties rock overall IMO
Thanks James.
|
|
|
|
|
Hmmm, hard to use the Quote button with this one...
Paul Watson wrote:
// At this point property StockItems has not been "run" and therefore no sub-items populated, right?
Correct
Paul Watson wrote:
// But now it has been populated because of the stockcollectionCurrent.StockItems just above, right?
Correct again
Paul Watson wrote:
get {return new StockItems(this);}
I would consider changing this to cache the value returned like I did in my example; otherwise you'll be fetching the data from the DB each time you access the StockItems property.
Of course you may have left that detail out again
James
Sig code stolen from David Wulff
|
|
|
|
|
James T. Johnson wrote:
Of course you may have left that detail out again
Nope, good idea of yours, thanks
James T. Johnson wrote:
Correct again
Thanks for your help James, much appreciated.
p.s. Daniel now has me worried that my class setup is, while elegant, a bad idea Do you agree, disagree? And why have collections at all if they are a bad idea? (thankfully apart from the medium sized product database, the actual traffic to this site is low and it will only be running on one server. Not exactly a high stress site )
|
|
|
|
|
Paul Watson wrote:
Do you agree, disagree?
I can see this becoming an issue when this design forces you to load all of the records when you only needed a subset. In my design I abstracted even further to address other problems, but it looks like it could solve this 'problem*' as well.
I have: AdvertiserCollection -> Advertiser -> AdCollection -> Ad
None of these classes know anything about databases; I have separate classes responsible for that, and they take into account whether all of the records are needed or only a subset.
*This only becomes a problem when you are fetching all of the rows when you don't need to. If your current code doesn't do this, then there isn't a problem now but there could be one in the future when you forget about this and wonder why it performs badly.
James
Sig code stolen from David Wulff
|
|
|
|
|
James T. Johnson wrote:
None of these classes know anything about databases; I have separate classes responsible for that, and they take into account whether all of the records are needed or only a subset.
Fully, I certainly have not made it so that each time I need a list of Ads from a certain Advertiser that each Ad constructor opens a DB connection and pulls down just it's own details. But I have not gone as far as to abstract the database bit out of the class, mainly for time sake as Mr. Client paid for an el-cheapo-quick-fix version (you should have seen the arguements I had with the client trying to get the database re-designed. whole portions of the database have no relations, no primary keys, no identity seeds and even allow NULL values which just causes endless problems. But then the other half does, so it is just a nightmare.)
Anyway, thanks again for the info
|
|
|
|
|
Paul Watson wrote:
I have not gone as far as to abstract the database bit out of the class
I did it mainly because I'm still up in the air over if I'm going to use Access or MSDE on the client's computer. This approach keeps most of the code the same, changing just the *DB classes.
It also bridges on whether I can get him to upgrade his last crappy PC to a new Win2K box. I don't think I want MSDE running on a system with only 64MB of RAM
James
Sig code stolen from David Wulff
|
|
|
|
|
You're in trouble: this kind of code, although OOP-friendly and very elegant, always lead to bad performance, sooner or later.
Unfortunately, the COM+ way of doing things and having stateless components wich usually only return the needed data asked is the way to go if you have performance and scalability concerns, despite its ugliness.
The collection-style data access layer also puts you in trouble when you need your data in different ways. The way you are designing you collection classes do not reflect properly a relational database and can leave you in really bad water when in the future you need even the simplest reports or calculations.
If you decide going this way, it’s better choosing a object oriented database instead of a relational database, e.g. Caché, which allows you to store things this way, takes care of the issues you noticed and lets you query it in a flexible way.
Q261186 - Computer Randomly Plays Classical Music
|
|
|
|
|
Daniel Turini wrote:
although OOP-friendly and very elegant
Damn you had me going with that... and then...
So if this way is elegant and what not but bad for performance and scalability what is the point? Why have the collection option at all? Or am I using it in a bad way?
Daniel Turini wrote:
Unfortunately, the COM+ way of doing things and having stateless components wich usually only return the needed data asked is the way to go
Got any examples/samples of this way? Would be interested to see, ta.
BTW with James' help it seems data is only pulled when needed, and not just when the top level collection is instantiated, thankfully
|
|
|
|
|
|
About the database. Is it possible to create a view from these mangled tables, adding the required constraints and indexing, etc. through the view. You would then be able to properly insert new records with newer applications, as well as beeing able to use DataSets. If its not possible to create views with the current DBMS, it might be worthwhile to convince your client to upgrade to MS SQL Server, and just import the data, then create the views.
It just seems like your going through a ton of work just to represent/provide data in the way you want. And the way your going about it, no offense meant, looks like it could possibly create more work later on, (i.e. in the future). (I know, clients NEVER care about the future, and get cranky when you mention it. )
Anyway, just some thoughts after reading the thread.
|
|
|
|
|
Jon Rista wrote:
your client to upgrade to MS SQL Server
We are using MS SQL server and I am making use of views and stored procedures. First off views are a touch limited and I am no pro at stored procedures (where is the intellisense! .)
For instance part of pulling the product out of the database involves checking the users delivery country, checking various special offers and special rules and then calculating the price. It gets complicated because each order can contain multiple delivery addresses (e.g. you buy three items, two for yourself and one for a friend) and each item is priced according to weight, type and time of year. There is also gift wrapping, gift tags and multiple VAT rules (including the fact that some products are exempt from VAT in certain countries due to their type.)
So basically there is a lot of "business logic" going on which is all calculated from the base data.
Now I thought that was the whole point of classes and a data abstraction layer. i.e. The database persists data. Store procedures and views provide the data (and to some extent stored procedures do business logic) to the classes and then the classes do various calculations and offer up that data in a nice usable way for the programmer to implement into a nice UI.
You mention DataSets (and so did Paul) but how is that going to improve things? Surely I am still going to have to encapsulate all the business logic somewhere and still then provide the DataSet data up for use to the front-end (or do DataSets allow for "complex" calculations to take place "inside" them in some way?)
Anyway thanks for the interest
|
|
|
|
|
DataSets are really just an in-memory cache of your database, or a part of it. And they don't nessesarily have to have a GUI. They can be created in conjunction with a schema, allowing for all the relationships and whatnot to be properly maintained in memory. You could load your data from the database into a dataset, use that as your database while doing your calculations, etc, and then persist that back to the database server when your done. It can improve performance and help keep things properly restricted.
|
|
|
|
|
create a workthread in c# ,and use Thread.Sleep(100000) in it.and when the main app exited ,the thread is still working!!!!
call the thread.Abort() and thread.join(0).It seemed useless.
what is the problem???
Is that a framework's bug???
lost my way
|
|
|
|