473,416 Members | 1,714 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,416 software developers and data experts.

Override static derived variable


Hello.

I have a problem with C# language. I want to define an algorithm on a
static function inside an abstract class. This function calls a static
variable inside the same class. Then I want to define some derived
classes wich inherit the function and override the variable, but it
doesn't work.

Testcase:

using System;

namespace Test
{

abstract public class X {
protected static string var = "x";

public static void print_my_var(){
Console.WriteLine("my var is " + var);
}
}

public class A : X {
protected static new string var = "a";
}

public class B : X
{
protected static new string var = "b";
}

class ClassTest {

[STAThread]
static void Main(string[] args)
{
X.print_my_var();
A.print_my_var();
B.print_my_var();
}
}
}
result:
my var is x
my var is x
my var is x

expected results:
my var is x
my var is a
my var is b

How can obtain the expected results using static methods and static
variables and without creating the static method A or B?

Thanks in advance.

Andrew

--
Nov 17 '05 #1
14 7057
"knocte" <kn****@NO-SPAM-PLEASE-gmail.com> a écrit dans le message de news:
d9**********@nsnmrro2-gest.nuria.telefonica-data.net...
I have a problem with C# language. I want to define an algorithm on a
static function inside an abstract class. This function calls a static
variable inside the same class. Then I want to define some derived
classes wich inherit the function and override the variable, but it
doesn't work.


I would have said that you should not override the variable, just the
initialising code in a static constructor.

abstract public class X
{
protected static string var;

protected static SetVar(string value)
{
var = value;
}

static X()
{
SetVar("X");
}

public static void print_my_var()
{
Console.WriteLine("my var is " + var);
}
}

public class A : X
{
static A()
{
SetVar("A");
}

But this doesn't work either as it appears that the only static constructor
to be called in class A is X().

I must admit that this is not as I would have expected. Does anyone know if
this is a bug in beta 1 ?

Joanna

--
Joanna Carter
Consultant Software Engineer
Nov 17 '05 #2
knocte <kn****@NO-SPAM-PLEASE-gmail.com> wrote in news:d93v33$skl$1@nsnmrro2-
gest.nuria.telefonica-data.net:
I have a problem with C# language. I want to define an algorithm on a
static function inside an abstract class. This function calls a static
variable inside the same class. Then I want to define some derived
classes wich inherit the function and override the variable, but it
doesn't work.


You cannnot override statics in C#, or in fact in .NET. In Delphi.NET you can, but they are done using
some magic to preserve compatibilty and dont export as normal statics for other languages.
--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Get your ASP.NET in gear with IntraWeb!
http://www.atozed.com/IntraWeb/
Nov 17 '05 #3
"Joanna Carter \(TeamB\)" <jo*****@nospamforme.com> wrote in
news:uF**************@TK2MSFTNGP10.phx.gbl:
But this doesn't work either as it appears that the only static
constructor to be called in class A is X().

I must admit that this is not as I would have expected. Does anyone
know if this is a bug in beta 1 ?


What code are you using to instantiate them? Statics in .NET are not at all like in Delphi, and Im
constantly hitting roadblocks here. I understand why they did it the way they did, and it has some
advantages but its requires some royal work arounds sometimes.
--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Make your ASP.NET applications run faster
http://www.atozed.com/IntraWeb/
Nov 17 '05 #4
"Chad Z. Hower aka Kudzu" <cp**@hower.org> a écrit dans le message de news:
Xn**************************@127.0.0.1...
What code are you using to instantiate them? Statics in .NET are not at all like in Delphi, and Im constantly hitting roadblocks here. I understand why they did it the way they did, and it has some advantages but its requires some royal work arounds

sometimes.

Hi Chad

I am not instantiating them for this example, I am just using static calls
as demonstrated by the OP.

Console.WriteLine(Thing.GetVar());
Console.WriteLine(Derived.GetVar());

Both return "Thing", the Derived static constructor doesn't get called at
all if there is a static constructor on the base class. This seems wierd; I
wasn't expecting virtual/override behaviour, just that the static
constructor on Derived would possibly hide that of Thing, but definitely
that it would get executed.

Can an MVP or someone from MS please confirm that this behaviour is
intentional ?

Joanna (Another frustrated Delphi OO expert)

--
Joanna Carter
Consultant Software Engineer
Nov 17 '05 #5
Joanna Carter (TeamB) <jo*****@nospamforme.com> wrote:
I am not instantiating them for this example, I am just using static calls
as demonstrated by the OP.

Console.WriteLine(Thing.GetVar());
Console.WriteLine(Derived.GetVar());


Those both compile to the same thing - there will be nothing which
actually references Derived.GetVar in the IL, as there is really no
such method. Therefore there is (as far as the CLR is concerned) no
need to initialise the Derived class.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #6
Jon Skeet [C# MVP] <sk***@pobox.com> wrote in
news:MP************************@msnews.microsoft.c om:
Those both compile to the same thing - there will be nothing which
actually references Derived.GetVar in the IL, as there is really no
such method. Therefore there is (as far as the CLR is concerned) no
need to initialise the Derived class.


Joanna,

I'll add a bit to Jon's reply since I know you have a Delphi background.

..NET does NOT load a class until it is ACTUALLY used. So the static constructor for a given class
will not be called, until the class is actually needed. All classes are load on demand, vs
Delphi where the units get their initialization sections called on start up of the application.
--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Develop ASP.NET applications easier and in less time:
http://www.atozed.com/IntraWeb/
Nov 17 '05 #7
"Chad Z. Hower aka Kudzu" <cp**@hower.org> a écrit dans le message de news:
Xn**************************@127.0.0.1...
I'll add a bit to Jon's reply since I know you have a Delphi background.

.NET does NOT load a class until it is ACTUALLY used. So the static constructor for a given class will not be called, until the class is actually needed. All classes are load on demand, vs Delphi where the units get their initialization sections called on start up of the application.


Unfortunately, I now understand that bit :-(

But the good news is that I have solved the OP's problem. All you have to do
is to re-declare the GetVar() static method and call the base method !!

class Thing
{
private static string var;

protected static void SetVar(string value)
{
var = value;
}

static Thing()
{
SetVar("Thing");
}

public static string GetVar()
{
return var;
}
}

class Derived : Thing
{
static Derived()
{
SetVar("Derived");
}

public static new string GetVar()
{
return Thing.GetVar();
}
}

Yeeesss !!!

Joanna

--
Joanna Carter (TeamB)

Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
Nov 17 '05 #8
Chad Z. Hower aka Kudzu <cp**@hower.org> wrote:
I'll add a bit to Jon's reply since I know you have a Delphi background.

.NET does NOT load a class until it is ACTUALLY used. So the static
constructor for a given class will not be called, until the class is
actually needed. All classes are load on demand, vs Delphi where the
units get their initialization sections called on start up of the
application.


There's a slight twist here due to the beforefieldinit flag, which is
present on all classes compiled by the C# compiler which don't have a
static constructor. Those classes are "lazily" initialized, which means
they're initialized at some point before the first static field access
- it actually usually means they're eagerly initialized at the start of
the first method which *might* use the type.

See http://www.pobox.com/~skeet/csharp/beforefieldinit.html

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #9
Jon Skeet [C# MVP] <sk***@pobox.com> wrote in news:MPG.1d1fc5ebac0821ce98c354
@msnews.microsoft.com:
.NET does NOT load a class until it is ACTUALLY used. So the static


There's a slight twist here due to the beforefieldinit flag, which is


I should have used "needed" insetad of "used". :)
--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Empower ASP.NET with IntraWeb
http://www.atozed.com/IntraWeb/
Nov 17 '05 #10

"Chad Z. Hower aka Kudzu" <cp**@hower.org> wrote in message
news:Xn**************************@127.0.0.1...
Jon Skeet [C# MVP] <sk***@pobox.com> wrote in
news:MP************************@msnews.microsoft.c om:
Those both compile to the same thing - there will be nothing which
actually references Derived.GetVar in the IL, as there is really no
such method. Therefore there is (as far as the CLR is concerned) no
need to initialise the Derived class.


Joanna,

I'll add a bit to Jon's reply since I know you have a Delphi background.

.NET does NOT load a class until it is ACTUALLY used. So the static
constructor for a given class
will not be called, until the class is actually needed. All classes are
load on demand, vs
Delphi where the units get their initialization sections called on start
up of the application.
--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Develop ASP.NET applications easier and in less time:
http://www.atozed.com/IntraWeb/


I'll add a bit as well as I have followed both Delphi and C# from scratch
and have some issues.
I think the Pascal way of doing things with having units as a concrete
subject in the system a neat thing.
This is why Delphi can sport static variables while the concept is not
present in the pascal language per se.

The Delphi way of having a type of object is extremely useful. Having a
concept of self (this) for a class (static) function is great. This
construct also gives room for classhelpers, why I love Delphi.NET when
building general- or util-classes.

The C# view that a class cannot be aware of self and not participate in
polymorphism is a contrieved construct. Delphi proves C# wrong. This is one
of the most irritating things about C#. Not to mention how C# handles
indexers. Yet again Delphi proves how things should, could and does work.

My bet is that C# 3.0 will sport both class types and class helpers. And
VB-style indexers, even though it's a Delphi-thing.

Joanna: You just can't code Delphi in C#. But you could always build some of
your classes in Delphi.NET

- Michael S


Nov 17 '05 #11
"Michael S" <a@b.c> wrote in news:#f*************@TK2MSFTNGP12.phx.gbl:
I think the Pascal way of doing things with having units as a concrete
subject in the system a neat thing.
At first this seemed better, but really the .NET way is better here. You can better split your
classes up into files without altering their visibility in namespaces.
This is why Delphi can sport static variables while the concept is not
present in the pascal language per se.
In your context what do you mean by static variables? Are you referring to globals?
The Delphi way of having a type of object is extremely useful. Having
This is one area that Delphi did better IMO. .NET took it much farther and overall there is more
there, but the basic idea of a Type is a lot easier to work with and more useful in Delphi.
a concept of self (this) for a class (static) function is great. This
construct also gives room for classhelpers, why I love Delphi.NET when
building general- or util-classes.
Yes, I sorely miss this functionality. However the reason .NET does not implement it is becuase
of how it treats types in the first place and the fact that there is not VMT in a type at all.

Delphi.NET works because they make some magic and some hidden .NET classes in the
background.
The C# view that a class cannot be aware of self and not participate
in polymorphism is a contrieved construct. Delphi proves C# wrong.
A constant sore spot that causes me grief.
This is one of the most irritating things about C#. Not to mention how
C# handles indexers. Yet again Delphi proves how things should, could
and does work.
What differences do you see here? I've not had issues with indexers in C# vs Delphi.
My bet is that C# 3.0 will sport both class types and class helpers.
When you say class helpers - you arent referring to the class helper feature added to
Delphi.NET are you? Thats highly domain specific and was only added to allow compatibility
with older Delphi code yet let newer code use FCL objects instead of VCL bases.
Joanna: You just can't code Delphi in C#. But you could always build
some of your classes in Delphi.NET


Except that a lot of the Delphi magic including the type functinoality does not export, or exports
with wierd interfaces and is for all intents and purposes not useable by non Delphi.NET
languages.
--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Develop ASP.NET applications easier and in less time:
http://www.atozed.com/IntraWeb/
Nov 17 '05 #12

"Chad Z. Hower aka Kudzu" <cp**@hower.org> wrote in message
news:Xn**************************@127.0.0.1...
"Michael S" <a@b.c> wrote in news:#f*************@TK2MSFTNGP12.phx.gbl:
I think the Pascal way of doing things with having units as a concrete
subject in the system a neat thing.
At first this seemed better, but really the .NET way is better here. You
can better split your
classes up into files without altering their visibility in namespaces.


There is no such thing as a namespace when it comes to CIL. That's syntactic
sugar allowing classnames to contain dots.

This is why Delphi can sport static variables while the concept is not
present in the pascal language per se.


In your context what do you mean by static variables? Are you referring to
globals?


I mean variables that are defined in the implementation section. Unit-scope.
The Delphi way of having a type of object is extremely useful. Having


This is one area that Delphi did better IMO. .NET took it much farther and
overall there is more
there, but the basic idea of a Type is a lot easier to work with and more
useful in Delphi.
a concept of self (this) for a class (static) function is great. This
construct also gives room for classhelpers, why I love Delphi.NET when
building general- or util-classes.


Yes, I sorely miss this functionality. However the reason .NET does not
implement it is becuase
of how it treats types in the first place and the fact that there is not
VMT in a type at all.


No. That's not the reason.
Delphi.NET works because they make some magic and some hidden .NET classes
in the
background.
No. There is no magic. If it compiles to CIL it's ok.
The C# view that a class cannot be aware of self and not participate
in polymorphism is a contrieved construct. Delphi proves C# wrong.
A constant sore spot that causes me grief.
This is one of the most irritating things about C#. Not to mention how
C# handles indexers. Yet again Delphi proves how things should, could
and does work.


What differences do you see here? I've not had issues with indexers in C#
vs Delphi.


No? By having to build nested classes if you want more than one indexer.
Elegant, yes. Useful, no. Hate it? Yes.
My bet is that C# 3.0 will sport both class types and class helpers.
When you say class helpers - you arent referring to the class helper
feature added to
Delphi.NET are you? Thats highly domain specific and was only added to
allow compatibility
with older Delphi code yet let newer code use FCL objects instead of VCL
bases.


Yes and no. Borland created classhelpers mostly for handling the
TObject.Free method. But it is a mighty thing they have created. Very
useful. Borland have created another dimension of OO. With Delphi.NET you
don't see util classes or functions. You can just expand a class. This is a
valueable feature of the pascal language not present in C#. I miss it.
Joanna: You just can't code Delphi in C#. But you could always build
some of your classes in Delphi.NET


Except that a lot of the Delphi magic including the type functinoality
does not export, or exports
with wierd interfaces and is for all intents and purposes not useable by
non Delphi.NET
languages.


So, we just do what we always do. Wrap great code in a lame proxy. For all
classes that needs to be public we need to be CLS-compliant. Nothing new
here.
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"


- Michael S
Nov 17 '05 #13
"Michael S" <a@b.c> wrote in news:ef**************@TK2MSFTNGP15.phx.gbl:
At first this seemed better, but really the .NET way is better here.
You can better split your
classes up into files without altering their visibility in
namespaces.
There is no such thing as a namespace when it comes to CIL. That's
syntactic sugar allowing classnames to contain dots.


Not at the IL level, but at the code level which is what he was referring to. Its going to be
difficult not to mix terms because he's coming from Delphi and some words in Delphi are the
same but have different meaning. This makes some things very hard to "cross" discuss and very
difficult for non Delphites to catch.

When I talked about visibilty in namespaces, I was speaking of compile time. In C# you can move
a class to another unit without affecting any code. In Delphi you can if you have not fully
qualified it. Usually in Delphi you do not fully qualify, but when conflicts come up of
names its necessary. Delphi.NET improves this, but also keeps with backward compatibility.
I mean variables that are defined in the implementation section.
Unit-scope.
These are global variables. They are not statics per say. In Delphi.NET they are implemented by
"magic", Delphi exports a unit class per unit and makes them statics in that unit.
Yes, I sorely miss this functionality. However the reason .NET does
not implement it is becuase
of how it treats types in the first place and the fact that there is
not VMT in a type at all.


No. That's not the reason.


Yes it is - .NET classes are implemented very differently than Delphi classes were.
Delphi.NET works because they make some magic and some hidden .NET
classes in the
background.


No. There is no magic. If it compiles to CIL it's ok.


As far as the other languages are concerned it is magic. Delphi takes and emits "foreign" objects
and performs "compiler magic" translations when resused with the Delphi language, class
helpers, virtual statics, globals, and more.
No? By having to build nested classes if you want more than one
indexer. Elegant, yes. Useful, no. Hate it? Yes.
You can have more than one indexer. You can declare:

this[string aValue]
and
this[int aValue]

in the same object.
Yes and no. Borland created classhelpers mostly for handling the
TObject.Free method. But it is a mighty thing they have created. Very
No way - no offense but you do not have an in depth understanding of what exactly the class
helpers and other parts of the Delphi.NET compiler does.

Class helpers are used to map TObject to System.Object, Component, and several others, YET
still add all the extra stuff that VCL had at that level. Its used for WAY more than just Free.
Its used to add Owner and dozens if not hundreds of other items.
useful. Borland have created another dimension of OO. With Delphi.NET
you don't see util classes or functions. You can just expand a class.
This is a valueable feature of the pascal language not present in C#.
I miss it.


Class helpers (even ask Danny) are a bit of a hack and ONLY usable from within Delphi. Load
Borland.VCL in C# and you wont see any of the items added by class helper to TComponent. Its
only visible when used in Delphi becuase Delphi implements a LOT of "magic" by interpreting
..NET structures it emits and handling them at the compiler level. These certainly are IL "legal"
but they are NOT recognized by ANY other CLS / CTS implementation.

Its a good solution for allowing Delphi to remain backward compatible - but it should NOT be
used moving forward in your own .NET code as you will not be able to export your libaries and be
usable by other .NET languages.

We have some of the largest and most compmlicated .NET assemblies in existence written in
Delphi.NET, in fact bigger than the VCL. Which ones? Well namely Indy and IntraWeb, both of
which ship as part of Delphi, so we've been through it all.


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Get your ASP.NET in gear with IntraWeb!
http://www.atozed.com/IntraWeb/
Nov 17 '05 #14
Joanna Carter (TeamB) escribió:
"Chad Z. Hower aka Kudzu" <cp**@hower.org> a écrit dans le message de news:
Xn**************************@127.0.0.1...
I'll add a bit to Jon's reply since I know you have a Delphi background.

.NET does NOT load a class until it is ACTUALLY used. So the static

constructor for
a given class will not be called, until the class is actually needed. All

classes are load
on demand, vs Delphi where the units get their initialization sections

called on start up
of the application.


Unfortunately, I now understand that bit :-(

But the good news is that I have solved the OP's problem. All you have to do
is to re-declare the GetVar() static method and call the base method !!

class Thing
{
private static string var;

protected static void SetVar(string value)
{
var = value;
}

static Thing()
{
SetVar("Thing");
}

public static string GetVar()
{
return var;
}
}

class Derived : Thing
{
static Derived()
{
SetVar("Derived");
}

public static new string GetVar()
{
return Thing.GetVar();
}
}

Yeeesss !!!

Joanna

--
Joanna Carter (TeamB)

Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker

Hello Joanna, thanks for your interest. Although the first concept I
wanted to make, is not allowed (as Kudzu says), I think this could be a
nice workaround (but I haven't tested it yet).

The problem is that, if I do it this way, I have to override the method
GetVar in every derived class. And this is one of the things I wanted to
avoid, so as to improve reusability.

Thanks very much.

Andrew

--
Nov 17 '05 #15

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

Similar topics

8
by: JPRoot | last post by:
Hi M. Jeffrey Tan, Just hopping you didn't forget me? :) Thanks JPRoot ----- \"Jeffrey Tan\" wrote: -----
5
by: Mark Broadbent | last post by:
Oh yes its that chestnut again! Ive gone over the following (http://www.yoda.arachsys.com/csharp/faq/ -thanks Jon!) again regarding this subject and performed a few of my own tests. I have two...
11
by: z_learning_tester | last post by:
Hello, yes another beginner question that I'm sure is obvious to many here :-) My book is so bad. Really. It uses the exact same example of code for using the new kw and for using virtual(in the...
2
by: Tony Maresca | last post by:
Don't know if there are any Delphi/Object Pascal converts here, but being one, I sorely miss the feature that permits class (e.g., static) methods to be virtual and be overridden in derived...
5
by: Marcel Hug | last post by:
Hi NG ! I'm new in C# and I'm reading a book about the fundamentals and concepts. In the chapter Methods it's written to use virtual, if i would like to override the method in a subclass. This...
14
by: Dave Booker | last post by:
It looks like the language is trying to prevent me from doing this sort of thing. Nevertheless, the following compiles, and I'd like to know why it doesn't work the way it should: public class...
5
by: none | last post by:
I'd like to create a new static property in a class "hiding" the property present in a base class. Since this needs to happen at runtime I tried doing this via DynamicMethod. But obviously the...
1
by: Sandro Bosio | last post by:
Hello everybody, my first message on this forum. I tried to solve my issue by reading other similar posts, but I didn't succeed. And forgive me if this mail is so long. I'm trying to achieve the...
5
by: sedrel | last post by:
Hello All, I'm new to C++ (been an Ada guy for over 20 years), and I've search but can't find an answer to my question on the Web (big place!), so I'm hoping you Gurus come help me. I know that...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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
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,...
0
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...

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.