Checking variable from a different class in C# - 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.

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

C# Give an constructor internal value

I am trying to give a class an object which don’t have control over it. That mean if the main class change the object, the class I’ve created have also the changes.
Example:
class main
{
private string test;
public main()
{
var Test = new Test(test);
}
}
If I change now the string “test” the object Test should also see the change string. Is that possible?
It is possible to do if you instead of string use a specially crafted class:
public class SharedData
{
public string Test {get;set;}
}
Then if you have an object of type SharedData instead of string, they will share the value. Strings are immutable in C#, so you wont' have the same string reference in both classes.
class main
{
private SharedData test = new ShareData();
public main()
{
var Test = new Test(test);
}
}
P.S. It's a different question whether this is a good design or not. It's hard to answer based on the examples you have provided. I would avoid such design if possible and rather pass string as parameter where you need it to have less state. But as always it depends and there can be cases where what you do is beneficial, but you can consider changing the design to make it easier.

Get name of property static as a string [duplicate]

I am getting into C# and I am having this issue:
namespace MyDataLayer
{
namespace Section1
{
public class MyClass
{
public class MyItem
{
public static string Property1{ get; set; }
}
public static MyItem GetItem()
{
MyItem theItem = new MyItem();
theItem.Property1 = "MyValue";
return theItem;
}
}
}
}
I have this code on a UserControl:
using MyDataLayer.Section1;
public class MyClass
{
protected void MyMethod
{
MyClass.MyItem oItem = new MyClass.MyItem();
oItem = MyClass.GetItem();
someLiteral.Text = oItem.Property1;
}
}
Everything works fine, except when I go to access Property1. The intellisense only gives me "Equals, GetHashCode, GetType, and ToString" as options. When I mouse over the oItem.Property1, Visual Studio gives me this explanation:
MemberMyDataLayer.Section1.MyClass.MyItem.Property1.getcannot be accessed with an instance reference, qualify it with a type name instead
I am unsure of what this means, I did some googling but wasn't able to figure it out.
In C#, unlike VB.NET and Java, you can't access static members with instance syntax. You should do:
MyClass.MyItem.Property1
to refer to that property or remove the static modifier from Property1 (which is what you probably want to do). For a conceptual idea about what static is, see my other answer.
You can only access static members using the name of the type.
Therefore, you need to either write,
MyClass.MyItem.Property1
Or (this is probably what you need to do) make Property1 an instance property by removing the static keyword from its definition.
Static properties are shared between all instances of their class, so that they only have one value. The way it's defined now, there is no point in making any instances of your MyItem class.
I had the same issue - although a few years later, some may find a few pointers helpful:
Do not use ‘static’ gratuitously!
Understand what ‘static’ implies in terms of both run-time and compile time semantics (behavior) and syntax.
A static entity will be automatically constructed some time before
its first use.
A static entity has one storage location allocated, and that is
shared by all who access that entity.
A static entity can only be accessed through its type name, not
through an instance of that type.
A static method does not have an implicit ‘this’ argument, as does an
instance method. (And therefore a static method has less execution
overhead – one reason to use them.)
Think about thread safety when using static entities.
Some details on static in MSDN:
Static Classes in C#
Static Constructors in C#
This causes the error:
MyClass aCoolObj = new MyClass();
aCoolObj.MyCoolStaticMethod();
This is the fix:
MyClass.MyCoolStaticMethod();
Explanation:
You can't call a static method from an instance of an object. The whole point of static methods is to not be tied to instances of objects, but instead to persist through all instances of that object, and/or to be used without any instances of the object.
No need to use static in this case as thoroughly explained. You might as well initialise your property without GetItem() method, example of both below:
namespace MyNamespace
{
using System;
public class MyType
{
public string MyProperty { get; set; } = new string();
public static string MyStatic { get; set; } = "I'm static";
}
}
Consuming:
using MyType;
public class Somewhere
{
public void Consuming(){
// through instance of your type
var myObject = new MyType();
var alpha = myObject.MyProperty;
// through your type
var beta = MyType.MyStatic;
}
}
cannot be accessed with an instance reference
It means you're calling a STATIC method and passing it an instance. The easiest solution is to remove Static, eg:
public static void ExportToExcel(IEnumerable data, string sheetName)
{
Remove the static in the function you are trying to call. This fixed the problem for me.
I got here googling for C# compiler error CS0176, through (duplicate) question Static member instance reference issue.
In my case, the error happened because I had a static method and an extension method with the same name. For that, see Static method and extension method with same name.
[May be this should have been a comment. Sorry that I don't have enough reputation yet.]
I know this is an old thread, but I just spent 3 hours trying to figure out what my issue was. I ordinarily know what this error means, but you can run into this in a more subtle way as well. My issue was my client class (the one calling a static method from an instance class) had a property of a different type but named the same as the static method. The error reported by the compiler was the same as reported here, but the issue was basically name collision.
For anyone else getting this error and none of the above helps, try fully qualifying your instance class with the namespace name. ..() so the compiler can see the exact name you mean.
Check whether your code contains a namespace which the right most part matches your static class name.
Given the a static Bar class, defined on namespace Foo, implementing a method Jump or a property, chances are you are receiving compiler error because there is also another namespace ending on Bar. Yep, fishi stuff ;-)
If that's so, it means your using a Using Bar; and a Bar.Jump() call, therefore one of the following solutions should fit your needs:
Fully qualify static class name with according namepace, which result on Foo.Bar.Jump() declaration. You will also need to remove Using Bar; statement
Rename namespace Bar by a diffente name.
In my case, the foollowing compiler error occurred on a EF (Entity Framework) repository project on an Database.SetInitializer() call:
Member 'Database.SetInitializer<MyDatabaseContext>(IDatabaseInitializer<MyDatabaseContext>)' cannot be accessed with an instance reference; qualify it with a type name instead MyProject.ORM
This error arouse when I added a MyProject.ORM.Database namespace, which sufix (Database), as you might noticed, matches Database.SetInitializer class name.
In this, since I have no control on EF's Database static class and I would also like to preserve my custom namespace, I decided fully qualify EF's Database static class with its namepace System.Data.Entity, which resulted on using the following command, which compilation succeed:
System.Data.Entity.Database.SetInitializer<MyDatabaseContext>(MyMigrationStrategy)
Hope it helps
YourClassName.YourStaticFieldName
For your static field would look like:
public class StaticExample
{
public static double Pi = 3.14;
}
From another class, you can access the staic field as follows:
class Program
{
static void Main(string[] args)
{
double radius = 6;
double areaOfCircle = 0;
areaOfCircle = StaticExample.Pi * radius * radius;
Console.WriteLine("Area = "+areaOfCircle);
Console.ReadKey();
}
}

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

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

Regarding C# Static Readonly members

I have the following situation. There is some very common class in my application that contains a static readonly field called "BinDirectory" that holds the path to the bin directory. Other fields in this class, which are static readonly too, use this value to as a base to their value. On the current version BinDirectory is initialized to hold the directory where the code is running (i.e. Assembly.GetExecutingAssembly().CodeBase). I want to extend this class to initialize BinDirectory to hold the "TargetDir" from the installer context when it is run from my application installer. I can change BinDirectory to be simply static but I don't want to, since it will make me do lots of changes to a class that is common in my app. Can somebody suggest an elegant solution to this problem?
Make it a property with just the "get" accessor:
public static string BinDirectory
{
get { return _initialisedBinDirectory; }
}
Then in your static constructor code, initialise the private variable as you need.
EDIT
Delayed load (as per comment):
public static string BinDirectory
{
get
{
if (_initialisedBinDirectory == null)
// load the variable when needed
else
return _initialisedBinDirectory;
}
}
This way you only load the variable when you need it, and it's re-used whenever you call it again. Hopefully you don't class null as a valid value for it though.
This is what AppConfigs are for. In your AppSettings section, add a new key called BinDirectory. You can re-write your class as:
public static string BinDirectory
{
get
{
return ConfigurationManager.AppSettings["BinDirectory"];
}
}
Finally, as one of the last steps in your installation process, you can change the BinDirectory to point to any directory you want. So now this value is determined entirely by the installer context.
It sounds like you're loath to change a static readonly field to simply static because it would force you to change the initialization of all of the other static readonly fields in your class.
If that is correct, unfortunately there isn't a whole lot you can do but take the time to make the change. By allowing the BinDirectory field to be set at runtime you are fundamentally changing the initialization sequence of the fields. Your code will need to adapt.
I think the easiest way is to convert to using static readonly properties which do the calculation of the value on the fly.
For example:
public class Values {
public static string BinDir;
public static string OtherDir {
get { return Path.Combine(BinDir,#"Some\Other\Path"); }
}
}

Categories