I'm quite new to C#, and I'm using it for coding a game on Unity. I have a file named GameTools.cs that helps me with commands so that I don't have to do too much. It basically makes my code simpler and shorter. Now with the code...
//GameTools.cs
public void DoSomething() {
//some code
//some more code
}
And inside my file IntroBehavior.cs has the same void as shown above.
//IntroBehavior.cs
void Start() {
DoSomething(); //command shown above
}
Will this work? Do I have to specify something inside IntroBehavior that will be able to run code from GameTools?
in c# all functions belong to classes. They are either instance methods, or static
Instance methods operate in instances of the class
public class User{
void Login(); <<< === instance method
}
used like this
var u1 = new User();
u1.Login();
Static methods dont operate on instances of classes
public class User{
static User CreateUser(); <<<<<= static
Login(); <<< === instance method
}
Here you use them like this
var u2 = User.CreateUser();
See that you can mix the 2. If you only want static methods in a class (to be sure ) then do
public static class User{
static CreateUser(); <<<<<= static
//Login(); <<< not allowed
}
So you want
static public class GameTools{
public static void CallSomething() {
//some code
//some more code
}
}
Now in you other file
void Start() {
GameTools.CallSomething(); //command shown above
}
Of course that method has to be in a class too.
Related
I am making a program where the objects need to chat with eachother and give orders. I'm somewhat new to C# and so I'm having trouble doing this properly. I have realized that using a static class I could achieve all I want to achieve. I understand that this is a bad approach for some reasons. I understand that I should be using dependency injection perhaps? Unfortunately I'm having trouble quite grasping how to realize that.
Below, I have created an example of what I mean by static objects that has all the "aspects" of what my program will be doing. If you feel like helping me in understanding dependency injection and it's not too much work, then you could try change my example to use dependency injection instead (and if you do, I would be very happy, as it would help me learn something I'm having trouble with)
class Program
{
static void Main(string[] args)
{
Global.worker = new Worker();
Global.employer = new Employer();
Global.reporter = new Reporter();
Global.worker.JobDone += Global.reporter.onWorkDoneR;
Global.worker.JobDone += Global.employer.onWorkDoneE;
Global.reporter.msgToUser("Initialization successful!!!");
Global.employer.startWorkDay();
Console.ReadLine();
}
}
static class Global
{
static public Worker worker;
static public Employer employer;
static public Reporter reporter;
}
class Worker
{
public delegate void EventHandler(object sender, ReporterArgs args);
public event EventHandler JobDone;
public void doJob(int joblength)
{
Global.reporter.msgToUser("Worker reporting that I'm starting work!!!");
System.Threading.Thread.Sleep(joblength*1000);
JobDone?.Invoke(this, new ReporterArgs("Work is done"));
}
}
class Employer
{
private int jobiteration = 1;
public void startWorkDay()
{
Global.worker.doJob(jobiteration);
}
public void onWorkDoneE(object sender, EventArgs args)
{
jobiteration++;
Global.worker.doJob(jobiteration);
}
}
class Reporter
{
public void msgToUser(string message)
{
Console.WriteLine(message);
}
public void onWorkDoneR(object sender, ReporterArgs args)
{
Console.WriteLine("{0} reporting: {1}", sender, args.Str);
}
}
public class ReporterArgs : EventArgs
{
private readonly string str;
public ReporterArgs(string str2lol)
{
this.str = str2lol;
}
public string Str
{
get { return this.str; }
}
}
First off, you should definitely read more references about classes in C#.
Looking at the code, the first thing I see is the way Employer class approaches the Worker.
public void startWorkDay()
{
Global.worker.doJob(jobiteration);
}
Instead of accessing a static worker object, you can treat any Worker object independently with this piece of code:
public void startWorkDay(Worker workerObjectToPerformTheJob)
{
workerObjectToPerformTheJob.doJob(jobiteration);
}
Also that is not how we write in C#:
static public Worker worker;
static public Employer employer;
static public Reporter reporter;
The correct way is: public static Foo bar;
About classes and objects:
Your program runs in the scope of static void Main(string[] args) {//stuff happens here} So when a object defined in the boundaries of Main() wants to access another object from the same scope, there is no need to define a second static class.
Now on the other hand, what if there was more classes or scopes? How can we connect them, so they can reliably access one another? Here we have two classes, foo and bar. Foo needs to hand a string variable to bar.
class foo{ string myString; }
class bar
{
void myMethod(string value)
{ print(value); }
}
Foo and Bar are in two different scopes, so in order to pass myString to myMethod(), we can implement a bridge between them.
static class Bridge
{
public static string passThis;
}
In scope 1 (maybe this was an event that was raised before a bar object was created) a Foo object gets created. This Foo object passes myString to
variable Bridge.passThis.
In scope 2 a Bar object gets created. Bar cannot access the Foo object, so we can't access objectFoo.myString. Instead we access Bridge.passThis and execute myMethod(Bridge.passThis);
I am currently trying to separate out the method implementation so that they can work independently. The methods that I am trying to separate are store and checker. Both these methods require the traverse method. My current implementation has two method store and checker methods which I have separated them into different classes. They require to be called within the traverse method to work. This is the my current implementation.
class Traverse
{
public void traversemethod()
{
Console.WriteLine("Traverse function");
Checker r = new Checker();
r.checkermethod();
Store s = new Store();
s.storemethod();
}
}
class Checker
{
public void checkermethod()
{
Console.WriteLine("Checker function");
}
}
class Store
{
public void storemethod()
{
Console.WriteLine("Store function");
}
}
class Compute
{
public static void Main()
{
Console.WriteLine("Main function");
Traverse v = new Traverse();
v.traversemethod();
Console.ReadLine();
}
Is there any way by which I can implement them separately without declaring them together in traverse method and calling both store and checker method separately in the main function. I can implement the traverse method in both store and checker method, but i was wondering if there is any way to do it rather than duplicating the same code again.
Sounds like a perfect place to use a lambda:
public delegate void TraverseDelegate();
public void traversemethod(TraverseDelegate dlg){
Console.WriteLine("Traverse function");
dlg();
}
and in the Main method use:
Traverse v = new Traverse();
v.traversemethod(() => {
Checker r = new Checker();
r.checkermethod();
Store s = new Store();
s.storemethod();
});
EDIT/UPDATE(=UPDIT :-) )
You can also make the delegate a member field of Traverse, and then pass it as a constructor argument and call traversemethod without any arguments:
public class Traverse{
public delegate void TraverseDelegate();
private TraverseDelegate dlg;
public Traverse(TraverseDelegate dlg){
this.dlg=dlg;
}
public void traversemethod(){
Console.WriteLine("Traverse function");
dlg();
}
}
and in the Main method use:
Traverse v=new Traverse(()=>{
Checker r = new Checker();
r.checkermethod();
Store s = new Store();
s.storemethod();
});
v.traversemethod();
I'm not about the relationship between Checker and Store so I'll show an example with an interface instead of a base class. However you could create a base class, possibly abstract, and have each child class implement their special method.
interface IPerformMethod
{
void SpecialFunction();
}
public class Store : IPerformMethod
{
public void SpecialFunction()
{
Console.WriteLine("Store function");
}
}
public class Checker : IPerformMethod
{
public void SpecialFunction()
{
Console.WriteLine("Checker function");
}
}
Then in your TraverseMethod, you could pass in an object that implements IPerformMethod (in this case it's either an instance of Checker or Store).
public void TraverseMethod(IPerformMethod item)
{
Console.WriteLine("Traverse function");
item.SpecialFunction();
}
//To call the method
TraverseMethod(new Checker());
TraverseMethod(new Store());
(Obviously you can rename the IPerformMethod interface to something more descriptive but if I understand the question correctly, this seems to be what you want).
This is a simple program I created - one table class, one main class. In the table class I created a print method which simply outputs my name. From the main class I am calling the print method but not getting the output.
namespace ConsoleApplication3
{
class table
{
public static void print()
{
Console.WriteLine("My name is prithvi-raj chouhan");
}
}
class Program
{
public static void Main()
{
table t = new table();
t.print(); // Error the program is not giving output while calling the print method
}
}
}
Since the function you are calling is static.
Use this syntax
public static void Main()
{
table.print();
}
Quote from MSDN:-
A static method, field, property, or event is callable on a class even
when no instance of the class has been created. If any instances of
the class are created, they cannot be used to access the static
member. Only one copy of static fields and events exists, and static
methods and properties can only access static fields and static
events. Static members are often used to represent data or
calculations that do not change in response to object state; for
instance, a math library might contain static methods for calculating
sine and cosine.
print is a static method, so call it as a static method:
public static void Main()
{
table.print();
}
try this:
class Program
{
public static void Main()
{
table.Print();
}
}
Print(); is a static method so you dont need to instantiate a new Table object in order to access it's methods
You are calling print() as an instance method but it is static. Try to remove the static keyword from the method.
Try to add a Console.ReadLine(); after table.print();.
UPDATE:
Missed the part with static, now corrected.
Going from Java to C# I have the following question:
In java I could do the following:
public class Application {
static int attribute;
static {
attribute = 5;
}
// ... rest of code
}
I know I can initialize this from the constructor but this does not fit my needs (I want to initialize and call some utility functions without create the object).
Does C# support this? If yes, how can I get this done?
Thanks in advance,
public class Application
{
static int attribute;
static Application()
{
attribute = 5;
} // removed
}
You can use the C# equivalent static constructors. Please don't confuse it with a regular constructor. A regular constructor doesn't have a static modifier in front of it.
I am assuming your //... rest of the code need to be also run once. If you don't have such code you can just simply do this.
public class Application
{
static int attribute = 5;
}
You just can write a static constructor block like this,
static Application(){
attribute=5;
}
This is what I could think of.
In your particular scenario, you could do the following:
public class Application {
static int attribute = 5;
// ... rest of code
}
UPDATE:
It sounds like you want to call a static method. You can do that as follows:
public static class Application {
static int attribute = 5;
public static int UtilityMethod(int x) {
return x + attribute;
}
}
I find something else useful. If your variable needs more than one expressions/statements to initialize, use this!
static A a = new Func<A>(() => {
// do it here
return new A();
})();
This approach is not limited on classes.
-A static constructor doesn't have any parameter.
-A static class can contain only one static constructor.
-A static constructor executes first when we run the program.
Example:
namespace InterviewPreparation
{
public static class Program
{ //static Class
static Program()
{ //Static constructor
Console.WriteLine("This is static consturctor.");
}
public static void Main()
{ //static main method
Console.WriteLine("This is main function.");
Console.ReadKey();
}
}
}
Output:
This is static constructor.
This is main function.
I am trying to use a method inside class, from another class.
namespace Crystal.Utilities
{
public class Logging
{
public static void Log()
{
//dostuff
Crystal.MainForm.general_log_add_item("Hello World");
}
}
}
namespace Crystal
{
public partial class MainForm : Form
{
public void general_log_add_item(string msg)
{
listBox1.Items.Add(msg);
}
}
}
I want to be able to call Crystal.Utilities.Logging.Log() from anywhere, and that to be able to call Crystal.MainForm.general_log_add_item() . But It doesn't let me, because if I put it as public, then I can't see it, if it's static then It can't interact with my listbox.
This is a wrong approach. Your class should not call into the UI, as the UI could change. The class should not know nor care about the UI. Instead, the class could expose an event that the form could subscribe to, and update based upon the information contained within the event's arguments.
Here's a hastily thrown together example.
class Program
{
static void Main()
{
Logger.OnLogging += Logger_OnLogging;
Logger.Log();
Logger.OnLogging -= Logger_OnLogging;
}
static void Logger_OnLogging(LoggingEventArgs e)
{
Trace.WriteLine(e.Message);
}
}
public class Logger
{
public delegate void LoggingEventHandler(LoggingEventArgs e);
public static event LoggingEventHandler OnLogging;
public static void Log()
{
// do stuff
RaiseLoggingEvent("Data logged");
}
protected static void RaiseLoggingEvent(string message)
{
if (OnLogging != null)
OnLogging(new LoggingEventArgs(message));
}
}
public class LoggingEventArgs : EventArgs
{
public LoggingEventArgs(string message)
{
this.Message = message;
}
public string Message { get; private set; }
}
Instead of implementing it as a static method, try implementing as a singleton. It's a common trick to make an instance global in scope, and restrict to one instance, without making everything static (and thus unable to be used as an instance).
You have to understand that the window is not static, there is one instance of him, thats why the method cant be static,
you can use
Application.Windows to reach this instance and call the add method.
or you can register the window in his constructor on another class that will mediate the Logging and the window.
If you don't understand tell me and I'll try to be more clear
When you declare a method as "static" you're saying that it's not dependent upon a specific instance of the class it's in.
For example if you have a class named "chair" and you want to count how many chairs there are, you'll do that with a static field, and a static method to return that field's value.
The count of all chairs is not related to a specific chair.
In your case you want to add a static method to add an item to a specific instance of a Form. That's impossible and doesn't make sense.
If you want to add an item to a listBox, it must be through a public method.
So basically what I'm saying is - rethink what you're trying to do, there's a good explanation as to why you're not succeeding in doing that.