Via en basklass kan man ju låta härledda klasser ärva metoder och fält. Om basklassen har ett statiskt fält så kommer alla härledda klasser också att ha det fältet. Du kan få till att varje klass har sitt eget statiska fält men jag tror inte du kan tvinga varje ärvd kalss att ha det. Sättet att få en ärv klass att ha sitt eget statiska fält är att använda nyckelordet "new". Tack för tipset. Med din kod som utgångspunkt har jag här ett exempel på något jag dock tycker är en smula underligt, fast kanske ändå inte. Det du vill göra går helt enkelt inte att göra, inte på det här sättet. (Jag kan inte komma på någonting som skulle kunna hjälpa dig i alla fall..) Hej, Vid användatet av shadowing "new" är det viktigt att förstå att det är den "deklarerade" typen som styr vilken implementation som faktiskt används, alltså inte den instansierade. När du nu också använder dig av statics och metoden ligger i förälderklassen så kommer metoden att accessa den variabel som ligger i den typen som metoden exekveras i, dvs. i ditt fall, föräldern.Arv och statiska variabler
Men jag har ett problem där jag vill att varje härledd klass skall ha ett eget statisk fält med namnet Period. De härledda klasserna skall alltså inte dela en och samma statiska variabel (arv från basklassen). Var och en skall ha sin egen. Och jag vill, i basklassen kunna säga att alla som ärver ifrån den, skall definiera en statisk variabel med namnet Period.
För icke statiska fält går sådant ju att fixa med abstrakta klasser och/eller interface, men med statiska fält tycks det vara helt omöjligt.
Är det möjligtvis någon som vet bättre?Sv: Arv och statiska variabler
<code>
class MyBase
{
public static int x = 25;
public static void Method()
{
Console.WriteLine("Base static method");
}
}
class MyClass : MyBase
{
public new static int x = 50;
public new static void Method()
{
Console.WriteLine("Derived static method");
}
}
class MyClient
{
public static void Main()
{
MyClass.Method(); // Displays 'Derived static method'
Console.WriteLine(MyClass.x);// Displays 50
}
}
</code>
taget från http://www.csharphelp.com/archives/archive148.htmlSv:Arv och statiska variabler
class MyBase
{
public static int MyStatic = 25;
public int GetMyStatic()
{
return MyStatic;
}
}
class MyClass1 : MyBase
{
public new static int MyStatic = 50;
}
class MyClass2 : MyBase //Bara för att visa att jag tänker mig många klasser
{ //härledda från MyBase, med unika värden på MyStatic
public new static int MyStatic = 43;
}
class MyClient
{
public static void Main()
{
Console.WriteLine( MyClass1.MyStatic ); // Displays 50
MyClass1 mc = new MyClass1();
Console.WriteLine( mc.GetMyStatic() ); // Displays 25!
Console.WriteLine( GetItsStatic<MyClass1>(mc) ); // Displays 25!
}
static int GetItsStatic<T>(T derivedFromMyBase) where T : MyBase
{
return derivedFromMyBase.GetMyStatic();
}
}
Men låt mig börja från början. För att slippa upprepa i princip samma kod (t ex metoden GetMyStatic()) i en mängd klasser vill jag definiera en basklass som jag sedan kan härleda mina klasser ifrån. Dessutom vill jag använda klasserna tillsammans med generiska metoder och även då är det bra att kunna tala om för kompilatorn att mina klasser är härledda från en gemensam basklass (where T : MyBase) så att den vet att T är av en typ som innefattar metoden MyStatic.
Men de härledda klasserna verkar inte kunna använda metoden GetMyStatic() (som de ärvt) till att hämta sin egen MyStatic vars värde är viktigt för att GetMyStatic() skall leverera rätt resultat.
Filosoferar jag fel här, eller blir jag faktiskt tvungen att skriva metoden GetMyStatic() en gång för varje klass? Det betyder ju att varje gång jag behöver ändra i denna metod, så är jag tvungen att ändra i varenda klass! Gillar jag inte alls.Sv: Arv och statiska variabler
Men.. Om du kan tänka dig en annan lösning så.. Om du i basklassen istället deklarerar ett dictionary enligt <System.Type, int>, och använder det för att slå upp, så borde det kunna fungera. Se upp för multitrådade saker bara; sålänge du kan garantera att skrivningar alltid är ensamma att operera på dictionaryt så är allt grönt, annars måste du implementera någon form av låsnings-historia.
I din Get-metod skickar du med T som nyckel till dictionaryt baraSv:Arv och statiska variabler
Är inte helt säker på vad du ska göra men....
Ett annat sätt är att använda System.Type och Reflections:
public class baseClass : Object
{
public static int StaticInt=0;
public static int GetInt (System.Type obType)
{
if (obType.IsSubclassOf(typeof(baseClass))){
return (int)obType.InvokeMember("StaticInt", BindingFlags.Default | BindingFlags.GetField,
null,null,new object[] {});
} else {
throw new Exception("obType is invalid!");
}
}
}
public class derivedClass1 : baseClass
{
public static new int StaticInt=1;
}
Sedan för att komma åt dit StaticInt som en statisk funktion från derivedClass1 kan du göra:
int test=derivedClass1.GetInt(typeof (derivedClass1));
Har inte kommit på något sätt att slippa parametern typeof(derivedClass1) men den vet du ju alltid eftersom den är samma som du anropar GetInt från.
int test=baseClass(typeof (derivedClass1));
Ger också StaticInt från derivedClass1.
Jobbar du med objekt har du ju this men då behöver man ju inte detta alls så det är ju bara intressant för statiska fält.
Det fungerar men är inte vacker och förmodligen också ganska "dyrt".
Det löser problemet med att få rätt StaticInt från metoder i bas klassen men det tvingar inte ärvda klasser att definiera StaticInt som för abstract eller interface.
Kanske inte precis vad du behöver men en ny synvinkel på saken.
/RubenSv: Arv och statiska variabler