public int userID;
//global variable
public Index()
{
userID = 10;
return userID;
}
public TaskCompleted()
{
Console.WriteLine(Index())
}
i want the userID to be accessed in each and every method and can we updated anywhere
Your Index method has two problems.
Syntax problem: Every method must have a return type. Either a real type like int or the void keyword.
public int Index()
Semantic problem. At every call it sets userID and returns it. Why store the value in this variable? It will be replaced by a new value at the next call and could just be a local variable (i.e., a variable inside the method) or be dismissed completely. But maybe your example was simply not complete.
Let's try different approaches:
Passing value through a class field (your "global" variable).
private int _userId;
public void SetUserId() // `void` means that the method is not returning a value.
{
_userId = 10;
}
public void PrintUserId()
{
Console.WriteLine(_userId);
}
This requires you to call SetUserId(); before calling PrintUserId();
Let the method return the value.
public int GetUserId() // `int` means that the method is returning an `int` value
{
return 10;
}
public void PrintUserId()
{
Console.WriteLine(GetUserId());
}
Combine the two previous approaches
private int _userId;
public void SetUserId()
{
_userId = 10;
}
public int GetUserId()
{
return _userId;
}
public void PrintUserId()
{
Console.WriteLine(GetUserId());
}
C# has a concept called "property". A property is a set of "Get" and "Set" methods, just as in the previous example, but with as special syntax.
private int _userId;
public UserId
{
get { return _userId; }
set { _userId = value; }
}
public void PrintUserId()
{
Console.WriteLine(UserId);
}
A property having no additional logic besides assigning and returning a value can also be implemented as an auto-property.
public int UserId { get; set; } // A hidden field is automatically created.
The caller would have to do something like this:
var obj = new MyClass();
obj.UserId = 10;
obj.PrintUserId();
You can use a static property of a static class:
public static class Globals
{
public static int UserID {get; set;}
}
Usage: var userId = Globals.UserID;
Related
I have a class library project, I want to create a variable and assign a value to it through MethodA() whose value can be access through MethodB().
Just like we have a session in ASP.NET.
I cannot pass as a parameter to MethodB() because MethodB() is being used in many places and if I change it, all the other methods will get affected.
Public Void MethodA()
{
string value ="Hello";
}
public Void MethodB()
{
-- I want to read the value which is set in MethodA()
}
I need to dispose the value as well after reading it in MethodB().
Both of these methods are in different classes inside the same project.
First try to create a property with a private setter:
public class A
{
public string Value { get { return MethodA(); } }
public string MethodA()
{
return "Hello";
}
public void MethodB()
{
var value = Value;
}
}
If you have two classes:
public class A
{
public string FooMethod()
{
return string.Empty;
}
}
public class B
{
public string BarMethod()
{
var result = new A().FooMethod();
return result;
}
}
You can get idea to handle your exception
public class test
{
public static int value = 0; //Global variable
public void MethodA()
{
//you can assign here as well
value++;
}
}
public class HomeController : Controller
{
test t = new test();
public IActionResult Index()
{
t.MethodA();
int d = test.value;
//you can assign here as well
test.value = 100;
int dd = test.value;
return View();
}
}
I am learning C# so I am still on the basics here. This is my code
class foo
{
protected int id;
protected string data;
static int nextId = 1;
public int Id
{
get { return id; }
}
public foo()
{
this.id = nextId++;
}
public foo(string somedata)
{
this.data = somedata;
this.id = nextId++;
}
}
This code works just fine for now. All objects will have a unique ID with them.
Problem is: I don't want the first ID to be 1, I want it to be the number on the first line of the file given as an argument to the application from the commandline. If no file is specified or the file does not exist, then it can be one. Is there a way to make a one-time method to set nextId so it cannot be tampered with outside of the class after it has been once set?
Duh... I guess this is the trick. Still, I'd like to know if there is some build in way to make variables that can only be set once.
public int nextId
{
set {if(nextId<1) nextId = value;}
}
You can implement static constructor, which assigns proper value to nextId before first usage of foo class:
using System.IO;
using System.Linq;
...
class foo
{
...
static int nextId;
// read-only property which however can be assigned in the constructor
public int Id {get;}
// This static costructor will be called once before 1st usage of foo class
static foo() {
//TODO: put the right file name here
string fileName = Environment.GetCommandLineArgs()[1];
nextId = int.Parse(File
.ReadLines(fileName)
.First());
}
public foo()
{
//Let's increment nextId in thread-safe manner
Id = Interlocked.Increment(ref nextId);
}
...
}
You can do this
class foo
{
private static int nextId = 1;
private static bool isNextIdSet;
public SetId(newId)
{
if (!isNextIdSet) nextId = newId;
isNextIdSet = true;
}
}
So the nextId can be set only once from outside the class.
UPDATE: if you prefer to use this with many variables, you can create a helper for this, such as
class SetOnlyOnce<T>
{
private bool isSet;
public T Value
{
get;
set
{
if (!isSet) Value = value;
isSet = true;
}
}
}
Then use it as
class Foo
{
public SetOnlyOnce<int> prop1 {get;set;}
public SetOnlyOnce<string> prop2 {get;set;}
}
class Bar
{
public Bar()
{
var foo = new Foo();
foo.prop1.Value = 2;
foo.prop1.Value = 3; // this doesn't set.
}
}
As an alternative to Dmitry's answer, you can define the initialization through a static method. I prefer avoiding static constructors unless multiple fields need to be initialized simultaneously.
using System.IO;
using System.Linq;
...
class foo
{
...
// The initialization will be called at some time before first use of nextId.
private static int nextId = GenerateInitialNextId();
// read-only property which however can be assigned in the constructor
public int Id {get;}
private static int GenerateInitialNextId() {
//TODO: put the right file name here
string fileName = Environment.GetCommandLineArgs()[1];
return int.Parse(File
.ReadLines(fileName)
.First());
}
public foo()
{
//Let's increment nextId is thread-safe manner
Id = Interlocked.Increment(ref nextId);
}
...
}
What I have is:
public static class IDs {
public static string someID { get; set; }
static IDs() {
log.info(someID);
// use someID here
}
}
public class otherClass {
public void otherMethod(string sym) {
IDs.someID = sym;
}
}
and then using an instance of otherClass like this:
otherClassInstance.otherMethod("someStringSymbol");
I dont have any build errors, but log.info(someID); is printing null.
I was expecting it to be someStringSymbol.
This is because the static constructor is called automatically before the first instance is created or any static members are referenced..
This means that when an instance of otherClass invokes IDs.someID = sym; the first operation that gets executed is the static constructor, i.e. the code inside static IDs().
At this point the static variable has not yet been initialized, and you are basically executing log.info(null);.
After the static constructor completes, the variable is initialized, so you should be able to see its value inside otherMethod, after the first reference of IDs.
Given the OP's requirement:
I want to use the value passed in someID in a switch statement
The solution could be to simply execute a static method whenever a new value is set, with the help of explicit getters and setters:
public static class IDs
{
private static string _someID; // backing field
public static string SomeID
{
get { return _someID; }
set
{
_someID = value;
DoSomethingWithSomeID();
}
}
private static DoSomethingWithSomeID()
{
// Use SomeID here.
switch (IDs.SomeID)
{
...
}
}
}
public class OtherClass
{
public void OtherMethod(string sym)
{
// This will set a new value to the property
// and invoke DoSomethingWithSomeID.
IDs.SomeID = sym;
}
}
DoSomethingWithSomeID will be invoked every time someone sets a new value to SomeID.
I dont think what you are trying to do is suited to static classes. I would try the following
public class IDs{
public string someID{ get; set; }
public IDs(string someId){
this.someID = someId;
log.info(this.someID);
//use someID here
}
}
pulic class otherClass{
public otherMethod(string sym){
IDs id = new IDs(sym);
}
}
public class anotherClass{
//access instance of otherClass in wrp and call otherMethod()
wrp.otherMethod("someStringSymbol")
}
I am new to C# I am trying to pass a value to a method but receiving 0.Creating an instance to the main method of calc and calling the calc methods in main.
public void test()
{
var calc = new Calc();
calc.Add(1);
var actual = calc.Value;
}
public class Calc
{
public int Value{
get; set;
}
public void Add(int value)
{
int result = value + value;
}
I am trying to set the current value, how could I do that?
I'd suggest refactoring it a bit so the variable names are more clear. Your initial problem is that you weren't doing anything with the result, when really you wanted to set it to your property.
public class Calc
{
public int CurrentValue { get; set; }
public void Add(int number)
{
this.CurrentValue = this.CurrentValue + number;
}
}
The result of your Add method is not stored anywhere, i.e. the after the method is complete all the memory allocated while it was executed, is released. If you wish to save the result of your method you should either return it (which will require changing your method's prototype) or save it in a member of you class and access it with an appropriate property or getter-method.
Your class should be something like this:
public class Calc
{
private int result;
public int Value
{
get { return result; }
set { result = value; }
}
public void Add(int value)
{
result = value + value;
}
}
Please note that currently the Add methods just saves the result of two times of the value of the sent parameter value into the class member result
I think you want something more like this:
public class Calc
{
public int Value{
get; private set;
}
public void Add(int value)
{
this.Value += value;
}
}
Note I changed your Value to have a private setter, so that only the Calc class has access to change its value, whereas other objects are still able to retrieve its value.
Notice the change in the Add function, we're adding the value passed into the function onto your Value property. In your case you were just creating a new variable result in each call of the Add method, and then doing nothing with it.
You can see it in action here
Edit 1
Is it possible to do this with get/set? Something like the below? This works for me but I am worried I am missing something not to mention all the staticness.
///<summary>
/// Class to track and maintain Heads Up Display information
///</summary>
public static class HUD
{
///<summary>
///Declare variables to store HUD values
///</summary>
private static string _lastName;
private static string _firstName;
private static string _middleName;
private static string _suffix;
private static string _sSN;
private static string _personID;
private static string _masterID;
private static string _enrollmentID;
private static string _planID;
// Store a reference to THE form that holds the HUD and is visible
private static FrmModuleHost _frmHUDHost;
public static string PersonId
{
get { return _personID; }
set
{
FrmHudHost.tbxHUD_PersonID.Text = value;
_personID = value;
}
}
public static string SSn
{
get { return _sSN; }
set
{
FrmHudHost.tbxHUD_SSN.Text = value;
_sSN = value;
}
}
public static string MiddleName
{
get { return _middleName; }
set
{
FrmHudHost.tbxHUD_MiddleName.Text = value;
_middleName = value;
}
}
public static string FirstName
{
get { return _firstName; }
set
{
FrmHudHost.tbxHUD_FirstName.Text = value;
_firstName = value;
}
}
public static string LastName
{
get { return _lastName; }
set
{
FrmHudHost.tbxHUD_LastName.Text = value;
_lastName = value;
}
}
public static string Suffix
{
get { return _suffix; }
set
{
FrmHudHost.tbxHUD_SuffixName.Text = value;
_suffix = value;
}
}
public static string MasterID
{
get { return _masterID; }
set
{
FrmHudHost.tbxHUD_MasterID.Text = value;
_masterID = value;
}
}
public static string EnrollmentID
{
get { return _enrollmentID; }
set
{
FrmHudHost.tbxHUD_EnrollmontPeriod.Text = value;
_enrollmentID = value;
}
}
public static string PlanID
{
get { return _planID; }
set
{
FrmHudHost.tbxHUD_PlanID.Text = value;
_planID = value;
}
}
public static FrmModuleHost FrmHudHost
{
get { return _frmHUDHost; }
set { _frmHUDHost = value; }
}
}
Original Post
I have a class that is responsible for updating a Heads Up Display of current selected member info. My class looks like this -->
public static class HUD
{
///<summary>
///Declare variables to store HUD values
///</summary>
public static string _lastName;
public static string _firstName;
public static string _middleName;
public static string _suffix;
public static string _sSN;
public static string _personID;
public static string _masterID;
public static string _enrollmentPeriod;
public static string _planID;
///<summary>
/// Method to update the display with current information
///</summary>
public static void UpdateHUD (FrmModuleHost frm, params String[] args)
{
frm.tbxHUD_LastName.Text = args[0];
_lastName = args[0];
frm.tbxHUD_FirstName.Text = args[1];
_firstName = args[1];
frm.tbxHUD_MiddleName.Text = args[2];
_middleName = args[2];
frm.tbxHUD_SSN.Text = args[3];
_sSN = args[3];
frm.tbxHUD_PersonID.Text = args[4];
_personID = args[4];
}
}
What I am trying to figure out is how I can tell what args are being passed. What you see below is what is called from the Search Page as that is all that is available at that point. The other 4 values will be loaded 1 at a time on various pages. A person HAS A enrollment which HAS A plan if that helps.
private void GetResults()
{
var lName = getCurrentRowVal("Last Name");
var fName = getCurrentRowVal("First Name");
var pID = getCurrentRowVal("Person ID");
var sSN = getCurrentRowVal("SSN");
var mName = getCurrentRowVal("Middle Name");
HUD.UpdateHUD(FrmWwcModuleHost, lName, fName, mName, sSN, pID);
}
Now when I call this from the Enrollment Page I will want everything to stay and add the EnrollmentID.
private void GetResults()
{
var enrollmentID = getCurrentRowVal("EnrollmentID");
HUD.UpdateHUD(FrmWwcModuleHost, enrollmentID);
}
My question is, How do I do that and know which arg[] index to call and not overwrite the existing values?
Is it as simple as always providing ALL parameters as they are set? So my call from the Enrollment Page would instead look like this -->
private void GetResults()
{
var enrollmentID = getCurrentRowVal("EnrollmentID");
HUD.UpdateHUD(FrmWwcModuleHost, HUD._lastName, HUD._firstName, HUD._middleName, HUD._sSN, HUD._personID, enrollmentID);
}
Thanks for any insights!
You'll really need to ditch the params style call and establish real parameters for your methods. Just create multiple overloads for your most common call signatures.
I did not see a reference to a particular version of .net you are using. Here is how I handle this in .net 3.5.
First create a class for passing the update values in, but make all of the properties nullable (since all of your items are string, they are already nullable). If the values are nullable, add actual property setters, and LastNameChanged properties.
public class UpdateData {
public string LastName { get; set;};
public string FirstName { get; set;};
public string MiddleName { get; set;};
...
}
Now your method signature looks like this:
public static void UpdateHUD (FrmModuleHost frm, UpdateData data)
{
if (!string.IsNullOrEmpty(data.FirstName) {
frm.tbxHUD_LastName.Text = data.FirstName;
_lastName = data.FirstName;
}
if (!string.IsNullOrEmpty(data.LastName) {
frm.tbxHUD_FirstName.Text = data.LastName;
_firstName = data.FirstName;
}
if (!string.IsNullOrEmpty(data.MiddleName) {
frm.tbxHUD_MiddleName.Text = data.MiddleName;
_middleName = data.FirstName;
}
Next is the setting the UpdateData and calling the method:
UpdateHUD(FrmWwcModuleHost, new UpateData{ FirstName = "test1", LastName = "test2", ...});
Final note: you are using a lot of statics here. You might consider changing most of them. Move the static variables to an actual class with properties (but no statics), and reference the class in your code.
Perhaps instead of
params String[] args
you should do
params KeyValuePair<String,String>[] args
where any given param's properies would be assigned something like this:
Key = "Last Name"
Value = "Hare"
Then inside your UpdateHUD method you could check to see what the Key of the parameter was so you would know which value was being passed.
You could also create a separate class to pass in the params array. Something like:
public class HUDParam {
public HUDParam(paramName, paramValue) { /*[init code here...]*/ }
public string Name { get; set; }
public string Value { get; set; }
}
Then:
HUD.UpdateHUD(frm, new HUDParam("FirstName", "Tom"),
new HUDParam("LastName", "Thompson");
In your update method, you can just check the name and set the appropriate value in your HUD.
C# 4.0 has optional params which are much different from the params keyword. Params keyword is literally no different at runtime than if you didn't have the params keyword at all. In other words, you just get an array of values with no way of knowing which are which. Params keyword is just a C# convenience at compile time.
Although I haven't used C# 4.0 optional parameters yet, I imagine they behave similarly to the way VB.NET optional parameters did in that you can specify a default value at the function and that default will be used if the caller doesn't specify it. But the caller still has to indicate (either with missing values or paramName:= syntax) which parameter they are specifying.
In your case I think you're better off using either normal named parameters and passing null when you don't need them, or pass a dictionary/hashtable instead.
You could pass the arguments with a Dictionary where you can assign a value to a certain name.
The cleanest version would be to make a method for each variable.
e.g.
void UpdateLastName(string name)
{
frm.tbxHUD_LastName.Text = _lastName = name;
}
If you can use Framework 4.0, you can use optional and named parameters. Until that time, you will need to pass all the arguments.
But, I think by your question you might misunderstand what's happening slightly. The arguments you send in params are going into the method as an argument. Their scope therefore is the method itself, so you not "overwriting" anything. The array that you used for the first call is gone (out of scope) and the array you use for the second call will have whatever you put in it. Best way to do optional parameters before 4.0 is using multiple method overloads.
If you have a name association with a value but possibly unknown name values this is a candidate for a Dictionary .
Optional parameters involve no less checking than checking a dictionary if a key exists or if a member of a class is null. Since there already exists a primitive for this and it's more flexible I see no reason to use variable parameters or optional parameters.
What I would do is use an ananoymous type (which can be turned into a dictionary at runtime) and then changing the values which are present.
New function definition:
public static void UpdateHUD (FrmModuleHost frm, object args);
And client code:
UpdateHUD(frm, new {
MiddleName = "Jed",
SSN = "..." });
Using the code from Roy Osherove's Blog, this can be turned into a dictionary. The new implementation would be similar to:
var dictionary = MakeDictionary(args);
if ( dictionary.ContainsKey("SSN") ) { _sSN = dictionary["SSN"]; }
Of course, this will all be irrelevant when C# 4.0 comes out.