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();
}
}
Related
I have some code that is using a third-party library that I can't bypass. This library provides some auxiliary features that I need. At this time, my code is setup like this:
static Engine engine = new Engine();
static void Main(string[] args)
{
engine.Execute(MyCode);
}
private static void MyCode()
{
// my code goes here
}
Here's my challenge: I have to instantiate some code before MyCode can use it because that instantiation must hit a database and takes longer than the threshold allowed by Engine. I can't use a static variable because multiple instances will be necessary. Which basically means, I want something like this:
static Engine engine = new Engine();
static void Main(string[] args)
{
MyClass c = new MyClass();
c.Initialize(); // This is the db call
engine.Execute(MyCode); // This line is the problem
}
private static void MyCode(MyClass c)
{
// my code goes here
c.DoStuff();
}
My problem is, I basically need to create an overloaded method that takes a parameter. However, the Execute method in the third-party library doesn't let me do that. Is there some C# syntactial way I can do this that I'm missing?
You're looking for lambda expressions:
engine.Execute(() => MyCode(c));
I'm assuming that Engine.Execute takes an instance of Action.
You could make the MyCode function an instance member function on MyClass, then pass MyClass.MyCode to Engine.Execute as an Action.
public class Engine
{
public void Execute(Action action)
{
action.Invoke();
}
}
public class MyClass
{
public void Initialize()
{
System.Threading.Thread.Sleep(500); //Simulate some work.
}
public void Run()
{
// I've renamed it from MyCode to Run, but this method is essentially your
// my code method.
Console.WriteLine($"I'm being run from the engine! My Id is {_id}.");
}
private readonly Guid _id = Guid.NewGuid();
}
public static class Program
{
static void Main(string[] args)
{
var engine = new Engine();
var c = new MyClass();
c.Initialize();
engine.Execute(c.Run);
}
}
Let's assume we have the following two classes, How can we listen for Errors and if any error occurred, recreate the singleton? I have put together the following code, but would like to know if there is a pattern for safely raise error, dispose object and recreate it automatically?
`
static void Main(string[] args)
{
MyFirstClass.Instance.SayHello();
}
}
class MySecondClass
{
public int ID { get; set; }
public void SayHelloFromSecondClass()
{
Console.WriteLine("Say Hello From Second Class");
}
public MySecondClass(int id)
{
ID = id;
}
}
public sealed class MyFirstClass
{
private static readonly MyFirstClass instance = new MyFirstClass();
private static MySecondClass msc;
public event EventHandler ErrorOccuredEvent;
private MyFirstClass() { }
public static MyFirstClass Instance
{
get
{
msc = new MySecondClass(id: 1);
return instance;
}
}
public void SayHello()
{
Console.WriteLine("Hello World...");
}
static void ErrorOccured(object sender, EventArgs e)
{
Console.WriteLine("Oops");
msc = null;
Thread.Sleep(5000);
GC.Collect();
msc = new MySecondClass(id: 2);
}
}
`
If I understand well, MyFirstClass (which is a singleton) is a kind of wrapper around MySecondClass that turns MySecondClass into a singleton as well.
Let's call MyFirstClass: Wrapper
Let's call MySecondClass: Service
If the clients always consume the Service through the single instance of Wrapper, then re-creating a Wrapper will not help, because the clients might keep a reference to Wapper. Re-creating Service can help if the clients don't see it and cannot keep a reference to it. Therefore they must consume the service indirectly.
It's easiest to achieve this through an interface:
public interface IHelloService
{
void SayHello();
}
public class HelloService : IHelloService
{
public void SayHello()
{
Console.WriteLine("Hello");
}
}
public class HelloServiceWrapper : IHelloService
{
public static readonly IHelloService Instance = new HelloServiceWrapper();
private HelloServiceWrapper () {}
private IHelloService _service;
public void SayHello()
{
EnsureServiceAvailable();
_service.SayHello();
}
private void EnsureServiceAvailable()
{
if(_service == null) {
_service = new HelloService();
}
}
private void HandleError()
{
_service = null;
}
}
But if the error happens when the client is using the service ...
HelloServiceWrapper.Instace.SayHello();
... this call might fail.
You would have to re-create the service instantly in order to make succeed the client's call (assuming that re-creating the service will solve the problem and that the error will not occur again immediately):
public void SayHello()
{
try {
_service.SayHello();
} catch {
_service = new HelloService();
_service.SayHello();
}
}
Note: Disposing the service invalidates the object and makes any reference a client has to it invalid. But re-creating a new one does not give the client a new reference! You would need to have a reference to the clients reference in order to be able to give the client a new instance.
I have a method A which call another method B. Upon clicking on a button, method A is called which in turn calls method B. However, when 2 users click on the button simultaneously, I want only one user to access method B while the other waits for method B to complete. I thought of doing it this way:
private static Object _Lock = new Object();
private void A(){
lock(_Lock){
B();
}
}
The users are on different machines. The project is a web site.
But I think this is not correct. How can I improve the above code so that it is the proper way to work?
I agree with #Torestergaard, you should keep the lock as slim as possible. Therefor if taking the code sample provided above by #Rebornx and modifying it a bit you can use something like below example:
public class Program
{
public static void Main()
{
LockSample lockSampleInstance = LockSample.GetInstance();
lockSampleInstance.MethodA();
}
}
public class LockSample
{
private static readonly LockSample INSTANCE = new LockSample();
private static Object lockObject = new Object();
public static LockSample GetInstance()
{
return INSTANCE;
}
public void MethodA()
{
Console.WriteLine("MethodA Called");
MethodB();
}
private void MethodB()
{
lock(lockObject)
{
Console.WriteLine("MethodB Called");
}
}
}
Hope it will help,
Liron
Here is a simple program, I used single ton pattern. You can achieve the locking by using "Monitor" also.
public class Program
{
public static void Main()
{
LockSample lockObject = LockSample.GetInstance();
lock(lockObject)
{
lockObject.MethodA();
}
}
}
public class LockSample
{
private static LockSample _Lock;
public static LockSample GetInstance()
{
if(_Lock == null)
{
_Lock = new LockSample();
}
return _Lock;
}
public void MethodA()
{
Console.WriteLine("MethodA Called");
MethodB();
}
private void MethodB()
{
Console.WriteLine("MethodB Called");
}
}
Generally you should keep you lock as slim as possible, so dependent on what you do then it might make sense to move the lock statement into method B only guarding the resource that doesn't support multiple parallel users.
But generally there is nothing wrong with your example.
You can declare the method B with this attribute:
[MethodImpl(MethodImplOptions.Synchronized)]
public void B() {
...
}
I'm fairly new to object oriented programming and I still have trouble organizing my programs.
I'm making a simulation of a factory in c#. I have one instance of a Simulation class. When initialized, the constructor creates several instances of a Machine class.
The Simulation class has an event list. The Machine class has methods that need to add events to this list. Right now, the only way I see how to do this is to pass a reference of the simulation to the Machine constructor. However, these seems messy to me and I feel like there has got to be a better way of organizing this.
public class Simulation
{
public LinkedList<Event> event_list = new LinkedList<Event>();
public Simulation()
{
Machine m1 = new Machine(this);
Machine m2 = new Machine(this);
}
static void Main(string args[])
{
Simulation sim = new Simulation();
}
}
public class Machine
{
public Simulation sim;
public Machine(Simulation sim)
{
this.sim = sim;
}
public void Schedule_Event()
{
sim.event_list.AddLast(new Event(etc etc));
}
}
public class Event
{
}
Is there a way to add events to Simulation.event_list without having to pass the this reference? In a sense each Machine "belongs" to the Simulation class, and I want to show this somehow.
You can have a method in Machine that returns Event objects, then Simulation can take care of adding it to event_list:
public class Simulation
{
public LinkedList<Event> event_list = new LinkedList<Event>();
public Simulation()
{
Machine m1 = new Machine();
Machine m2 = new Machine();
event_list.AddLast(m1.GetEvent());
event_list.AddLast(m2.GetEvent());
}
static void Main(string args[])
{
Simulation sim = new Simulation();
}
}
public class Machine
{
public Machine() {}
public Event GetEvent()
{
return new Event(etc etc);
}
}
seems pretty much ok to me, I'd just hide the event_list implementation in the Simulation class:
public class Simulation
{
private LinkedList<Event> event_list = new LinkedList<Event>();
public void addEven(Event x) {event_list.Add(x); }
}
passing this in constructor is ok, if you really want to you can put a factory method in simulation:
public class Simulation
{
public Machine CreateNewMachine() { return new Machine(this); }
}
to just allow Machine m1 = Simulation.CreateNewMachine()
You could use a more Observer-pattern type approach, using Action<T>
Add a public action to Machine:
public class Machine
{
public Action<Event> EventAdded;
private void Schedule_Event()
{
if(EventAdded != null)
EventAdded(new Event());
}
}
And Subscribe to the action upon creation:
public class Simulation
{
public LinkedList<Event> event_list = new LinkedList<Event>();
public Simulation()
{
Machine m1 = new Machine() { EventAdded = AddEvent };
}
static void Main(string[] args)
{
Simulation sim = new Simulation();
}
public void AddEvent(Event e)
{
event_list.AddLast(new Event(etc etc));
}
}
Then, the only contract you have between your two objects is the Event type.
Is it by any chance possible to call a method without referencing to its class?
For instance, you have a helper class:
class HelperTools
{
public static void DoWork()
{ /*...*/ }
}
And then you need to call it:
class MainClass
{
public static void Main()
{
HelperTools.DoWork();
}
}
Is it possible to call DoWork(); without a reference? Like this:
public static void Main()
{
DoWork();
}
Just for sake of simplicity.
Not quite, but here are 5 patterns that get you close:
namespace My.Namespace
{
using H = MyHelperClass;
public class MyHelperClass
{
public static void HelperFunc1()
{
Console.WriteLine("Here's your help!");
}
}
public class MyHelperClass2
{
public static void HelperFunc4()
{
Console.WriteLine("Here's your help!");
}
}
public interface IHelper{ }
public static class HelperExtensions
{
public static void HelperFunc3(this IHelper self)
{
Console.WriteLine("Here's your help!");
}
}
public class MyClass : MyHelperClass2, IHelper
{
private static readonly Action HelperFunc2 = MyHelperClass.HelperFunc1;
private static void HelperFunc5()
{
Console.WriteLine("Here's your help!");
}
public void MyFunction()
{
//Method 1 use an alias to make your helper class name shorter
H.HelperFunc1();
//Method 2 use a class property
HelperFunc2();
//Method 3 extend an interface that has extension methods.
//Note: you'll have to use the this keyword when calling extension
this.HelperFunc3();
//Method 4 you have access to methods on classes that you extend.
HelperFunc4();
//Method 5 put the helper method in your class
HelperFunc5();
}
}
}
No. Java has the concept of importing static like this, but C# does not. (IMO, a naked DoWork() without any clue as to where the implementation resides is non-ideal.)
a few years late but maybe this will help someone else...
Use a using static directive to reference the static class: (introduced in C# 6)
using static HelperTools;
class MainClass
{
public static void Main()
{
DoWork();
}
}
---------------- HelperTools.cs--------------------
class HelperTools
{
public static void DoWork()
{ /*...*/ }
}
The only place you can call DoWork from without referencing the class name is within the class itself. For instance, if you add a non-static method to HelperTools:
public void foo()
{
DoWork();
}
You can call DoWork from within it, even though foo() is not static.