So I have to use this void
static void PerformOption(int option)
However I want this int option to be able to be used by other voids as well.
I know this could be done by deleting inside of brackets and assigning a static int but I have to use int option for this void, so I cannot change this one.
So how can I make option as global variable?
public class MyGlobalsBecauseImEvilAndLoveBadProgrammingMemes
{
public static int Spaghetti { get; set; }
}
then in PerformOption do
MyGlobalsBecauseImEvilAndLoveBadProgrammingMemes.Spaghetti = option;
but hopefully you want a member, then do
public class MyClass
{
int Option { get; set; }
public void PerformOption(int option)
{
Option = option
// other stuff
}
public void SomethingElse()
{
if(Option == 1) // use Option at will
{
}
}
}
Declare a global int variable to hold option value inside the PerformOption method to be used in other methods.
public static class MyClass
{
private static int globalOption;
public static void PerformOption(int option)
{
globalOption = option;
...
}
}
Related
Hi I have some code where I use a static object of Manager to call methods from Manager:
public class Manager
{
public static Manager sManager = new Manager();
public int x;
public Manager()
{
}
public void Modify()
{
x ++;
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Manager.sManager.x);
Manager.sManager.Modify();
Console.WriteLine(Manager.sManager.x);
Console.ReadLine();
}
}
Is this a good way of accessing a method from Manager from outside or is there a better way if the class Manager must own the method Modify.
Would use of events in this case be a better way to build this and have Manager listen for an update?
Or is there a better way to handle this even if I want the method Modify to stay inside the Manager class?
It depends on the architecture you're trying to build.
Make everything static
If it's as simple as that, just make x and Modify static and you won't need an instance.
Use a singleton pattern
If you do need a Manager instance your code would be better using a Singleton pattern
private static Manager _manager;
public static Manager Manager
{
get
{
if (_manager == null)
{
_manager = new Manager();
}
return instance;
}
}
There is no reason here to create a static field of same type in the Manager class. You just need to create an object and then call the needed methods.
A more better way can be to make field private and just expose it for reading so that it can't be modified directly, and we only modify it by calling the modify() method:
public class Manager
{
private int x;
public int X
{
get
{
return x;
}
}
public Manager()
{
}
public void Modify()
{
x++;
}
}
and then in your Program class use it:
class Program
{
static void Main(string[] args)
{
Manager objManager = new Manager();
Console.WriteLine(objManager.X);
objManager.Modify();
Console.WriteLine(objManager.X);
Console.ReadLine();
}
}
This is code inside Proizvod.cs file
namespace mateo_zadatak
{
class Proizvod
{
public string Šifra = "šifra";
public string Naziv = "naziv";
public string Proizvođač = "proizvođač";
public float Cijena;
public int Količina;
private float Ukupno;
private int Popust;
private float UkupnoPopust;
private void variable()
{
Ukupno = Cijena * Količina;
{
if (Količina < 10)
{
Popust = 0;
}
else if (Količina > 9 && Količina < 31)
{
Popust = 5;
}
else Popust = 10;
}
}
}
}
I have to use this variables in Form1.cs file , because i will need some calculations from datagrid. How to connect those two files?
There are no "Global" variables in C# but what you can do is create a new Class with Static variables and assign/use them. For example:
public static class GlobalVariables
{
public static int IntVariable;
public static string StringVariable;
}
And then you can reference them as GlobalVariables.IntVariable and GlobalVariables.StringVariable.
A Form is just a class - Add public properties/members to the Form and access them from a reference to the form.
Make your class public, and make sure you include Proizvod.cs file into your project or add a reference to it from your project.
You can use public properties instead of variables from another class
Perhaps I'm missing something, but:
public class Form1 : ...
{
public Proizvod Foo;
Form1()
{
Foo = new Proizvod();
}
SomeMethod()
{
MessageBox.Show(Foo.Naziv);
}
}
I'm sure I've seen somewhere that I can do the following by using an attribute above my Init() method, that tells the compiler that the Init() method must only be called from the constructor, thus allowing the readonly field to be set. I forgot what the attribute is called though, and I can't seem to find it on google.
public class Class
{
private readonly int readonlyField;
public Class()
{
Init();
}
// Attribute here that tells the compiler that this method must be called only from a constructor
private void Init()
{
readonlyField = 1;
}
}
Rob's answer is the way to do it, in my book. If you need to initialize multiple fields you can do it using out parameters:
public class Class
{
private readonly int readonlyField1;
private readonly int readonlyField2;
public Class()
{
Init(out readonlyField1, out readonlyField2);
}
protected virtual void Init(out int field1, out int field2)
{
field1 = 1;
field2 = 2;
}
}
Personally I find this makes sense in certain scenarios, such as when you want your fields to be readonly but you also want to be able to set them differently in a derived class (without having to chain a ton of parameters through some protected constructor). But maybe that's just me.
Instead of using an Initialize method, how about inheriting a basic constructor through all your other constructors.
i.e.
public class MyClass
{
readonly int field1;
readonly double field2;
public MyClass(int field1, double field2)
{
//put whatever initialization logic you need here...
field1 = 10;
field2 = 30.2;
}
public MyClass(int field1, double field2p1, double field2p2)
: this(field1, (field2p1 + field2p2))
{
//put anything extra in here
}
}
This may be a little late to reach the original person in need, but it seems like this will cleanly solve the problem... Without the need to use any sort of nasty reflection or out parameters.
The only solution I can think of is to return the value from the Init() method that the readonly field needs to be assigned:
public class Class
{
private readonly int readonlyField;
public Class()
{
readonlyField = Init();
}
private int Init()
{
return 1;
}
}
Jared is right; this is not possible. The workarounds I can think of are:
Initialize the field in the declaration.
Initialize the field in the constructor (Manually inline your Init method).
Assign the field to a value returned by a method, e.g.: _myField = GetInitialMyFieldValue();
Pass the field to the Init method, with the out modifier. This may be useful if you have many fields to initialize, which are dependent on constructor parameters. E.g.
private readonly int _x;
private readonly string _y;
private void Init(int someConstructorParam, out int x, out string y){ .. }
public Class(int someConstructorParam)
{
Init(someConstructorParam, out _x, out _y);
}
This cannot be done. Fields which are tagged with readonly can only be set from the constructor
What i ended up doing in current tech (C# 7.x) is use the value tuple system:
public class MyClass
{
private readonly int x;
private readonly int y;
private readonly int z;
public MyClass(int x)
{
this.x = x;
(y, z) = InitYandZ();
}
private (int, int) InitYandZ()
{
return (5, 10);
}
}
Not the cleanest either, But seems cleaner to me.
C# compiler only allows you to set readonly fields if you're initializing them inline:
private readonly int readonlyField = 1;
or from the constructor:
public Class()
{
readonlyField = 1;
}
How about an initialized property with a getter only (as of C# 6.0)?
private int MyProperty { get; } = 0;
I know this is late, but what about using a class as a return value instead of using out params if there is a need to initialize multiple fields, are there any drawacks? Imho this is more convenient and more readable than using nested constructors.
public class MyInitClass
{
public int Field1 { get; set; }
public int Field2 { get; set; }
}
public class Class
{
private readonly int readonlyField1;
private readonly int readonlyField2;
public Class()
{
var init = Init();
readonlyField1 = init.Field1;
readonlyField2 = init.Field2;
}
private MyInitClass Init()
{
return new MyInitClass() { Field1 = 1, Field2 = 2 };
}
}
I think it works if use Reflection. Actually this works for me:
public class Class
{
private readonly int readonlyField;
public int MyField()
{
return readonlyField;
}
public Class()
{
readonlyField = 9;
}
}
and
static void Main(string[] args)
{
Class classObj = new Class();
Console.WriteLine(classObj.MyField());//9
Misc.SetVariableyByName(classObj, "readonlyField", 20);//20
Console.WriteLine(classObj.MyField());
}
this is SetVariableByName():
public static b
ool SetVariableyByName(object obj, string var_name, object value)
{
FieldInfo info = obj.GetType().GetField(var_name, BindingFlags.NonPublic| BindingFlags.Instance);
if (info == null)
return false;
/* ELSE */
info.SetValue(obj, value);
return true;
}
the only thing is that readonlyField is public not private. I know that you can edit a private field, but am not sure why its not working for me!
In below example, i defined number field. This field will work as i wanted but it is not enough efficient to provide my expectations.
number value is fixed value for each class,number is not dependent instances and number support polymorphism. How can i do that ? Or is there another solution for not use unneccesary number field for instances ?
abstract class Main
{
public int number;
public virtual void dostuff(){
int x = number;
}
}
class Derived:Main
{
public ovverride void dostuff(){
int x = number;
}
}
You could just make the number a property and initialise is in each class constructor:
abstract class Main
{
public int number{get; private set;}
public void dostuff(){
int x = number;
}
}
class Derived:Main
{
public Derived()
{
number = 5; // Specific value for each derived class
}
public void dostuff(){
int x = number;
}
}
Looks like I got the wrong end of the stick -- you want to be able to set it statically per class type, which has already been answered.
You could make the property static and then add it to each class:
abstract class Main
{
public static int number;
public virtual void dostuff(){
int x = Main.number;
}
}
class Derived : Main
{
public static int number;
public overide void dostuff(){
int x = Derived.number;
}
}
Edit: I am a bit confused by your comments about polymorhism so i have added some more examples.
Main obj = new Derived();
obj.doStuff(); //This will use Derived.number; as doStuff is and overidden virtual method.
However if you do the following:
abstract class Main
{
public static int number;
public void dostuff(){
int x = Main.number;
}
}
class Derived : Main
{
public static int number;
public new void dostuff(){
int x = Derived.number;
}
}
Then you get different behaviour as below:
Main obj = new Derived();
obj.doStuff() // Will use Main.number
Derived obj2 = (Derived)obj;
obj2.doStuff() // Will use Derived.number
If you want some other kind of behaviour i havn't defined here please exaplin because i do not understand what you want.
actually i refactor some portion of code.
what i want to do is to initialize an object "Task" with an object "TaskArgument".
let s say "TaskArgument" is abstract and "Task" implements a method "OnEnterTask(TaskArgument args)" and is sealed (for some special behavior of the existing system, which is out of scope).
old code:
public sealed class Task : SomeSystemBaseTask {
private int accessMe;
private int meToo;
public void OnEnterTask(TaskArgument args) {
if (args is SimpleTaskArgument) {
accessMe = ((SimpleTaskArgument)args).uGotIt;
meeToo = 0;
} else if (args is ComplexTaskArgument) {
accessMe = ((ComplexTaskArgument)args).uGotItValue * ((ComplexTaskArgument)args).multiplier;
meToo = ((ComplexTaskArgument)args).multiplier - 1;
}
}
}
what would be the best practise avoid the typecheck?
my first stupud thought was:
public abstract class TaskArgument {
internal public abstract Initialize(Task args);
}
public class SimpleTaskArgument : TaskArgument {
public int uGotIt = 10;
internal public Initialize(Task task){
task.accessMe = uGotIt;
}
}
public class ComplexTaskArgument : TaskArgument {
public int uGotItValue = 10;
public int multiplier = 10;
internal public Initialize(Task task){
task.accessMe = uGotItValue*multiplier;
task.meToo = multiplier - 1;
}
}
public sealed class Task : SomeSystemBaseTask {
public int accessMe;
public int meToo;
public void OnEnterTask(TaskArgument args){
args.Initialize(this);
}
}
but then my "accessMe" is public and the "Initialize" method works only with "Task".
so i moved the typechecking to another place (in future).
is there any best practise or good design idea.
..."internal public"... mmhhmm?
another crazy idea was an inner class, but i dont like those and it make such a simple case more complex or don't:
public abstract class TaskArgument {
internal public abstract Initialize(ITaskWrapper wrapper);
}
public class SimpleTaskArgument : TaskArgument {
...
}
public class ComplexTaskArgument : TaskArgument {
...
}
public interface ITaskWrapper {
public int AccessIt { set; get; }
...
}
public sealed class Task : SomeSystemBaseTask {
private int accessMe;
...
class TaskWrapper : ITaskWrapper {
...
}
public void OnEnterTask(TaskArgument args){
args.Initialize(new TaskWrapper(this));
}
}
where is the best place for initialization when it is based on the given Type of the "TaskArgument"?
kindly excuse my bad english knowledge
greetings
mo
Use an interface.
public void OnEnterTask(TaskArgument args) {
if (args is SimpleTaskArgument) {
accessMe = ((SimpleTaskArgument)args).uGotIt;
} else if (args is ComplexTaskArgument) {
accessMe = ((ComplexTaskArgument)args).uGotItValue * ((ComplexTaskArgument)args).multiplier;
}
}
becomes
public void OnEnterTask(ITaskArgument args) {
accessMe = args.GetAccessMe();
}
Then you have your classes implement ITaskArgument and implement the method for each class. In general, when you're doing something like this:
accessMe = ((ComplexTaskArgument)args).uGotItValue * ((ComplexTaskArgument)args).multiplier;
where you're accessing multiple properties on an object to perform a calculation, it usually makes sense to push that logic into the class itself.
Sounds like you want to put the logic associated with each sub-class of TaskArgument onto that class. You could add an abstract method to TaskArgument called Calculate that has the sub-class specific calculation. That would remove the need for your if statements completely:
public class Task {
private int accessMe;
public void OnEnterTask(TaskArgument args)
{
accessMe = args.Calculate();
}
}
You would then put the multiplication or whatever is appropriate into each sub-class.
I would create a public interface, which only exposes the Intialize method. Do your calculations in your derived classes e.g.
public interface ITaskArgument
{
void Initialize(Task task);
}
public abstract class TaskArgument : ITaskArgument
{
protected int _value;
public class TaskArgument(int value)
{
_value = value;
}
public abstract void Initialize(Task task);
}
public class SimpleTaskArgument : TaskArgument, ITaskArgument
{
public SimpleTaskArgument(int value)
: base (value)
{
}
public override void Initialize(Task task)
{
task.AccessMe = _value;
}
}
public class ComplexTaskArgument : TaskArgument, ITaskArgument
{
private int _multiplier;
public ComplexTaskArgument(int value, int multiplier)
: base (value)
{
_multiplier = multiplier;
}
public override void Initialize(Task task)
{
task.AccessMe = _value * _multiplier;
}
}
public class Task
{
public Task()
{
}
public int AccessMe { get; set; }
public void OnEnterTask(ITaskArgument args)
{
args.Initialize(this);
}
}
example
SimpleTaskArgument simpleArgs = new SimpleTaskArgument(10);
ComplexTaskArgument complexArgs = new ComplexTaskArgument(10, 3);
Task task = new Task();
task.OnEnterTask(simpleArgs);
Console.WriteLine(task.AccessMe); // would display 10
task.OnEnterTask(complexArgs);
Console.WriteLine(task.AccessMe); // would display 30
OK, changed my answer a bit in light of the changing requirements appearing in the comments! (Sheesh, scope creep or what?!)
public class Task
{
public int Variable1 { get; internal set; }
public int Variable2 { get; internal set; }
public void OnEnterTask(ITaskInitializer initializer)
{
initializer.Initialize(this);
}
}
public interface ITaskInitializer
{
void Initialize(Task task);
}
public class SimpleTaskInitializer : ITaskInitializer
{
private int uGotIt = 10;
public void Initialize(Task task)
{
task.Variable1 = uGotIt;
}
}
public class ComplexTaskInitializer : ITaskInitializer
{
private int uGotIt = 10;
private int multiplier = 10;
public void Initialize(Task task)
{
task.Variable1 = uGotIt;
task.Variable2 = uGotIt * multiplier;
// etc - initialize task however required.
}
}
You could create overloads of Task as one option:
public class SimpleTask : Task
{
public override void EnterTask(TaskArgument arg)
{
var s = (SimpleTaskArgument)arg;
}
}
So each task type deals with an equivalent argument type. Or, you can move the logic to a TaskFactory with a static method that returns an int, and has the type checking argument there.
public static class TaskFactory
{
public static int GetVal(TaskArgument arg)
{
if (args is SimpleTaskArgument) {
return ((SimpleTaskArgument)args).uGotIt;
} else if (args is ComplexTaskArgument) {
return ((ComplexTaskArgument)args).uGotItValue * ((ComplexTaskArgument)args).multiplier;
}
}
}
Your interface implementation also would work; I wouldn't discount that... or define an abstract method within Taskargument, that each overrides to return the value.
HTH.