I've got a wrapper class which encapsulates a piece of information that needs to be transmitted as a byte array.
In that way, the class encapsulates the necessary header (with fields like DATA_LENGTH or MESSAGE_TYPE) into the corresponding byte positions. For that I want to define positions and length in constants, for example:
HEADER_DATA_LENGTH_IX = 0;
HEADER_DATA_LENGTH_LENGTH = 2;
which means DATA_LENGTH starts at 0 and takes two bytes.
but so far I'm struggling with making them constants or static readonly fields. Const cannot be protected, therefore I won't be able to derive a new class and change the constants if a use them, on the other way I might declare new constants in the derived class and the use them.
What will be your approach?
If you want to change the value of these params in a derived class, you can make them readonly and change them in the constructor of the derived class
I wouldn't make them const anyhow, because they're not...
The basic difference is when the variable is initialized. 'readonly' is set at initialization, or in the contructor, while 'const' is set at compile time.
I think the big decision is if you want to inherit the class and override the value. If you do, go readonly. Otherwise I don't think it really matters.
readonly C#ref: http://msdn.microsoft.com/en-us/library/acdd6hb7.aspx
const C# ref: http://msdn.microsoft.com/en-us/library/e6w8fe1b.aspx
Create an inner class with the constants. The deriving classes can then later override the inner class and change the constants as necessary.
e.g. base class:
public class Stuff
{
public class HeaderInformation
{
public const int HEADER_DATA_LENGTH_IX = 0;
public const int HEADER_DATA_LENGTH_LENGTH = 2;
}
}
Then the derived class can do this:
public class DerivedStuff : Stuff
{
public new class HeaderInformation : Stuff.HeaderInformation
{
public new const int HEADER_DATA_LENGTH_IX = 10;
}
}
This way, you have flexibility. In DerivedStuff, the HeaderInformation class has all of the constants in the base Stuff.HeaderInformation class, but can change any of them, or keep the ones it has.
This exact question is answered by the official c# faq on msdn
I wouldn't make these constant because they simply aren't constants. When declaring something as const you should ask yourself: can this change? Your message lengths might change one day, so they are better to be made readonly.
Related
Am new to C#, but have a plenty of experience of VB.net, now my issue is that there are no modules in C# and i need to define a class which is accessible in all classes and i don't know how to do it.
For example I have a "classProject" and I need to make it accessible everywhere, so in vb.net , I will define it in module like below.
Module ModuleMain
Public tProject As New ClassProject
End Module
Now, I need to do same in C#.
Thanks in advance.
You can do this in your case:
namespace MyProject
{
public static class classProject
{
int myIntvar = 0;
string myStringvar = "test";
}
}
And you can use this static class in your other classes like:
public class Test
{
int intTest = classProject.myIntvar; //will be 0
string stringTest = classProject.myStringvar; // will be test
}
You can use the variables in the static class since a static variable shares the value of it among all instances of the class. When you create multiple instances of classProject class, the variables myIntvar and myStringvar are shared across all of other classes in your project. Thus, at any given point of time, there will be only one integer and one string value contained in the respective variable's.
It sounds like you're looking for a static class. You can reference the access modifiers here: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers
I think you need to extends your other classes to class father (ClassProject) And you can access to it with youur children classes.
//[access modifier] - [class] - [identifier]
public class Customer
{
// Fields, properties, methods and events go here...
}
see more
How do I declare a variable so that every class (*.cs) can access its content, without an instance reference?
In C# you cannot define true global variables (in the sense that they don't belong to any class).
This being said, the simplest approach that I know to mimic this feature consists in using a static class, as follows:
public static class Globals
{
public const Int32 BUFFER_SIZE = 512; // Unmodifiable
public static String FILE_NAME = "Output.txt"; // Modifiable
public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}
You can then retrieve the defined values anywhere in your code (provided it's part of the same namespace):
String code = Globals.CODE_PREFIX + value.ToString();
In order to deal with different namespaces, you can either:
declare the Globals class without including it into a specific namespace (so that it will be placed in the global application namespace);
insert the proper using directive for retrieving the variables from another namespace.
You can have static members if you want:
public static class MyStaticValues
{
public static bool MyStaticBool {get;set;}
}
First examine if you really need a global variable instead using it blatantly without consideration to your software architecture.
Let's assuming it passes the test. Depending on usage, Globals can be hard to debug with race conditions and many other "bad things", it's best to approach them from an angle where you're prepared to handle such bad things. So,
Wrap all such Global variables into a single static class (for manageability).
Have Properties instead of fields(='variables'). This way you have some mechanisms to address any issues with concurrent writes to Globals in the future.
The basic outline for such a class would be:
public class Globals
{
private static bool _expired;
public static bool Expired
{
get
{
// Reads are usually simple
return _expired;
}
set
{
// You can add logic here for race conditions,
// or other measurements
_expired = value;
}
}
// Perhaps extend this to have Read-Modify-Write static methods
// for data integrity during concurrency? Situational.
}
Usage from other classes (within same namespace)
// Read
bool areWeAlive = Globals.Expired;
// Write
// past deadline
Globals.Expired = true;
A useful feature for this is using static
As others have said, you have to create a class for your globals:
public static class Globals {
public const float PI = 3.14;
}
But you can import it like this in order to no longer write the class name in front of its static properties:
using static Globals;
[...]
Console.WriteLine("Pi is " + PI);
I want to pass a value to the base class constructor. The problem which I am facing is that the value is stored in a private variable inside derived class. Is it possible to pass it? or is it a good approach to do like this?
This is what I tried
class Filtering : Display
{
private int length = 10000;
public Filtering():base(length)
{
}
}
It is showing
An object reference is required for non-static field, method or
property
Base class
abstract class Display
{
public Display(int length)
{
}
}
Exactly as answerer Chips_100 wrote in his answer (currently deleted by owner):
If you want length to be an instance variable, but still supply it to the base constructor, I would suggest something like the following:
private const int DefaultLength = 10000;
private int length = DefaultLength;
public Filtering() : base(DefaultLength)
{
}
I haven't seen any indication the original author of this answer is inclined to undelete his own post. At the same time, while I would have written basically the same thing, I'd rather not take credit for an answer already present, authored by someone else. So I've converted this to a Community Wiki answer.
Is it bad practice to put most variables at class level in a Form? Would these be considered global variables?
public partial class Form1 : Form
{
private string mode;
private int x, y;
public Form1()
{
InitializeComponent();
}
}
I'm using the variables in multiple controls when I declare them at class level.
What i get from the question is that if you are using as a Individual form that is not dependent on any form then all this variables will be private variables to the class. And if the form is called from somewhere else. Then also it will be private variables. If you really want to make a clear design then you can Create public properties over private variables that you want to expose to other class.
In that way you can put a limit access to the other class to the private variables by creating read only properties so that other classes cannot modify but can access it.
Those would be considered class-level globals (to distinguish from application globals.) The more important distinction in this case is that they are private to the class.
Class-level globals have their uses, so I definitely wouldn't call it a bad practice. A very good use for private class globals is when you plan to expose them through property accessors. For example:
public readonly properties whose values are controlled by logic internal to your class.
public properties with both set and get accessors (enabling custom validation logic in setter.)
However, I would say it's a good practice to make things local unless otherwise necessary. The reason is that you have less mutable state belonging to a class instance, so there is less potential for bugs like this:
private int EvilMethod1() {
x = (int) Math.Pow((double) y, 2);
return x;
}
private int EvilMethod2() {
y = (x + y) * 2;
return y;
}
// Assignments depend on the current values of x and y,
// as well as yielding unexpected side effects.
private void PureEvil()
{
// Return value depends on current y; has side effect on x while assigning y.
y = EvilMethod1();
// Return value depends on current x and y; has side effect on y while assigning x.
x = EvilMethod2();
}
Those aren't considered global variables. They are global only within the Form1 class, not the entire program.
It depends what the variables are used for.
If they are only used within a single method they should be local to that method.
If they describe the state of the class and are used in multiple places they should be declared as class members.
They are private to the class Form1
Without knowing what the intent of your form is, it's hard to say whether what you're doing is good or bad. The variables shown here have class scope, and since they are private, they are not accessible outside of Form1 and are not considered "global."
If you truly want global variables, create a static class with private static variables and public static accessors/mutators (a property in C#), and access the variable through the public property. See this answer for an example.
This is more of an "is there a better way" question than a real problem.
When having a property that is only accessed in a base class:
private const bool isSomething = true;
I sometimes have to change this value in a project where I inherit from this class. But as it is a constant and used class-wide, I normally change the code in the base class to something like this:
private const bool isSomething = true;
protected virtual bool IsSomething{
get{
return isSomething;
}
}
And override the property in the subclass and create a new isSomething constant.
This creates a new field and an override and, in my opinion, is not nice style. Is there a better way to do this?
The value is a constant, and it will be constant in the complete project where I'm using it.
If you need to set the value based on which class you are in but don't want the value to change later, than const is not the right keyword. Instead, you can use readonly and require sub-classes to pass in a value to the constructor.
The readonly keyword is different from the const keyword. A const field can only be initialized at the declaration of the field. A readonly field can be initialized either at the declaration or in a constructor. Therefore, readonly fields can have different values depending on the constructor used. Also, while a const field is a compile-time constant, the readonly field can be used for runtime constants...
Source
Edit:
To summarize: You have a filed that is only accessed by the base class and the base class should never alter that value. In most cases, the default value is fine. However, there are some cases that arise when a subclass need to set it's own value that is different than the default.
class Base {
private readonly bool _isSomething;
public Base() : this(false) {}
protected Base(bool isSomething)
{
_isSomething = isSomething;
}
}
class Child {
public Child() : base(true) {}
}
This provides the same functionality as your suggested work-around. The value can not be changed and only a child class can provide a different value. It has an added benefit of not allow the child class invalidate the fact that the value is intended to be constant. The override method allows for this:
protected override bool IsSomething{
get{
return BOOLEAN_EXPRESSION;
}
}
I understand your idea of making it a static value (since we know every instance will use the same value), but that only makes things complicated as static items are not inherited.