Different static member values on derived classes [duplicate] - c#

This question already has answers here:
What is the best way to define a static property which is defined once per sub-class?
(3 answers)
Having separate copy of base class static member in each derived class
(3 answers)
Closed 9 years ago.
When I write:
public class A
{
public static int v;
}
public class B : A { }
public class C : A { }
Values of A.v, B.v and C.v are all same.
How can I make them to store different static values?

Values of A.v, B.v and C.v are all same.
How can I make them to store different static values?
You can't; A.v, B.v and C.v all refer to the same static field, so they can't have different values.
A possible workaround would be to redeclare v in B and C:
public class A
{
public static int v;
}
public class B : A
{
public static new int v;
}
public class C : A
{
public static new int v;
}
If you do that, A.v, B.v and C.v will effectively refer to different fields, so they can have different values.
(Note the new modifier; it tells the compiler that you're intentionally hiding the member from the base class)
Depending on your exact needs, faester's solution might be better.

Dont make them static but use a virtual readonly property to obtain the same effect:
public class A
{
public virtual int v { get { return 1; } }
}
public class B : A { }
public class C : A
{
public override int v
{
get { return 2; }
}
}

Related

Static member accessability through generic inheritance

I was recently coming up with some rather funky singleton work and discovered that I can access a protected static member from any unique inherited type using the same base of inheritance where generics are used. An example of what I'm talking about is as follows:
public abstract class Class<T>
{
protected static int number = 5;
public void Print()
{
Console.WriteLine(number);
}
}
public class ClassA : Class<ClassA>
{
}
public class ClassB : Class<ClassB>
{
public ClassB()
{
number = 1;
}
}
public class ClassC : Class<ClassC>
{
public ClassC()
{
number = ClassA.number;//I don't want to be able to see "number"
}
}
Since generics are in use here, each unique inheriting type gets its own "number" (which is what I want). But I don't like that I can access "number" from other types inheriting the same base type when generics are used. Is there a way to fix this? And also why does this happen (I understand why it happens with inheritance without generics, but it doesn't seem right that it happens with generics)?
I don't like that I can access "number" from other classes inheriting the same base class when generics are used. Is there a way to fix this?
The only true fix is to declare separate private static variables for each class. This will keep you from being able see the number variable in one class type from any other class type.
public abstract class Class<T>
{
private static int number = 5;
public void Print()
{
Console.WriteLine(number);
}
}
public class ClassA : Class<ClassA>
{
}
public class ClassB : Class<ClassB>
{
private static int number;
public ClassB()
{
number = 1;
}
}
public class ClassC : Class<ClassC>
{
private static int number;
public ClassC()
{
number = 123; // Cannot see ClassA.number because it is private to `Class<T>`
}
}
The side effect is being caused by declaring the variable protected static and using it with inheritance. It is unclear why you would attempt to do that when the behavior you are after is that of a private static field.
You can use the private modifier to make the static member invisible to descendents. Use protected only if you want the descendants to be able to access it. It makes no difference generic vs. non.
public abstract class Class<T>
{
private static int number = 5; //Private now
public void Print()
{
Console.WriteLine(number); //Works
}
}
public class ClassA : Class<ClassA>
{
//No number
}
public class ClassB : Class<ClassB>
{
public ClassB()
{
number = 1; //Will not compile
}
}
public class ClassC : Class<ClassC>
{
public ClassC()
{
number = ClassA.number;//Will not compile
}
}
If you want the static variable to be accessible only to some descendants and not others, define the variable in the first class in the inheritance chain that needs access:
public abstract class Class<T>
{
}
public class ClassA : Class<ClassA>
{
static private int number = 7;
}
public class ClassB : Class<ClassB>
{
static private int number = 7;
public ClassB()
{
ClassA.number = 5; //Does not compile
ClassB.number = 6;
}
}
public class ClassC : Class<ClassC>
{
static private int number = 7;
public ClassC()
{
Console.WriteLine(ClassA.number); //Does not compile
Console.WriteLine(ClassB.number); //Does not compile
Console.WriteLine(ClassC.number); //Compiles
}
}
You cannot define something in an ancestor class and remove it from a descendant.

Dynamically create instance of a class which is derived from an abstract class [duplicate]

This question already has answers here:
How to create instance of inherited in static base method?
(3 answers)
Closed 6 years ago.
I have 2 classes which are derived from an abstract class
abstract class Order
{
public virtual boolean Export()
{
...
}
}
class TradeOrder : Order
{
public override bool Export()
{
//Create a new order
}
}
class LibraryOrder : Order
{
public override bool Export()
{
//Dont create order but Update an existing order
}
}
TradeOrder is created for customertype "Trade" and LibraryOrder is created for customertype "Library".
The customer type will grow in near future.
How do I create instance of the derived class based on the customer type without using if...else or swicth ...case?
The instance of the class will call the export method to either create or update a sales order.
-Alan-
Here is one way to achieve what you want. We can call it "convention over configuration approach" since, obviously, your derived order type names and your enum names have to match.
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var customerType = CustomerType.Library;
var order = (Order)Activator.CreateInstance("ConsoleApplication2", "ConsoleApplication2." + customerType.ToString() + "Order").Unwrap();
}
}
public enum CustomerType
{
Trade,
Library
}
public abstract class Order
{
public virtual void Export() { }
}
public class TradeOrder : Order
{
public override void Export() { }
}
public class LibraryOrder : Order
{
public override void Export() { }
}
}
I suggest have a map of object type name and Type and create instance based on the mapping. The mapping details can be initialized in the code or from external source (Ex. Config file).
enum OrderType
{
TradeOrder,
LibraryOrder
}
Dictionary<OrderType, Type> _orderTypeMap = new Dictionary<OrderType, Type>
{
{ OrderType.LibraryOrder, typeof(LibraryOrder)},
{ OrderType.TradeOrder, typeof(TradeOrder)}
};
Order GetOrderInstance(OrderType orderType)
{
return Activator.CreateInstance(_orderTypeMap[orderType]) as Order;
}

Interface With Class Enums [duplicate]

This question already has answers here:
Enum "Inheritance"
(17 answers)
Closed 7 years ago.
Is there a way to interface with or inherit the enum of another class? Obviously I can move the enum outside of the class, but I am curious if a reference can be made:
public class deferment
{
public enum test
{
test = 0,
live
}
}
public class defermentLog
{
public enum test1 : deferment:test //this is where I want to reference
{
}
public test1 action()
{
return test1.live;
}
}
In that case, yes, you can.
namespace ConsoleTests
{
using TestAlias = Class1.test;
public class Class1
{
public enum test
{
test,
live
}
}
public class Class2
{
public void x()
{
TestAlias t = TestAlias.live;
}
}
}
Its called a type alias, and its defined like this: using TestAlias= Class1.test;
It should be noted though that you have to define that alias in the file that you use it and it does not copy over to other files, so you have to define it in every one you use it.

Is there something known as Private Class [duplicate]

This question already has answers here:
method without access modifier
(8 answers)
Default Class Accessibility in C#
(4 answers)
Closed 8 years ago.
If we do not specify Public/Private/Protected, what will it be?
Is there something known as a private class?
1: that depends on whether the class is nested or not. A top level class defaults to internal. A nested class defaults to private.
class TopLevelClass {
class PrivateClass {
}
}
2: yes, but only for nested classes:
class TopLevelClass {
private class ExplicitlyPrivateClass {
}
class ImplicitlyPrivateClass {
}
}
If you don't specify Public/Private/Protected for a main class it will be internal, for a nested class the default access specifier will be private.
private class exists. You can access a private class only if it is declared inside another class. Means it is private to the parent class as
class example //which is default interal
{
private class ex
{
}
class ex1 //default private
{
}
}
1) If no modifier is specified, the visibility will depend on the situation where it is omitted; the topic is discussed in this question.
2) In the following code, InnerClass is private in OuterClass.
namespace ClassTest
{
class OuterClass
{
private class InnerClass
{
}
OuterClass()
{
InnerClass Test = new InnerClass();
}
}
class Program
{
static void Main(string[] args)
{
OuterClass TestOne = new OuterClass();
InnerClass TestTwo = new InnerClass(); // does not compile
}
}
}
What are the Default Access Modifiers in C#?
and there is a private class but in my opinion its pointless

How to inherit a static property with a unique value for each subclass?

I have a series of objects, lets call them buildings, that each share certain properties that are static for that building, but different for each building, such as price. I assumed that the best way to implement this was to create an abstract superclass with the shared price attribute and set the values in each subclass, but I cannot figure out how to get this to work. Here is an example of something I have tried:
using System;
public abstract class Buildings
{
internal static int price;
internal static int turnsToMake;
}
using System;
public class Walls : Buildings
{
public Walls()
{
price = 200;
turnsToMake = 5;
}
}
This works fine for construction, but if I want to check the price before creating it (to check if the player has enough money) then it just returns a null value. I'm sure that it is is a super simple fix, but I can't figure it out. Any help?
There is a "patchy" yet simple solution that's worth to consider. If you define your base class as a Generic class, and in deriving classes set T as the class itself, It will work.
This happens because .NET statically defines a new type for each new definition.
For example:
class Base<T>
{
public static int Counter { get; set; }
public Base()
{
}
}
class DerivedA : Base<DerivedA>
{
public DerivedA()
{
}
}
class DerivedB : Base<DerivedB>
{
public DerivedB()
{
}
}
class Program
{
static void Main(string[] args)
{
DerivedA.Counter = 4;
DerivedB.Counter = 7;
Console.WriteLine(DerivedA.Counter.ToString()); // Prints 4
Console.WriteLine(DerivedB.Counter.ToString()); // Prints 7
Console.ReadLine();
}
}
Don't use static. Static says that all instances of Building have the same value. A derived class will not inherit its own copy of the statics; but would always modify the base class statics. In your design there would only be one value for price and turnsToMake.
This should work for you:
public abstract class Buildings
{
internal int price;
internal int turnsToMake;
}
However, most people don't like using fields these days and prefer properties.
public abstract class Buildings
{
internal int Price { get; set; }
internal int TurnsToMake { get; set; }
}
I want to check the price before creating it […]
I suppose that's how you got to static fields; however, static and virtual behaviour cannot be combined. That is, you would have to re-declare your static fields for each subclass. Otherwise, all your subclasses share the exact same fields and overwrite each others' values.
Another solution would be to use the Lazy<T, TMetadata> type from the .NET (4 or higher) framework class library:
public class Cost
{
public int Price { get; set; }
public int TurnsToMake { get; set; }
}
var lazyBuildings = new Lazy<Buildings, Cost>(
valueFactory: () => new Walls(),
metadata: new Cost { Price = 200, TurnsToMake = 5 });
if (lazyBuildings.Metadata.Price < …)
{
var buildings = lazyBuildings.Value;
}
That is, the metadata (.Metadata) now resides outside of the actual types (Buildings, Walls) and can be used to decide whether you actually want to build an instance ( .Value) of it.
(Thanks to polymorphism, you can have a whole collection of such "lazy factories" and find a building type to instantiate based on the metadata of each factory.)
Building on Uri Abramson's answer above:
If you need to access the static property from within the Base class, use reflection to get the value from T. Also, you can enforce that Base must be inherited using T of the derived type.
e.g.
class Base<T> where T : Base <T> {
static int GetPropertyValueFromDerivedClass<PropertyType>(BindingFlags Flags = BindingFlags.Public | BindingFlags.Static, [CallerMemberName] string PropertyName = "")
{
return typeof(T).GetProperty(PropertyName, Flags)?.GetValue(null);
}
static int Counter{ get => GetPropertyValueFromDerivedClass(); }
}
static int DoubleCounter{ return Counter*2; } //returns 8 for DerivedA and 14 for DerivedB
}
If you have a better way to do this, please post.
Not as easy for the inheritor, but workable...
public abstract class BaseType
{
public abstract contentType Data { get; set; }
}
public class InheritedType : BaseType
{
protected static contentType _inheritedTypeContent;
public override contentType Data { get => _inheritedTypeContent; set => _inheritedTypeContent = value; }
}

Categories

Resources