I have a csharp app with a xml config file containing an element called "environment" which can be set to different values (development/test/production for example).
When this config file entry is modified the resulting global variables within the application should all change. I have a class in my application called Globals were I am storing global variables. I want to add a case/switch element to it but it won't seem to work.
So for example I have the following defined at the top of the globals class:
public static string environment = MyApp.Properties.Settings.Default.Environment;
Then lower down in my class I'm trying to do the following:
switch (environment)
{
case "development":
public static string Server = "SQL1";
public static string Username = "dev.user";
case "test":
public static string Server = "SQL2";
public static string Username = "test.user";
case "production":
public static string Server = "SQL3";
public static string Username = "prod.user";
default:
public static string Server = "SQL1";
public static string Username = "dev.user";
}
(In the example above I reduced the number of variables to two just to make it more understandable but in reality there are probably 30 variables per environment.)
This doesn't work I get multiple errors:
Invalid token 'switch' in class, struct, or interface member declaration
Invalid token ')' in class, struct, or interface member declaration
Invalid token 'case' in class, struct, or interface member declaration
Is there some other way of doing this?
Thanks
Brad
public static class Globals
{
public static string Environment = MyApp.Properties.Settings.Default.Environment;
public static string Server;
// rest of code
public static void LoadEnvironment()
{
switch (Environment)
{
case "development":
{
Server = "SQL1";
Username = "dev.user";
break;
}
// rest of code
}
}
}
Based on the error the compiler thinks it is coded inside the body of the class. Try moving the logic inside a method or some such and this may be due to your access modifiers inside your switch statement - eg. public static etc
public static should be declare in the class scope, not within a function.
You can initializes static variable either in the line of declaration or within the static constructor.
You forgot puting "break at the end of each case.
So the code should looke like this:
public class MyClass
{
public static string Server;
public static string Username;
static MyClass()
{
switch (environment)
{
case "development":
Server = "SQL1";
Username = "dev.user";
break;
case "test":
Server = "SQL2";
Username = "test.user";
break;
case "production":
Server = "SQL3";
Username = "prod.user";
break;
default:
Server = "SQL1";
Username = "dev.user";
break;
}
}
}
Try to define your strings before the switch statement. For each case, you have to define a break statement to make the pointer get out of the switch structure.
For your case, it's a good idea to define the Server and Username as properties and in a static constructor of a static class, define these values from the object. For sample:
public static class Globals
{
// define properties
public static string Server { get; set; }
public static string Username { get; set; }
// encapsulate the Settings.Environment in a property
public public static string Environment
{
get { return MyApp.Properties.Settings.Default.Environment; }
}
// when the application starts, this static scope will execute!
static Globals()
{
switch (environment)
{
case "development":
Server = "SQL1";
Username = "dev.user";
break;
case "test":
Server = "SQL2";
Username = "test.user";
break;
case "production":
Server = "SQL3";
Username = "prod.user";
break;
default:
Server = "SQL1";
Username = "dev.user";
}
}
}
To use it, just call
var server = Globals.Server;
var user = Globals.Username;
Related
Simply put how do you establish a connection between method variable decloration and connect it with class properties (or inner objects), lets say you have default or hard set values in a class like this (obviously they could be other types but for simplicity its set to strings) :
public class SampleClass
{
public string strA = "Something 1";
public string strB = "Something 2";
public string strC = "Something 3";
}
//think of it as a data layer where strings are pointers to dbSets
How do you leverage the same SampleClass in a method that allows ONLY pick of properties Method(property).
Easy sample that does what its supposed to:
public class ProccessClass
{
private string _dummyOut;
public ProccessClass Pick(string input)
{
this._dummyOut = input;
return this;
}
}
class Program
{
static void Main(string[] args)
{
var Test = new ProccessClass().Pick(new SampleClass().strB);
// we know this works and compiles and returns the strB
}
}
What would you have to convert to ommit the new instantiation and skip the class declaration (if possible but in theory should be doable)
new SampleClass().strB
needs to be just
strB
So how to get the final code to execute??
public class SampleClass
{
public string strA = "Something 1";
public string strB = "Something 2";
public string strC = "Something 3";
}
public class ProccessClass
{
private string _dummyOut;
public ProccessClass Pick(SampleClass sampleClass) //is it the variable declaration?
{
this._dummyOut = input;
return this;
}
}
class Program
{
static void Main(string[] args)
{
string Test = new ProccessClass().Pick(strB);
//so NO new keywords clean and easy set based on class provided above
}
}
Constructor and void setters but no go, the goal is to set the Hard relation ship between the method intake value and setters
I need to get string from one class to another class,
It is possible to set public string from method I mean like in this code:
class test
{
static void Main(string[] args)
{
load();
}
public class Data
{
public string datacollected { get; set; }
}
public static void load()
{
string fileName = "samplefile.json";
string jsonString = File.ReadAllText(fileName);
Data datacfg = new Data();
var datanew = System.Text.Json.JsonSerializer.Deserialize<List<Data>>(jsonString);
datacfg = datanew.First();
}
public string datacollected = datacfg.datacollected;
}
i want to use string datacollected in another class and in another public void
The datacollected member that is directly in the test class is not a property. It's a field. Fields that have an assignment on the same statement as the declaration are evaluated before* the class's constructor (ie: before the Main method runs).
You probably want it to be a property instead, which is evaluated each time you access the member. The simplest method to fix that is by adding a > after the equals.
public string datacollected => datacfg.datacollected;
You've got two other problems though.
datacollected (in the test class) isn't static. All of your methods are static, and therefor wouldn't be able to access the non-static member.
You've still got the problem where the datacfg is a local variable that is defined inside the load method. You can't use variables outside their defined scope.
Option 1: you only need the parsed file data in the method that called load.
Change load to return the parsed data, rather than save it to a class-global variable.
using System.Text.Json;
static class test
{
static void Main(string[] args)
{
Data loadedData = load();
}
public static Data load()
{
string fileName = "samplefile.json";
string jsonString = File.ReadAllText(fileName);
return JsonSerializer.Deserialize<List<Data>>(jsonString).First();
}
}
public class Data
{
public string datacollected { get; set; }
}
Option 2: If you really need some global variable, put the whole Data object up to a field instead. This doesn't use a property - there's really no advantage in this case.
using System.Text.Json;
static class test
{
// assuming you're using nullable reference types (the "?")
private static Data? loadedData;
static void Main(string[] args)
{
load();
Console.WriteLine(loadedData!.datacollected);
// "!" to tell compiler that you know loadedData
// shouldn't be null when executed
}
public static void load()
{
string fileName = "samplefile.json";
string jsonString = File.ReadAllText(fileName);
loadedData = JsonSerializer.Deserialize<List<Data>>(jsonString).First();
}
}
public class Data
{
public string datacollected { get; set; }
}
I'd go with Option 1 if at all possible.
* I don't remember if it's before, during, or after.
You can declare a class like this
public class UseData
{
private List<Data> _data=null;
public string datacollected
{
get
{
if (_data == null)
LoadData();
return _data.First().datacollected;
}
}
private void LoadData()
{
string fileName = "samplefile.json";
string jsonString = File.ReadAllText(fileName);
_data = System.Text.Json.JsonSerializer.Deserialize<List<Data>>(jsonString);
}
}
which have a private list of data and it loads from your json file at first time you called. Next time you call it, as the private _data object is filled, it wont load again and the datacollected property returns the first data object's datacollected string property.
public class Program
{
public static void Main(string[] args)
{
var c = check.myValue("Example 1"); //This is the pattern I've to use, don't want to create an object (Is it possible to use it with static class)
Console.WriteLine(c.result1);
Console.WriteLine(c.result2);
}
}
public static class check
{
public static void myValue(string qr)
{
public string result1 = "My Name" + qr;
public string result1 = "You're" + qr;
}
}
See here Online Example (Code is not working)
Every thing on main function I've to use exactly the same pattern because I'll use it in a lot of different classes and I don't want to create object each and every time by using non-static class.
Please correct me if I'm wrong
There's a lot wrong with the syntax of that code, which #Sergey addresses in his answer.
You appear to want to return an instance of a class from a static method, and that class should contain two properties.
You can do that by creating the actual, nonstatic class containing the properties:
public class Check
{
public string Result1 { get; set; }
public string Result2 { get; set; }
}
Then return a new instance from the static method therein:
public static Check MyValue(string qr)
{
var result = new Check();
result.Result1 = "My Name" + qr;
result.Result2 = "You're" + qr;
return result;
}
However, you're saying in the comments in your code that you don't want to use an object.
In that case it appears you want to use static properties. That's generally not recommendable, but it would look like this:
public static class Check
{
public static string Result1 { get; set; }
public static string Result2 { get; set; }
public static void MyValue(string qr)
{
Result1 = "My Name" + qr;
Result2 = "You're" + qr;
}
}
Then you can read Check.Result1 after calling the method MyValue().
Your code is totally wrong
myValue method returns void. You cannot assign void return value to variable.
You cannot have public modifiers for local variables.
You cannot have local variables with same name in same scope
If you want to return two values from method, then you should return object with two fields - custom class or tuple. You can also use out parameters, but I don't think it's your case
public static class Check
{
public static Tuple<string, string> MyValue(string qr)
{
return Tuple.Create($"My Name {qr}", $"You're {qr}");
}
}
With C# 7 it's a little bit better. You can write this method in one line and provide names for tuple properties
(string MyName, string YourName) MyValue(string qr) => ($"My Name {qr}", $"You're {qr}");
Usage
var result = Check.MyValue("Example 1");
Console.WriteLine(result.Item1); // result.MyName
Console.WriteLine(result.Item2); // result.YourName
You can practice with creating custom class with nicely named properties instead of using tuples.
Why Could I not set my Property?
The DLL is imported and all methods are reachable but the URL property wont show up and also seems to not exists
http://prntscr.com/6y2az8
Dll Code:
namespace Steap
{
public class SteapAPI
{
public static String URL
{
get;
set;
}
public static XmlReader r = XmlReader.Create("");
public int getSteamID64()
{
int ID = 0;
r.ReadToFollowing("steamID64");
ID = r.ReadContentAsInt();
return ID;
}
public string getSteamID()
{
string ID = String.Empty;
r.ReadToFollowing("steamID");
ID = r.ReadContentAsString();
return ID;
}
public string getName()
{
return getSteamID();
}
}
}
I also used string intead of String and I need the static for the later statement
In the image that you added you are trying to access it like this:
SteapAPI sapi = new SteapAPI);
sapi.URL = // ... do something
Your property is static, so you should call it from class and not from instance:
SteapAPI.URL = // ... do something
Static properties are on the class not the instance. Use
SteapAPI.URL
Keep in mind this means the value is shared by all instances of the class.
If it is static then you access it like
SteapAPI.URL
i have one main class and with in this main class i have another class A. class A has few static property and when i tried to access those static property from outside but getting error....not being possible
here is my classes structure
public class EShip
{
class Credentials
{
private static string _accessKey = "aaa";
private static string _accessPwd = "xxx";
private static string _accountNumber = "2222";
public static string AccessKey
{
get { return _accessKey; }
}
public static string AccessPassword
{
get { return _accessPwd; }
}
public static string AccountNumber
{
get { return _accountNumber; }
}
}
public static Credentials Credential
{
{ get; }
}
}
i try to expose that inner class by a main class property and from outside i try to do like
EShip.Credentials.AccessKey
EShip.Credentials.AccessPassword
it is not getting possible......suggest me good approach and why i am stuck. thnx.
Class Credentials is not public, therefore it's not accessible. Change that and you're able to do:
String key = EShip.Credentials.AccessKey;
Access Modifiers (C# Programming Guide)