|
There are both static and instance constructors.
Instance constructors are the constructors that are called whenever you create a new instance of the class (e.g. Object foo = new Object() ).
Static constructors are called automagically by the runtime some non-deterministic time before you access the first static member/property/whatever of the class.
The problem isn't with the static constructors per se, it's that there doesn't seem to be any inheritance polymorphism involved. When I call ChildA.OutputClassName() the method uses the superclasses static properties, not ChildA's.
|
|
|
|
|
moredip wrote:
So it seems that inheritance polymorphism isn't available for the static members of a class. Is this intentional, and is there an elegant way around this?
I think its more to do with bad design
What you are infact doing is just calling the same static function pointing to the baseclass. Remember with static constructors, the base constructor is not called, hence the fact that classname never gets changed.
Do something like this rather:
<code><font size=2 face="Courier New"><font color="#FFFFFF"> </font><font color="#0000FF">class </font><font color="#000000">Parent
</font>{
<font color="#000000">internal </font><font color="#0000FF">static </font><font color="#000000">string className</font>;
<font color="#0000FF">static </font><font color="#000000">Parent</font>()
{
<font color="#000000">className </font>= <font color="#FF8000">"Parent"</font>;
}
<font color="#0000FF">static public void </font><font color="#000000">OutputClassName</font>()
{
<font color="#000000">System</font>.<font color="#000000">Console</font>.<font color="#000000">Out</font>.<font color="#000000">WriteLine</font>( <font color="#000000">className </font>);
}
}
<font color="#0000FF">class </font><font color="#000000">ChildA </font>: <font color="#000000">Parent
</font>{
<font color="#0000FF">static </font><font color="#000000">ChildA</font>()
{
<font color="#000000">Parent</font>.<font color="#000000">className </font>= <font color="#FF8000">"ChildA"</font>;
}
}
<font color="#0000FF">class </font><font color="#000000">ChildB </font>: <font color="#000000">Parent
</font>{
<font color="#0000FF">static </font><font color="#000000">ChildB</font>()
{
<font color="#000000">Parent</font>.<font color="#000000">className </font>= <font color="#FF8000">"ChildB"</font>;
}
}
</font>
</code>
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
Thanks for the help, but with the revised code I'm still getting the same problem.
Stepping through with the debugger, it seems that the derived class's static ctors are never called.
Is this an inherent restriction of the language, and if so how would I go about implementing functionality similar to the example (not specifically className stuff, but hsving static members that have different values in sub-classes)?
Thanks,
Pete
|
|
|
|
|
moredip wrote:
Stepping through with the debugger, it seems that the derived class's static ctors are never called.
Thats what I said, its like that by design
moredip wrote:
Is this an inherent restriction of the language, and if so how would I go about implementing functionality similar to the example (not specifically className stuff, but hsving static members that have different values in sub-classes)?
I would do the implementation in each class then. Its a bit long, but why would you want to do that? I cant think of any good reason.
PS: I never did test that code Just a question, did you change it from protected to internal?
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
>Thats what I said, its like that by design
Ah, sorry I misunderstood you.
>I would do the implementation in each class then. Its a bit long, but why would you want to do that? I cant think of any good reason.
Without going into too much detail, I'm making a light-weight wrapper class around ADO.NET.
The idea is that the base class has static members for tableName, PrimaryKeyName, etc. and some static methods (e.g. Delete( uint rowID ). The base class implements the Delete() method, using the values of the static variables. One could then implement a subclass which changes the values of tableName etc. and therefore changes the effect of Delete().
Does that make sense? I could post some example code if it'd help....
Oh, and I just tried changing it from protected to internal (missed that first time, as you guessed) - no diffence.
|
|
|
|
|
moredip wrote:
Without going into too much detail, I'm making a light-weight wrapper class around ADO.NET.
I have some code I have written a while back, I'll mail it to you, mite be all you need
moredip wrote:
Oh, and I just tried changing it from protected to internal (missed that first time, as you guessed) - no diffence.
OK, I know what the problem appears to be (still too tired to test it ). The static contructor only gets called when its need, then in your case none of those sub classes get staticcally contructed. By anyways look at the code. There is 2 parts, a class generator based on your table database, and secondly using the generated assembly. Email me if you need help, but look at the sample DB first.
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
Thanks for the code
Unfortunately I can't really use it, as the work I'm doing is part of a University project. I will look it over for inspiration though.
|
|
|
|
|
From an initial scan, this code looks similar to mine....
Where mine differs is that I wanted a static Delete() function. Semantically it doesn't make sense to instantiate a DataObject in order to call a DataObject::Delete() function that doesn't use any of the instance's data. So I wanted to create a static Delete() function that used the derived classes static values for things like tableName....
I can't figure out a way to do this The base class's static method has no way to know what derived class was used to invoke the method, as the method is static.
There must be a way to do this statically, but I can't figure it out
|
|
|
|
|
Just to clarify, I wanted a Delete( uint rowID ) function, that simply removes the specified row, and doesn't use any instance-specific data.
Oh and I also wanted a static DataObject[] GetAllRows() function......
|
|
|
|
|
moredip wrote:
Just to clarify, I wanted a Delete( uint rowID ) function, that simply removes the specified row, and doesn't use any instance-specific data.
But your are using instance specific data. The only solution is to add the same static function and static field for each class... Personally I would just use instances and let inheritance do the trick for me. Remember doing the following will allways return what ever classes satic contructor got called last (in your psuedo class).
Parent.PrintClassName();
ChildA.PrintClassName();
ChildB.PrintClassName();
static is just not kosher with OOP. You want to use a single value to store 3 different values. That is just impossible. Go the instance way rather.
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
I don't think I am using instance-specific data, only class-specific. It's kinda like parametric polymorphism in C++, except with static variables rather than template variables.
All you need for a Delete is a tableName and a PKName, right? And that isn't instance specific, it's class-specific. So I don't see why C# won't let me create a base class static function Delete() which uses a different value for a static variable depending on what the instantiating class is.
When you say "you want to use a single value to store 3 different values. That is just impossible" I disagree. If you think about it, it's no different than using one method signature to refer to 3 different methods depending on the invoking object's class. The difference is that it's a string rather than a function pointer, and that the polymorphism can be resolved at compile-time, not run-time (I think...).
Hmm, I think this could all be academic anyway, if C# can't do it then it can't do it. It just seems ugly to me to create a non-static variable that doesn't use any instance-specific data.
|
|
|
|
|
moredip wrote:
I don't think I am using instance-specific data, only class-specific.
Inheritance is just not an option then...
What you want to design is numerous singleton classes each doing it own thing, BUT you want all the benefits of inheritance (which we have said will not work).
moredip wrote:
All you need for a Delete is a tableName and a PKName, right? And that isn't instance specific, it's class-specific.
Place that function in a util class as a static method then passing the tablename and pk value.
moredip wrote:
So I don't see why C# won't let me create a base class static function Delete() which uses a different value for a static variable depending on what the instantiating class is.
Youre contradicting yourself here. placing static and instance in the same sentence is unsafe . Just think about it, if you have a static function say Class.Delete() , what is it suppose to delete??? I assume these classes are mapped to a table or a record. What happens if you have 2 records open at the same time, which one is meant to get deleted?
moredip wrote:
When you say "you want to use a single value to store 3 different values. That is just impossible" I disagree. If you think about it, it's no different than using one method signature to refer to 3 different methods depending on the invoking object's class. The difference is that it's a string rather than a function pointer, and that the polymorphism can be resolved at compile-time, not run-time (I think...).
OK I should have rather said, pointing all to one address then. Strings are infact stored as pointers.
moredip wrote:
Hmm, I think this could all be academic anyway, if C# can't do it then it can't do it. It just seems ugly to me to create a non-static variable that doesn't use any instance-specific data.
Then you will have to boot an OO approach and follow the C approach using C style parameterized functions. Which will probably much easier doin git in C/C++. Did you look at my code though (i didnt mean copy)? I run into similar issues, hence using an instance design. No I have no problem if you create classes for a Table as well , but that would be unnecesary using an instance approach. These table classes would have a static Delete fucntion, but would need at least need one parameter but you would lose inheritance thus losing the abilty to cast and use base classes's methods. And interfaces.
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
I don't think I'm explaining myself very well here
I see what you're saying about having util classes with static methods, rather than inheritance, but I like the idea of having both in the same class. It means only specifying things like tableName and PKName once (rather than once in the instance-base class and once in the util class). And as these are stored in the class, one can use polymorphism to delete a row from a table (for example) without having to know what kind of table it is.
Unfortunately, it seems that we're both agreed that this just isn't possible in C#. So i've make the relevant variable readonly properties that always return the same value, e.g.:
class DBData
{
virtual protected string tableName{ get{ return ""; } };
....
....
}
class AuthorData : DBData
{
override protected string tableName{ get{ return "Author"; } }
....
....
}
Now I can write functions like Delete( uint rowID ) in the base class, and via polymorphism they DELETE from different tables depending on what the type the instantiating class is.
This seems less clean to me than using static functions, but it does the job.
RE: placing static and instance in the same sentence, you're quite right. I was using the wrong terminology there. What I meant when i referred to the instantiating class was the class used to call the static method: e.g. with ChildA.SomeMethod() ChildA would be the instantiating class, even though the method is only declared in the base class. Do you see what I mean that with static inheritance polymorphism (which I think could just be a fancy way of saying genericity), the method would behave differently depending on what class was used to call it. E.g. ChildA.SomeStaticMethod() would have different results to ChildB.SomeStaticMethod(), even if neither redefined the method, but simply redefined so static variables.
Oh, and you're right about the static Delete function not making sense. I meant to say that it would be Delete( uint rowID ), where you specify the row you want to delete as a parameter. It seems a bit silly to me to instantiate an entire object just so you can set its rowID and then delete it
I hope I've cleared that up a bit. Sorry, I'm terrible at expressing my ideas on 'paper'!
I'm still working on a solution to this using readonly properties - and I might have to dirty my hands a little with Reflection (not sure yet). If you'd like I can send you my code so you can get some idea what I'm working towards.
|
|
|
|
|
moredip wrote:
Now I can write functions like Delete( uint rowID ) in the base class, and via polymorphism they DELETE from different tables depending on what the type the instantiating class is.
This seems less clean to me than using static functions, but it does the job.
Please look how I did it in my code. I just a nice inherited Delete() function without any parameters. Look at the base class in the Interfaces.cs file (ok the filename is a bit dumb).
To do what you wanna do, will force you to rewrite the each fucntion (i have gone over this).
Best is to think about your whole design again. What you will designing if you succeed, will be some classes that cannot be reused in any way, destroying the concept of OOP. I ussually have to redesign a class structure 4/5 times to make it work in its most effecient way. So just go and sleep on the thoughts for the next few days.
You can mail me your code, I could have a look at the design, maybe some mistunderstandings will be cleared up.
moredip wrote:
I hope I've cleared that up a bit. Sorry, I'm terrible at expressing my ideas on 'paper'!
Same here
moredip wrote:
I'm still working on a solution to this using readonly properties - and I might have to dirty my hands a little with Reflection (not sure yet). If you'd like I can send you my code so you can get some idea what I'm working towards.
Now I really dont want to know what you are trying todo with readonly properties.
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
Hi all
I have bound a textbox to a field in a table. The problem is however that databinding does not occur until either control gets destroyed or it text is changed by moving to the next element. Now when I want to save the dataset to xml, I have to move to another element, before the changes are reflected.
How can I manually force databinding on a textbox?
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
OK found answer, before the page even reloaded
control.DataBindings[0].BindingManagerBase.EndCurrentEdit();
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
I have one treeview and one toolbar in my form.The toolbar has TOP DOCKING and I want TreeView has Left Docking.When I set the its docking it takes all of the left side of the form,and the form set the TOP DOCKING of toolbar at the second,so it does not take all of the top of the form and it start after hte TreeView,how can I change this,so Toolbar takes all space at the TOP,and TreeView start below it with Left DOCKING?
Mazy
"And the carpet needs a haircut, and the spotlight looks like a prison break
And the telephone's out of cigarettes, and the balcony is on the make
And the piano has been drinking, the piano has been drinking...not me...not me-Tom Waits
|
|
|
|
|
Make sure the toolbar is added to the forms control collection before adding the treeview.
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
Hehehe..
Well,I had to add TreeView BEFORE toolbar,but anyway now its right.
Mazy
"And the carpet needs a haircut, and the spotlight looks like a prison break
And the telephone's out of cigarettes, and the balcony is on the make
And the piano has been drinking, the piano has been drinking...not me...not me-Tom Waits
|
|
|
|
|
Mazdak wrote:
I had to add TreeView BEFORE toolbar
Now that is so dumb (not you, but M$)
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
hehe , ms didnt do anything wrong..
r-click one of the controls and choose send to back or bring to front and see what happends
//Roger
|
|
|
|
|
ja ja It's my way or the highway
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
Its not the correct way.With this will it will come to front,but it will cover another control.It is not the solution for my problem.
Mazy
"And the carpet needs a haircut, and the spotlight looks like a prison break
And the telephone's out of cigarettes, and the balcony is on the make
And the piano has been drinking, the piano has been drinking...not me...not me-Tom Waits
|
|
|
|
|
i am finding something like CWinThread in C# to Create multi UI Thread.Can anybody help me?Thanks!!! sdfasdfasdf
|
|
|
|
|
Would you please delete your extrs messages?
Mazy
"And the carpet needs a haircut, and the spotlight looks like a prison break
And the telephone's out of cigarettes, and the balcony is on the make
And the piano has been drinking, the piano has been drinking...not me...not me-Tom Waits
|
|
|
|
|