How I will use the following static variable from other class? - c#

I have a class like following:
public class Trainee
{
private static int numberOfTrainee = 30;
private string traineeName;
private string tarineeId;
}
Now I want to access the static data "numberOfTrainee" in the following class without creating a object of "Trainee" class and I don't want to write getter for "numberOfTrainee". Because, static member can be used only using "." operator.
public class TraineeUI : Form
{
private void showButton_Click(object sender, EventArgs e)
{
// I want to access "numberOfTrainee" here. Something like following:
// MessageBox.Show("Total number of trainee is: " );
}
}

If you don't want a getter for it, the only way to use it from elsewhere will be to increase the visibility, like so:
public class Trainee
{
public static int NumberOfTrainee = 30;
private string traineeName;
private string tarineeId;
}
// Other code.
MessageBox.Show("Total number of trainee is: " + Trainee.NumberOfTrainee);
However, I would recommend against doing this with a field that can change. Unless it's a constant, you should define a property to control access to this field, static or not.

You should make a property, like this:
public class Trainee
{
private static int numberOfTrainee = 30;
public int TraineeCount { get { return numberOfTrainee; } }
private string traineeName;
private string tarineeId;
}
Note that you may want to consider thread safety... it's possible that this simple implementation will give stale results in a multi-threaded environment. Making numberOfTrainee volatile would solve this.
Further, note that by making this a property rather than giving direct access to the field, you:
Can add extra logic should you ever wish to
Can make the property readonly, but modify the field from within the class
Keep encapsulation intact: a property is part of the API of a class, whereas a field is an implementation detail

I don't want to recycle what others have said, but....
You need to look at access modifiers. You say you don't want to make numberOfTrainee public, but you can make it internal. That way, if Trainee and TraineeUI are in the same assembly, than TraineeUI can access the field of Trainee without the field being exposed to types outside the assembly.
I would make it a property instead of a field though.

Well, either you could make it public and then just calll it with:
Trainee.numberOfTrainee
Or you could create a static readonly property.
public static int NumberOfTrainee
{
get
{
return numberOfTrainee;
}
}

Related

How to declare variables and methods globally i.e. outside a class? [duplicate]

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);

How to return class instance from static class?

I want use a static class that must contains global variables, so I can access to all application controls simply from a variable.
Actually I've this implementation:
public static class Globals
{
public static HeadToHead Head2Head
{
get { return Resources.Controls.HeadToHead; }
}
}
in the case above, I want return the instance of HeadToHead control, the control look like this:
public partial class HeadToHead : UserControl
{
public static int HomeId = 0;
}
my goal is to access to the static variables of this control, like: Globals.Head2Head.HomeId
but I get this error on this line: get { return Resources.Controls.HeadToHead; }
HeadToHead is a type which is not valid in the given context
You're returning what looks like a type from a property that seems to be declaring an instance of that type. If you truly want to return that type, there's syntax for that (I don't remember any more, I think in c# it's classname.type). If you want to return an instance, then you need to get that instance from somewhere.
As an aside, static instances of UI controls are a bad idea, and a code smell.
You have to instantiate an instance of the type and return that. As you want a single global instance you could use the static constructor.
public static class Globals {
static Globals(){
Head2Head = new Resources.Controls.HeadToHead();
}
public static HeadToHead Head2Head { get; private set; }
}
There are few situations in which you would actually want to do this but common static settings that do not change in the life of the application might be one of them. As HeadToHead inherits from UserControl that does not really seem to be the case, an instance of a UserControl should ideally never be static.

how to define a Global Structure in C#?

I want to define a global structure in C# and use it in three separate subroutines. I have already created the structure but I don't know how to make it a global variable so I can use it in multiple sections of my code. Any help is appreciated.
public struct Simple
{
public int Position;
public bool Exists;
public double LastValue;
};
static void Main(string[] args)
{
Simple s;
s.Position = 1;
s.Exists = false;
s.LastValue = 5.5;
}
So I want to use a Simple structure in two other routines in my code and possible pass it to different form (multiple usage of one variable).
The closest thing to "global" in C# is "static". Simply define the class and all members as static and it'll be accessible from anywhere the containing namespace is referenced. EDIT as Servy correctly points out, the class itself does not have to be static; however doing so forces all members to be static at compile-time. Also, static members can have any visibility, so you can have a private static field used by a public static property or method, and you can have an internal static class that won't be visible outside its home assembly. Just being static doesn't automatically make it wide open.
However, a better pattern might be the Singleton; you define a class that has one static instance of itself, that can then be passed around. The benefit is that you can still deal with the object as an instance class if you want to, but the same instance is available everywhere using a static getter. Here's some reading material: http://csharpindepth.com/Articles/General/Singleton.aspx
In your case it appears that you have a object as a local variable in your main method that you need to use in another method. The appropriate solution in this context is to add a parameter to that other method. Take a look at this example:
public class MyObject
{
public int Value;
}
public static void Main(string[] args)
{
MyObject obj = new MyObject();
obj.Value = 42;
PrintObject(obj);
Console.WriteLine("Press any key to exit...");
Console.ReadKey(true);
}
public static void PrintObject(MyObject obj)
{
Console.WriteLine(obj.Value);
}

Private 'set' in C# - having trouble wrapping my brain around it

I've seen a lot of example code written using something like (please forgive how horribly canned this is):
public class Test
{
public object Thingy { get; private set; }
}
Unfortunately, these kinds of examples never really explain why 'set' is set as private. So, I'm just wondering if there's a good, common example that will illustrate to me why something like this would be used.
I sort of see it - the property can be run to process some extra logic in addition to setting that field. I'm just confused on how it would be invoked, and why this approach would be used rather than a generic setter method.
This would be if you have a property that you don't want anyone to set but your class. This can be handy with database id's. The internal class can set it but you wouldn't want anyone else changing it. So you can give them read access but not write.
EDIT: One more point on this is that using what you showed there is helpful for automatic properties. Unfortunately with automatic properties you are unable to only specify get so to avoid exposing a setter publicly it is just made private.
EDIT: Just thought I would throw in an example. Automatic properties are great for clean, terse code. But like you showed there is a limitation in that you have to have get and set. So before it was like this for a property like you showed:
public class Test
{
private object thingy;
public object Thingy
{
get { return thingy; }
}
}
Now we can get rid of that unneeded private declaration but it requires both. So make private to get around that.
I know this was overkill on the explanation but different things kept popping in my head.
As a simple example; it is a cheap way of making an "immutable enough" object (for use in threading, state, etc). But also anywhere where the client simply shouldn't need to assign it, or can't be trusted to assign it (correctly).
Another example might be a list:
public List<Foo> Items {get;private set;}
since we might call obj.Items.Add() etc, but we would rarely assign obj.Items = .... However, this example is marred by needing explicit initialization in the constructor, and XmlSerializer hates it - to be honest for lists I mainly use:
private readonly List<Foo> items = new List<Foo>();
public List<Foo> Items {get { return items;}}
which solves both of these.
As another example, contrasting:
private readonly int foo;
public int Foo {get{return foo;}}
vs
private readonly int foo;
public int Foo {get{return foo;} private set {foo=value;}}
this pattern may be useful in serialization, for example with DataContractSerializer (with the addition of some attributes), since many serializers will still look for private accessors. This avoids us having to decorate our internal state (foo), but gives the veneer of privacy to the set.
Ultimately anything can be bypasses and assigned via reflection, so private set is only intended to avoid accidental damage to data.
The private makes it into a readonly property. A common example is if you have multiple classes passing around a single object, you don't want another class to be able to modify the instance.
Basically, it is a readonly property. If it was written in full (not as an auto property) you would simply leave out the setter.
Two examples that are largely the same:
class Foo1
{
public int Id { get; private set; }
public Foo1()
{
Id = lastId ++;
}
}
class Foo2
{
private int _id;
public int Id { get { return _id; } }
public Foo2()
{
_id = lastId ++;
}
}
I've seen this used with the design:
public class whatever
{
public string WhateverId { get; private set; }
public static whatever Create(string whateverId)
{
return new whatever() { WhateverId = whateverId };
}
}
So you create whatever class, but after it's created the id can't be changed because it might break things that are connected to it.
the private set just gives the simple initializer syntax, I kind of like it for some scenarios.
Also can be used if it's changeable, but you need to manage it when changes are made
public void SetWhateverId(string whateverId)
{
DisconnectAllCurrentWhateverIdReferences();
WhateverId = whateverId;
ReconnectAllPreviousWhateverIdReferences();
}
This syntax allows you to provide a public-facing property that appears read-only to consumers of your API but internally can be changing. By auto-implementing in this way, you avoid having to write boilerplate code such as a distinct setter or a backing field for the value, and you leave room in your design to add a bespoke set algorithm if it is deemed necessary at some point in the future without having to decide right away.
private set is very handy for simple immutable value types.
struct Point
{
public int X { get; private set; }
public int Y { get; private set; }
public Point(int x, int y)
{
this = default(Point);
X = x;
Y = y;
}
}
This is just laziness that comes about from auto-properties. Before auto properties were around, people would implement the getter and omit the setter for properties which are meant to be read-only.
public class Test
{
private /*readonly*/ Type _thingy;
public Type Thingy { get { return _thingy; } }
}
Hopefully, C# 5 will allow you to create auto-properties with a getter only - because that's what everyone wants. (They should make readonly setters in auto-props too, I need that badly)
To answer the question of a common scenario where this might be used...
In an MVP pattern, if your Model exposes some properties for your Presenter I would write
public string Bazinga { get; private set; }
Now, the Model can change this value but other classes that use it cannot.

Checking variable from a different class in C#

Greetings-
I have 2 classes. One is called "Programs" and the other is called "Logs". The class called Programs has public const string m_sEnviron = ""; near the top and I need to check what the m_sEnviron variable is set to through my class called Logs. The variable m_sEnviron will get set from a scheduler called Tidal so how can I check its value from a different class. If this is not the best to do this then please let me know what the better ways are.
Thanks in advance.
Regards,
Namespace NightScripts
{
class Program
{
public static string m_sEnviron {get; set;}
static void Main(string[] args)
{
}
//Lots of other functions...
}
class Logs
{
//I try to get access to m_sEnviron but it will not show after I type Program.
}
}
Well, m_sEnviron isn't a variable (/field) - it is a const; it is always "".
If it was a static property (or field), then Programs.m_sEnviron. If it was an instance property (or field) then someInstance.m_sEnviron should work, since it is public - but I would rename it.
I expect you mean it to be a static field; which can work, but you should at least be a little cautious that this doesn't necessarily play nicely if you start using multiple threads, etc. And public fields are generally best avoided (prefer private fields and public properties).
For example:
public static string Environ {get;set;}
would be a public, static property easily accessible as Program.Environ.
const basically makes the variable static and readonly. So public const string m_sEnviron = ""; means that m_sEnviron will ALWAYS be the empty string. If you try and change it, you will get an error.
However, to access it from a method in the Logs class, you just access it just like a static variable:
string foo = Programs.m_sEnviron;
If I understand your question correctly, you could specify the class where the variable is located as a static class which would therefore not require instantiation.

Categories