In C# can a constant be overridden in a derived class? I have a group of classes that are all the same bar some constant values, so I'd like to create a base class that defines all the methods and then just set the relevant constants in the derived classes. Is this possible?
I'd rather not just pass in these values to each object's constructor as I would like the added type-safety of multiple classes (since it never makes sense for two objects with different constants to interact).
It's not a constant if you want to override it ;). Try a virtual read-only property (or protected setter).
Read-only property:
public class MyClass {
public virtual string MyConst { get { return "SOMETHING"; } }
}
...
public class MyDerived : MyClass {
public override string MyConst { get { return "SOMETHINGELSE"; } }
}
Protected setter:
public class MyClass {
public string MyConst { get; protected set; }
public MyClass() {
MyConst = "SOMETHING";
}
}
public class MyDerived : MyClass {
public MyDerived() {
MyConst = "SOMETHING ELSE";
}
}
Unfortunately constants cannot be overridden as they are not virtual members. Constant identifiers in your code are replaced with their literal values by the compiler at compile time.
I would suggest you try to use an abstract or virtual property for what you would like to do. Those are virtual and as such can (must, in the case of an abstract property) be overridden in the derived type.
Constants marked with const cannot be overridden as they are substituted by the compiler at compile time.
But regular static fields assigned to constant values can. I've had such a case just now:
class Columns
{
public static int MaxFactCell = 7;
}
class Columns2 : Columns
{
static Columns2()
{
MaxFactCell = 13;
}
}
If I just redefined the MaxFactCell field in the derived class instead, polymorphism wouldn't work: code using Columns2 as Columns would not see the overriding value.
If you need to restrict write (but not read) access to the field, using readonly would prohibit redefining it in Columns2. Make it a property instead, that's slightly more code:
class Columns
{
static Columns()
{
MaxFactCell = 7;
}
public static int MaxFactCell { get; protected set; }
}
class Columns2 : Columns
{
static Columns2()
{
MaxFactCell = 13;
}
}
Edit: This can have unexpected behaviour, see Shai Petel's remark below.
You can hide the inherited constant in a derived class by declaring the new constant new. I'm not sure this is a good practice, though.
class A
{
protected const int MyConst = 1;
}
class B : A
{
new private const int MyConst = 2;
}
to Work off dten + Tracker1's answer but updated for c# 6
public class MyClass {
public virtual string MyConst =>"SOMETHING";
}
...
public class MyDerived : MyClass {
public override string MyConst =>"SOMETHING ELSE";
}
You can force derived classes to have a value for a constant (well, a read-only property)
Make an interface containing a read-only property.
Put that interface on the base class.
Example:
public interface IHasConstant
{
string MyConst { get; }
}
Related
I have a class Foo, which is a base class for a lot other classes such as Bar and Baz, and I want to do some calculation within Foo using the static members in Bar and Baz, as shown below:
public class Foo{
public result1 {
get{
return field1;
}
}
}
public class Bar : Foo{
public const int field1 = 5;
}
public class Baz : Foo{
public const int field1 = 10;
}
The only solution I can think of is wrap all the fields in a container, add an extra identifier for each object, and use a function to return the fields, like so
Bar : Foo{
public readonly int id = 0;
public static Wrapper wrapper;
}
public Wrapper GetWrapper(int id){
switch(id){
case 0:
return Bar.wrapper;
}
}
However, as you can see, I need to maintain one additional class and function, and I'd rather not to fragment my code. Is there any alternative?
Edit
What you are asking for, i.e. accessing a static or const value in a subclass from a base class is technically possible, but doing so will violate the principals of good SOLID OO design. Also, since you will need an instance of a specific subclass in order to be able to 'reason over' the type of the subclass in order to obtain the appropriate field1, there's little point approaching this problem statically.
Instead, the common, cleaner, approach here is to use subtype polymorphicism which will allow a calling method in the base class, or a method in an external class altogether, to access the appropriate value for 'field1' based on the subclass. This allows control over the value returned to remain inside the appropriate subclasses (i.e. as per your words, the code won't become "fragmented").
Alternative solution using subclass polymorphicism (recommended)
A subclass polymorphic approach (i.e. with the virtual/abstract and override keywords) will allow you to encapsulate the retrieval of a value (or object) which is customizable for each subclass. Here, the abstraction remains conceptually at "give me an integer value", and then the sub-class-specific implementations of 'how' to return the value can be abstracted (hidden) from the caller. Also, by marking the base property as abstract, you will force all subclasses to implement the property, so that the requirement to provide a value isn't forgotten about.
i.e. I would recommend a polymorphic approach like this:
public abstract class Foo
{
public abstract int Result { get; }
}
public class Bar : Foo
{
// This is implementation specific. Hide it.
private const int field1 = 5;
public override int Result
{
get { return field1; }
}
}
public class Baz : Foo
{
public override int Result
{
// No need for this implementation to be a constant ...
get { return TheResultOfAReallyComplexCalculationHere(); }
}
}
If there are no other reusable concrete methods on the base class Foo, then you could also model the abstraction as an interface, with the same effect:
public interface IFoo
{
int Result { get; }
}
Approaching this problem without polymorphicism (Not recommended)
Any compile-time attempt to access static fields on subclasses will typically require code somewhere to switch (or map) on the actually type of the subclass instance, e.g.:
public class Foo
{
public int result1
{
get
{
switch(this.GetType().Name)
{
case "Bar":
return Bar.field1;
case "Baz":
return Baz.field1;
default:
return 0;
}
}
}
public void MethodRequiringValueFromSubclass()
{
Console.WriteLine(result1);
}
}
public class Bar : Foo
{
public const int field1 = 5;
}
public class Baz : Foo
{
public const int field1 = 10;
}
The problem here is that the Open and Closed principal is violated, as each time a new sub class is added, the result1 method would need to be changed to accomodate the new class.
I'd suggest to use abstract function rather that using static member.
public abstract class Foo{
public result1 {
get{
return get_field1();
}
}
protected abstract int get_field1();
}
public class Bar : Foo{
public const int field1 = 5;
protected override int get_field1() { return field1;}
}
public class Baz : Foo{
public const int field1 = 10;
protected override int get_field1() { return field1;}
}
You either add constructor parameter to your Foo class which can be passed from inheritors, thus you don't need extra classes also you'll have less coupling
public class Foo
{
private readonly int _field1;
public Foo(int field1)
{
_field1 = field1;
}
}
or you can use it exactly from inheritors type as static/const members are members of class type
public class Foo
{
public result1
{
get
{
return Bar.field1;
}
}
}
but this gives your code less flexibility and more coupling.
Also you have an option by using virtual properties which you can implement in derrived classes and use in base:
public class Foo
{
public virtual int Field { get { return 0; } }
}
Instead of making Foo abstract as other answers suggested you can use virtual and override result1 in each child class
public class Foo
{
public virtual int result1 { get; }
}
public class Bar : Foo
{
public const int field1 = 5;
public override int result1
{
get { return field1; }
}
}
public class Baz : Foo
{
public const int field1 = 10;
public override int result1
{
get { return field1; }
}
}
If you want default result1 to return something else than 0 you can give it another value
public class Foo
{
public virtual int result1 { get; } = -1;
}
I always feel like a jerk when I answer my own question... Yet didn't see what I was expecting so I might as well just share what I've got after a night of mind boggling.
The reason I don't want to make the calculation abstract/virtual is because there are many subclasses and the formula is the same for all of them. I just refuse to type the same code 10-20 times repeatedly.
Couldn't make the static fields non static either, as they should be accessible at a class level plus they can get big, and they are the same for all instances.
The only solution I can come up that minimizes code fragment is something like this
public class Foo {
public class Wrapper {
Fields...
}
public Wrapper wrapper; // reference
public int result1 { get; }
}
public class Bar : Foo {
public static Wrapper subclassWrapper; // put in the implementation
public Bar() : base(){
wrapper = subclassWrapper;
}
}
So each instance now needs to hold an extra reference, however I don't need to keep a function. The wrapper is kept within the base class so it is less fragmented.
I have multiple classes. Each one have two constants defined (the constants values differ, but I know every class has this 2 constants). Those constants are used as values for a DbColumn Attribute (It's not possible to use Properties instead). I want to use this classes as generics in another class and get the value of the constants.
Here's a little example:
public abstract class BaseAssignment
{
//Won't work
public (abstract) const string Item;
public (abstract) const string AssignedItem;
}
public class AssignemtA : BaseAssignment
{
public const string Item = "A";
public const string AssignedItem = "1";
[DbColumn(Item)]
...
[DbColumn(AssignedItem)]
...
}
public class AssignmentB : BaseAssignment
{
public const string Item = "B";
public const string AssignedItem = "2";
[DbColumn(Item)]
...
[DbColumn(AssignedItem)]
...
}
public class AssignmentHandler<Tobj> where Tobj : BaseAssignment
{
public void Test()
{
Console.WriteLine(Tobj.AssignedItem);
}
}
The BaseAssignment class would not work, because it's not possible to define a abstract constant. Is there any possibility to solve this problem?
Abstract and constants are orthogonal. Constants are kind of static member, whereas abstract means it participates in inheritance and which should be a instance member.
My suggestion is to use abstract property. If you can't use properties, then you'll have to use reflection to read the constant value.
Here's how you do with reflection:
public class AssignmentHandler<TObj> where TObj : BaseAssignment
{
public void Test()
{
var assignedItemField = typeof(TObj).GetField("AssignedItem", BindingFlags.Static | BindingFlags.Public);
Console.WriteLine(assignedItemField .GetRawConstantValue());
}
}
Note:Even if you use abstract property, you can't use Tobj.AssignedItem. You need a instance of Tobj to read the property.
Is there a way to modify the access of some attribute to a specific class? More specifically, I want to create a property that has a public get, but can only be set by a certain class.
Example:
public Class1
{
Class2.SomeInt = 5;
}
public static Class2
{
private static int someInt;
public static int SomeInt
{
get { return someInt; }
(give access to Class1 only somehow?) set { someInt = value; }
}
}
Update (more info):
I'm doing this in xna, I want the main type (Game1) to be the only thing that can modify a static helper class. It's for a group project in school, we're using SVN (not sure how that'd be relevant), I could just tell everyone in my group to avoid setting the values, but I was wondering if there was a better way.
This sounds like the friend access modifier, which C# doesn't have. The closest I've seen to this in C# is to have the "unrelated" class be an interface and have a private implementation within a class. Something like this:
public interface IWidget
{
void DoSomethingPublic();
}
public class SomeObject
{
private ObjectWidget _myWidget = new ObjectWidget();
public IWidget MyWidget
{
get { return _myWidget; }
}
private class ObjectWidget
{
public void DoSomethingPublic()
{
// implement the interface
}
public void DoSomethingPrivate()
{
// this method can only be called from within SomeObject
}
}
}
Code external to SomeObject can interact with MyWidget and sees anything that's on the IWidget interface, but code internal to SomeObject can also non-interface public members on MyWidget.
It seems to be impossible in C#. You can only use public, protected, protected internal, internal and private access modifiers.
But you can, for instance, make an assembly that contains only these two classes and set the internal modifier for the SomeInt setter or nest one class into another.
If you want to just hide a setter from the IntelliSense, you can define this setter in some interface and implement it explicitly:
public interface IHidden<T>
{
T HiddenPropery { set; }
}
public class SomeClass : IHidden<int>
{
private int someInt;
public int HiddenPropery
{
get { return someInt; }
}
int IHidden<int>.HiddenPropery
{
set { someInt = value; }
}
}
Usage:
// This works:
((IHidden<int>)new SomeClass()).HiddenPropery = 1;
// This doesn't:
new SomeClass().HiddenPropery = 1;
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; }
}
I want to create an abstract base class for all paramter-type classes to inherit from in my application. All paramters will have name, ID and required properties.
All parameters will have their properties set from XML via the SetProperties method (the XmlParser class shown below is just for demonstration).
Since all parameters will have the same 3 properties, I wanted the base class to set those properties but have the inheriting class extend the SetProperties method to set the additional properties it contains.
I was thinking of something like overriding events on a Control.
Here is a sample of what I was thinking, although it does not work.
abstract class ParameterBase
{
protected string ParameterName;
protected bool IsRequired;
protected int ParameterId;
public abstract void SetProperties(string xml)
{
this.ParameterName = XmlParser.GetParameterName(xml);
this.IsRequired = XmlParser.GetIsRequired(xml);
this.ParameterId = XmlParser.GetParameterId(xml);
}
}
abstract class Parameter1 : ParameterBase
{
private string _value;
public string ParameterName
{
get { return base.ParameterName; }
}
public bool IsRequired
{
get { return base.IsRequired; }
}
public int ParameterId
{
get { return base.ParameterId; }
}
public string Value
{
get { return _value; }
}
public Parameter1()
{
}
public override void SetProperties(string xml)
{
base.SetProperties(xml);
_value = XmlParser.GetValue(xml);
}
}
I would do simply, like this:
abstract class ParameterBase
{
protected string ParameterName;
protected bool IsRequired;
protected int ParameterId;
public abstract void SetProperties(string xml);
}
and derived one:
public class Parameter1 : ParameterBase
{
public override void SetProperties(string sml)
{
//set properties including those ones of parent
}
}
It's easy and clearer to manage in this way. Move common properties in separate base class it's good, but persistance management (Save/Load), leave to children. They should know how to do that.
Code provided has a couple of problems:
abstract method can not have body
you have strange public override void SetValues(string xml) which I think should be
public override void SetProperties(string xml)
There are four issues with your code that I can see:
You are redefining the 3 shared properties, and you're trying to name them the same as an existing field. This is not allowed. The simplest way is to implement the properties in the base class in the same way you implemented Value in the inheriting class: with backing fields. In C# 3.0 and above (Visual Studio 2008 and up), you can use auto-implemented properties with a private setter. This will make the compiler create the backing fields for you. For example:
public string ParameterName { get; private set; }
You are declaring the SetProperties method as abstract. This should be virtual. abstract means that the subclass must define the entire implementation. That's not the case here.
In your derived class, you override SetValues but the method is called SetProperties.
You are declaring Parameter1 as abstract. You can't instantiate abstract classes, so you would have to inherit a class from Parameter1 as well in order to use it. I'm guessing you would just want to remove the abstract qualifier.
I would make the common Base class properties Public with protected setters, then you can access them from any derived classes, no use duplicating code!
protected string ParameterName { get; protected set; };
protected bool IsRequired { get; protected set; };
protected int ParameterId { get; protected set; };
You are making it too complicated. The first three properties can be inhertied from the base class:
public abstract class ParameterBase
{
public string ParameterName { get; private set; }
public bool IsRequired { get; private set; }
public int ParameterId { get; private set; }
public virtual void SetProperties(string xml)
{
ParameterName = XmlParser.GetParameterName(xml);
IsRequired = XmlParser.GetIsRequired(xml);
ParameterId = XmlParser.GetParameterId(xml);
}
}
public class Parameter1 : ParameterBase
{
public string Value { get; private set; }
public override void SetProperties(string xml)
{
base.SetProperties(xml);
Value = XmlParser.GetValue(xml);
}
}
Also note that an abstract method cannot have a body, instead it is terminated by a semicolon:
public abstract void SetProperties(string xml);
You must delacre it as virtual if you want to give it a base implementation.
(And you must override SetProperties, not SetValue.)
As noted, don't over think it. I'd declare the abstract parameter class so that it has a single constructor (protected) that takes the mandatory three properties ( Name, IsRequired, and ID). This means that every concrete subtype must construct it properly.
Then, I'd have an abstract factory method, CreateInstance(), that every concrete subtype must implement, returning an instance of AbstractParameter. Why? Read up on the Liskov Substitution Principle. In the Real World, of course, it might make more sense to, rather than use a factory method, separate the concern of how to creating parameter instances from the concerns of being a parameter, by moving the construction logic into its own factory class (AbstractParameterFactory?).
I might note, though, that you're missing an essential property that all parameters will have: a Value. You might consider making your abstract parameter's base class generic.
Anyway, here's my AbstractParameter class:
public abstract class AbstractParameter
{
public string Name { get ; protected set ; }
public bool IsRequired { get ; protected set ; }
public int ID { get ; protected set ; }
protected AbstractParameter( string name , bool isRequired , int id )
{
this.Name = name;
this.IsRequired = isRequired;
this.ID = id;
this.Value = default(T) ;
return;
}
public abstract AbstractParameter CreateInstance( string xml ) ;
}
A concrete parameter class that derives from AbstractParameter might then look something like this:
public class ConcreteParameter : AbstractParameter
{
public ConcreteParameter( string name , bool isRequired , int id ) : base( name , isRequired , id )
{
return ;
}
public override AbstractParameter CreateInstance( string xml )
{
string name = XmlParser.GetName();
bool required = XmlParser.GetIsRequired();
int id = XmlParser.GetID();
ConcreteParameter instance = new ConcreteParameter( name , required , id );
return instance;
}
}