CODE :
public class A {
public const int beingSupportedRate = 0;
}
public partial class B : A {
public const int beingSupportedRate = 1;
}
I want it as explicitly as a const int because of performance.
Putting virtual in front of class A variable beingSupportedRate causes compiler error following :
The modifier 'virtual' is not valid for this item
You should use the new keyword to explicitly hide the inherited member:
public class A
{
public const int beingSupportedRate = 0;
}
public class B : A
{
public new const int beingSupportedRate = 1;
}
Remember that you cannot access the constant member from an instance.
Console.WriteLine(A.beingSupportedRate);
Console.WriteLine(B.beingSupportedRate);
Output:
0
1
There are some problems that you should consider when using this solution. Take the following console program, for example:
class Program
{
static void Main(string[] args)
{
A a = new A();
B b = new B();
C c = new C();
a.GetBeingSupportRate();
b.GetBeingSupportRate();
c.GetBeingSupportRate();
Console.Read();
}
public class A
{
public const int beingSupportedRate = 0;
public void GetBeingSupportRate()
{
Console.WriteLine(beingSupportedRate);
}
}
public class B : A
{
public new const int beingSupportedRate = 1;
}
public class C : B
{
}
}
This will output 0 for all three class instances, since the inherited method uses the constant value in A. This means you will have to override all methods that reference the constant.
A preferred approach is to use an interface with a property that must be implemented and not use constants for this purpose.
Fields (including constants) can't be virtual. That has nothing to do with it being a constant... it's just the way fields work... although the fact that constants are implicitly static makes it even less feasible, as it were.
If you want polymorphic behaviour, it has to be via an instance member which is a property, method or event.
As an aside, I strongly suspect your "I want it as const for performance reasons" justification is bogus micro-optimization. It's not even clear how you're using this, but I very much doubt that you've tried it as a non-constant and proved that it's too slow.
Actually I believe you misunderstood the point of polymorphism in object-oriented programming.
Constants, fields and variables are just a storage (well, references, but I'm talking from the conceptual point of view).
Polymorphism is about changing the behavior of something. Overriding a constant couldn't be changing a behavior but changing its value.
Another point is a constant is static, thus it doesn't belong to an instance but there's an immutable single value in the AppDomain and it survives for the application life-cycle.
With the above statement, why you would want to override a constant like an instance member? Do you imagine the next situation?
public class A
{
public virtual const int Some = 1;
}
public class B : A
{
public override const int Some = 2;
}
public class C : A
{
// No override here!
}
int valueOfSomeConstant = C.Some;
Hold! If a constant is static, C.Some would be 2 even if C does override no constant!
Some quote from your question:
I want it as explicitly as a const int because of performance. [...]
This has only an answer: the premature optimization is the devil of any software development.
As Jon Skeet said, this is going to be the least of your issues.
Constants cannot be overridden, they are constant.
If you want this value to be alterable by extension then you'll need to use something less constant, with a nature of being changed per context, such as an abstract element to implement or virtual to override.
U Can do this i guess:
public class A
{
public virtual Int32 beingSupportedRate
{
get { return 0; }
}
}
public class B : A
{
public override Int32 beingSupportedRate
{
get { return 1; }
}
}
Related
So I'm aware of several ways to make private fields accessible to other classes, I just I feel like their must be an easier way because I could do it easier in C++ with pointers.
Basically, I have a class with a large number of integers, that then creates a number of classes that use these integers. But each class only uses a few integers each. What I want is to allow each class to access only the variables that they need, but have all the remaining integers be unaccessible.
Basically what I would do in C++ is:
class PrivateClass
{
private:
int a, b, c, d;
public:
void DoStuff();
};
And then
void DoStuff()
{
ClassOne class_one(&a, &b);
ClassTwo class_two(&c, &d);
//stuff
}
So then class_one has access to the values of a and b, while class_two has access to the values of c and d. (Also, if I've made any errors in my code forgive me, it has been a while since I've actually written in C++)
Given how easy it is to do there, it makes me feel (perhaps erroneously) like there must be a similarly easy method in C#. If not, I'll mostly just make an indexer to encapsulate the variables so that they can be accessed that way.
Edit: Basically I'm getting that I should just use properties like I've been weirdly avoiding. I don't mind making properties for a few fields, but for some reason doing it for 30 or so just feels wrong, like there should be a better way.
The idea of sharing private variables with another class doesn't quite make sense. There are various access modifiers, but that doesn't help if you want one class to have access to certain members, another class to have access to different members, and so forth.
So the first question is how to share variables. Typically we do that with properties.
In this example another class can read A but can't change it. Another class can both read and write B. There is no property for changing _c.
If we want to split hairs, nothing outside the class can actually read or change the variables. They can only access the property, and the property reads/writes the variable.
(You can also do this with auto-properties. You don't need a variable and a separate property. But that's irrelevant for now.)
class PrivateClass
{
private int _a;
private int _b;
private int _c;
public int A => _a;
public int B
{
get { return _b; }
set { _b = value; }
}
};
Next you want to be able to control which classes can "see" which variables.
As long as there are properties, you can't absolutely prevent someone from writing code that calls them. But you can control how one class "sees" another class.
Here's a contrived example. These types don't make much sense.
public class PublicTransportVehicle : IPublicTransport, IMotorVehicle
{
public int PassengerCapacity { get; private set; }
public int PassengerCount { get; set; }
public int AxleCount { get; private set; }
}
public interface IPublicTransport
{
int PassengerCapacity { get; }
int PassengerCount { get; set; }
}
public interface IMotorVehicle
{
int AxleCount { get; }
}
The PublicTransportVehicle class has three int properties. Two are read-only. One is read-write. (I used auto-properties instead of variables. This just means that if set is private then only the class itself can set the property.)
Now I can write a class with a method that takes an argument of type IPublicTransport. I can pass an instance of PublicTransportVehicle or any other class that implements the interface. But the method only sees IPublicTransport. The only properties it knows about are the ones exposed by that interface.
I can write another method that takes an argument of type IMotorVehicle and it only interacts with the properties defined in that interface.
I can pass an instance of PublicTransportVehicle to either method because it implements both interfaces, but each one sees it differently.
Can we absolutely prevent the caller from accessing properties we didn't want it to access? That's a lot harder. For example, a class could do this:
public void DoSomethingWithMotorVehicle(IMotorVehicle motorVehicle)
{
var publicTransportVehicle = motorVehicle as PublicTransportVehicle;
if (publicTransportVehicle != null)
{
publicTransportVehicle.PassengerCount = 1000;
}
}
But we usually can't and shouldn't bother trying to exercise complete control over that. It's practically impossible. The idea is to communicate which properties and methods consumers are expected to interact with. We do that by deliberately making them accessible. If someone wants to something weird like casting an object or using reflection there's not a lot we can do. Unless it's a serious security-related matter we don't need to worry about that.
Private fields, methods, properties, constructors, and events are all meant to be used by the class only. If you want to access these fields from other classes, you can make something like this:
using System;
namespace SharePrivateFields
{
class Supervisor
{
void DoStuff()
{
var subject = new Subject();
var first = new First(subject);
var second = new Second(subject);
}
}
class Subject : IFirstSubject, ISecondSubject
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
public int D { get; set; }
}
interface IFirstSubject
{
int A { get; set; }
int B { get; set; }
}
interface ISecondSubject
{
int C { get; set; }
int D { get; set; }
}
class First
{
private IFirstSubject _subject;
public First(IFirstSubject subject)
{
_subject = subject;
}
protected void DoMagic()
{
Console.WriteLine(_subject.A); // Completely correct
Console.WriteLine(_subject.C); // `IFirstSubject` does not contain definition for `C`
}
}
class Second
{
private ISecondSubject _subject;
public Second(ISecondSubject subject)
{
_subject = subject;
}
protected void DoMagic()
{
Console.WriteLine(_subject.A); // `ISecondSubject` does not contain definition for `A`
Console.WriteLine(_subject.C); // Completely correct
}
}
}
However, we're now treading waters of Abstract Factory Design Pattern, which is a more desirable approach in this case.
I'm convinced that the C++ implementation you're mentioning is a flawed design, so it's a reason why you can't make it easy in C# (if we're being completely honest - you can, read about Unsafe code, pointer types, and function pointers; but it's 99% of a time taboo for C# code).
So I suggest you learn about Abstract Factory or at least use my solution for your use-case.
Make the method static and send the corresponding instance to it, then you can access the data you want.
Static Void DoStuff(PrivateClass instance)
{
ClassOne class_one(instance.a, instance.b);
ClassTwo class_two(instance.c, instance.d);
//stuff
}
But the reality is that it is wrong, you should either add reading and writing properties to your variables to be able to send them to DoStuff from outside as a parameter.
//in Main
PrivateClass pClass = new PrivateClass(1,30,2,19);
DoStuff(pClass.A, pClass.B, pClass.C, pclass.D);
//in PrivateClass
namespace Test
{
class PrivateClass
{
private int a;
private int b;
private int c;
private int d;
public PrivateClass(int a, int b, int c, int d)
{
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
public int A
{
get
{
return this.a;
}
set
{
this.a = value;
}
}//etc
public static void DoStuff(int a, int b, int c, int d)
{
ClassOne class_one(a, b);
ClassTwo class_two(c, d);
//stuff
}
}
}
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 two classes, A and B. B inherits from A.
Here is my problem : I have a constant ConstantA which is useful for the class A, but also for the child classes. I also have a constant ConstantB, which is specific to my class B.
Since I store my constants in a public static nested class, the Constants class in the child class hides the parents one. I tried making it a partial class, it does not help. Is there any way to solve this?
Here's an example :
public class A
{
public static partial class Constants
{
public const int ConstantA = 1;
}
}
public class B : A
{
public static partial class Constants
{
public const int ConstantB = 1;
}
}
Thank you!
You would need to make A a partial class as well, and declare your B-specific constant separately from the B class itself:
public partial class A
{
public static partial class Constants
{
public const int ConstantA = 1;
}
}
public partial class A
{
public static partial class Constants
{
public const int ConstantB = 1;
}
}
public class B : A
{
static void M()
{
int i = Constants.ConstantB;
int j = Constants.ConstantA;
}
}
That said, I'm skeptical that design is all that good. It has the effect of declaring your ConstantB value inside A, which seems contrary to the goal of encapsulation, assuming ConstantB really is relevant only to class B. If you declare it this way, ConstantB is accessible via any use of the Constants class, in any type.
But if you're okay with that, and are just trying to make sure the declaration of the constant stays with the B class, then the above will work.
Other options include going ahead and hiding (using the new keyword) the base Constants class, with the minor inconvenience of having to specify the base class as fully-qualified to access the base values (e.g. A.Constants.ConstantA), hiding the base class and having the B.Constants class inherit A.Constants (requires abandoning the static class attribute) or, IMHO much better, not using a nested class at all, and instead putting the Constants classes in their respective namespaces.
Simply make your ConstantA an attribute of your parent class, putting this attribute in a nested class removes it from the scope of the inherited class.
If you really want nested classes, you can leave the static keyword, and do inheritance for the B.Constants nested class:
public class A
{
public class Constants
{
public const int ConstantA = 1;
}
}
public class B : A
{
public new class Constants : A.Constants
{
public const int ConstantB = 2;
}
}
The usage will be the same.
I have the following classes:
public class HeaderBase
{
public int HeaderSize { get { return sizeof(byte); } }
public byte[] Content { get; private set; }
public HeaderBase(byte[] bytes)
{
Content = bytes;
}
}
public class BiggerHeader : HeaderBase
{
public new int HeaderSize { get { return sizeof(byte) + sizeof(UInt32); } }
public BiggerHeader(HeaderBase header) : base(header.Content)
{ }
}
I also have a templated method to marshal and instantiate the BiggerHeader type
public static T Get<T>() where T : HeaderBase
{
HeaderBase b = new HeaderBase(new byte[]{});
T instance = (T)Activator.CreateInstance(typeof(T), b);
return instance;
}
According to MSDN:
where T : <base class name>: The type argument must be or derive from the specified base class.
However, the value of HeaderSize is 1 and not 5 as I would have expected. Why would this be the case, and how can I instantiate an object which will use the new properties from derived types?
DotNetFiddle
Related: Generics in C# - how can I create an instance of a variable type with an argument?
new members have the same name as a base member but are otherwise unrelated. It looks like you want to make use of virtual in the base and override in the derived class.
With new you essentially silenced the warning that warned you about this. new had no functional effect.
Calls on T are resolved as if T was HeaderBase. Anything else would require the runtime to perform a dynamic binding at runtime based on the name of what you called. Imagine T t; t.Xyz();. That code would not compile because no Xyz was found statically. But you are doing the same thing! At the time of compiling the method there is no Derived.HeaderSize visible because we don't know that T is going to be Derived. It could end up being something else. That's why the call is statically bound to Base.HS. The fact that B.HS and D.HS have the same name means nothing. It's a coincidence.
Well, I believe that mainly error here is a result of bad architecture.
Let's add some improvements and make all properties, that has to be changed in every other derived class - abstract. By doing so we'll make sure that we didn't forget anything, and can start using polymorphism (override behaviour).
Let's also use some features of C# 6.0
It'll also make code more readable :
public abstract class AbstractHeader
{
public abstract int HeaderSize { get; }
public virtual byte[] Content { get; set; }
protected AbstractHeader() { }
protected AbstractHeader(byte[] bytes)
{
Content = bytes;
}
}
public class BaseHeader : AbstractHeader
{
public override int HeaderSize => sizeof (byte);
}
public class BiggerHeader : AbstractHeader
{
public override int HeaderSize => sizeof (byte) + sizeof (UInt32);
public BiggerHeader(BaseHeader header) : base(header.Content)
{
}
}
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; }
}