C# Calling a Method Inside another Method - c#

public static void Main2(string[] args)
{
WebRequest_BeginGetRequeststream.RequestCheck();
WebRequest_BeginGetRequeststream.ReadCallback(IAsyncResult asynchronousResult);
}
This is the Method I want to call.
static void OnMsg(SteamFriends.FriendMsgCallback callback)
{
string msg = callback.Message;
//Announcement Related Messages
if (msg == "RequestCheck")
{
Main2 (string[] args);
Console.WriteLine("Starting Operation Line for Announcement Creation.");
Console.WriteLine("Version 1.08 of Announcement Code Initiated.");
}
}
This is where I want to call the method, I had everything else set but I wanted to make it so that inside the...
if (msg == "RequestCheck")
{
Main2 (string[] args);
Console.WriteLine("Starting Operation Line for Announcement Creation.");
Console.WriteLine("Version 1.08 of Announcement Code Initiated.");
}
It can call Main2 which will run the WebRequests, It tells me that I need to make a return type and when I do that, I get a whole bunch of errors.
How can I call inside Method OnMsg and call Main2 without disrupting the Method.
by the way, to get to where I am now. I had been following this code.
public class AllMethods
{
public static void Method2()
{
// code here
}
}
class Caller
{
public static void Main(string[] args)
{
AllMethods.Method2();
}
}
I had seen that this method had works and tried to try it our but I still have problems calling inside OnMsg.

Write Main2 (args); instead, where args is a string[], for example new string[]{"foo", "bar"} or null. Alternativly, you can implicitly pass specified arguments to the call as an array if you add params to the main methods argument args: public static void Main2(params string[] args) { ... }

you need to pass the parameters to the Main2 function, in this case an array of strings.

Related

Can I have two entry points in C#

Would it be possible to use two entry points in C# instead of just having the one. For example when I have this:
using System;
namespace learning
{
class cool
{
static void Main(string[] args)
{
}
}
}
Would it be possible to have another entry point such as secondary that the program executes once the main entry point has finished.
You may want to do something like this:
class Program {
public static void EntryPoint1(string[] args) {
// Code
}
public static void EntryPoint2(string[] args) {
// Code
}
public static void Main(string[] args) {
EntryPoint1(args);
EntryPoint2(args);
}
}
Just make sure to not modify args during EnteryPoint1 or if you want to, clone them like this:
class Program {
public static void EntryPoint1(string[] args) {
// Code
}
public static void EntryPoint2(string[] args) {
// Code
}
public static void Main(string[] args) {
EntryPoint1(args.Clone());
EntryPoint2(args.Clone());
}
}
In C#, you specify the entry point using the /main: compiler option.
Imagine that the code containing containing two main() methods as follow :
namespace Application {
class ClassA {
static void main () {
// Code here
}
}
class ClassB {
static void main () {
// Code here
}
}
To use ClassA.main() as your entry point, you would specify the following when compiling:
csc /main:Application.ClassA hello.cs
You can only have a single entry point, but you can write two separate methods, call the first one, and then the second one. You will achieve what you're describing.
using System;
namespace learning
{
class cool
{
static void Main(string[] args)
{
PartOne();
PartTwo();
}
void PartOne() {
// Something happens here
}
void PartTwo() {
// Something else happens here
}
}
}
Additionally (depending on how the program starts up) you can send in arguments to specify which method you want to execute (if you don't need both of them to execute). Then you can just do an "if/else" statement that will decide which method to run depending on the arguments passed into Main

Pointing a function to another

Suppose I have two functions:
void DoesNothing(){}
void OnlyCalledOnce(){
//lines of code
}
Is it possible to call OnlyCalledOnce and it actually run DoesNothing ? I imagine something like this:
void DoesNothing(){}
void OnlyCalledOnce(){
//lines of code
OnlyCalledOnce = DoesNothing;
}
and after that last line, whenever I called OnlyCalledOnce it would run DoesNothing.
Is it possible?
You can simply return early in OnlyCalledOnce like this: (assuming your DoesNothing example literally does nothing - it isn't needed)
bool initialized = false;
void OnlyCalledOnce()
{
if (initialized) return;
// firsttimecode
initialized = true;
}
The initialized variable will be true after first run.
Did you try to use delegate?
class Program
{
private static Action Call = OnlyCalledOnce;
public static void Main(string[] args)
{
Call();
Call();
Call();
Console.ReadKey();
}
static void DoesNothing()
{
Console.WriteLine("DoesNothing");
}
static void OnlyCalledOnce()
{
Console.WriteLine("OnlyCalledOnce");
Call = DoesNothing;
}
}
Another way you could solve this is to maintain a list of strings that represent the methods that have been called. The strings don't even have to be the method name, they just need to be unique to each method.
Then you can have a helper method called ShouldIRun that takes in the function's unique string and checks to see if it exists in the list. If it does, then the method returns false, and if it doesn't, then the method adds the string to the list and returns true.
The nice thing here is that you don't have to maintain a bunch of state variables, you can use this with as many methods as you want, and the methods themselves don't need any complicated logic - they just ask the helper if they should run or not!
public class Program
{
private static List<string> CalledMethods = new List<string>();
static bool ShouldIRun(string methodName)
{
if (CalledMethods.Contains(methodName)) return false;
CalledMethods.Add(methodName);
return true;
}
// Now this method can use method above to return early (do nothing) if it's already ran
static void OnlyCalledOnce()
{
if (!ShouldIRun("OnlyCalledOnce")) return;
Console.WriteLine("You should only see this once.");
}
// Let's test it out
private static void Main()
{
OnlyCalledOnce();
OnlyCalledOnce();
OnlyCalledOnce();
GetKeyFromUser("\nDone! Press any key to exit...");
}
}
Output
As already stated, you can use this:
private bool isExecuted = false;
void DoesNothing(){}
void OnlyCalledOnce(){
if (!isExecuted)
{
isExecuted = true;
//lines of code
DoesNothing();
}
}
If you have multiple threads etc, you can do a lock(object) ..
What's your problem with this?
void DoesNothing()
{
}
void OnlyCalledOnce()
{
DoesNothing();
}
It will run DoesNothing() once you run OnlyCalledOnce()

What is this type of delegate called(C#)

I have these lines of code.
class Program
{
public delegate void printer();
public static void Method()
{
Console.WriteLine("Hello");
}
static void Main(string[] args)
{
printer del = delegate { Method(); };
del();
Console.ReadKey();
}
}
Now what do i call this statement printer del = delegate { Method(); };.
Surely it cant be called anonymous method because here i have a named method.
It's called an Anonymous method
Surely it can't be called anonymous method because here I have a named method
It's still an anonymous method, as #Daniel pointed out in the comments what your doing is instantiating an instance of the printer delegate by assigning a method with the same signature (which happens to be...an anonymous method). You could avoid using an anonymous method completely by doing:
Printer del = Method;
It's an anonymous delegate who's only function happens to be calling a named method.
It's an anonymous method. The inside of the method does call a named one but that doesn't change the fact that the outher method is anonymous.
You can easily see this when you would expand del:
class Program
{
public delegate void printer();
public static void MethodA()
{
Console.WriteLine("Hello");
}
public static void MethodB()
{
Console.WriteLine("World");
}
static void Main(string[] args)
{
bool x = true;
printer del = delegate
{
if (x)
{
MethodA();
}
else
{
MethodB();
}
};
del();
Console.ReadKey();
}
}
If you don't want to use a delegate you could do the same with an Action:
Action delA = () => MethodA();
delA();
Action points to a void returning method that takes no parameters.
It's an anonymous method, as the others have said.
You could also accomplish the same thing with this code:
Action del = () => Method();
del();
This way, you don't need to define the delegate and use the built-in Action type.

implementing delegates in c#

This would be the first time I'd use delegates in c# so please bear with me. I've read a lot about them but never thought of how/why to use this construct until now.
I have some code that looks like this:
public class DoWork()
{
public MethodWorkA(List<long> TheList) {}
public void MethodWork1(parameters) {}
public void MethodWork2(parameters) {}
}
I call MethodWorkA from a method outside the class and MethodWorkA calls MethodWork 1 and 2. When I call methodA, I'd like to pass some sort of parameter so that sometimes it just does MethodWork1 and sometimes it does both MethodWork1 and MethodWork2.
So when I call the call it looks like this:
DoWork MyClass = new DoWork();
MyClass.MethodA...
Where does the delegate syntax fit in this?
Thanks.
public void MethodWorkA(Action<ParamType1, ParamType2> method) {
method(...);
}
You can call it using method group conversion:
MethodWorkA(someInstance.Method1);
You can also create a multicast delegate that calls two methods:
MethodWorkA(someInstance.Method1 + someInstance.Method2);
For what you described, you don't need delegates.
Just do something like this:
public class DoWork
{
public void MethodWorkA(List<long> theList, bool both)
{
if (both)
{
MethodWork1(1);
MethodWork2(1);
}
else MethodWork1(1);
}
public void MethodWork1(int parameters) { }
public void MethodWork2(int parameters) { }
}
If you're just experimenting with delegates, here goes:
public partial class Form1 : Form
{
Func<string, string> doThis;
public Form1()
{
InitializeComponent();
Shown += Form1_Shown;
}
void Form1_Shown(object sender, EventArgs e)
{
doThis = do1;
Text = doThis("a");
doThis = do2;
Text = doThis("a");
}
string do1(string s)
{
MessageBox.Show(s);
return "1";
}
string do2(string s)
{
MessageBox.Show(s);
return "2";
}
}
Considering that all methods are inside the same class, and you call MethodWorkA function using an instance of the class, I honestly, don't see any reason in using Action<T> or delegate, as is I understood your question.
When I call methodA, I'd like to pass some sort of parameter so that
sometimes it just does MethodWork1 and sometimes it does both
MethodWork1 and MethodWork2.
Why do not just pass a simple parameter to MethodWorkA, like
public class DoWork()
{
public enum ExecutionSequence {CallMethod1, CallMethod2, CallBoth};
public MethodWorkA(List<long> TheList, ExecutionSequence exec)
{
if(exec == ExecutionSequence.CallMethod1)
MethodWork1(..);
else if(exec == ExecutionSequence.CallMethod2)
MethodWork2(..);
else if(exec == ExecutionSequence.Both)
{
MethodWork1(..);
MethodWork2(..);
}
}
public void MethodWork1(parameters) {}
public void MethodWork2(parameters) {}
}
Much simplier and understandable for your class consumer.
If this is not what you want, please explain.
EDIT
Just to give you an idea what you can do:
Example:
public class Executor {
public void MainMethod(long parameter, IEnumerable<Action> functionsToCall) {
foreach(Action action in functionsToCall) {
action();
}
}
}
and in the code
void Main()
{
Executor exec = new Executor();
exec.MainMethod(10, new List<Action>{()=>{Console.WriteLine("Method1");},
()=>{Console.WriteLine("Method2");}
});
}
The output will be
Method1
Method2
In this way you, for example, can push into the collection only functions you want to execute. Sure, in this case, the decision logic (which functions have to be executed) is determined outside of the call.

C# Making a delegate available to a class

I would like to make a delegate available to an entire class. The point of this is to allow a called method from an external class' backgroundWorker to continually report back through all of it's methods (ExternalClass.Run(); calls ExternalClass.Method2(); ExternalClass.Method3(); etc and they all need to send several progress reports. It seems inefficient to have to continually pass the delegate.
I've tried initializing an instance of the delegate globally and setting it to equal the passed instance in Run(); for each method to then have available to it but I am given an error that a null object cannot be implicitly converted.
thanks!
I cannot show the code I am working with as I do not currently have it with me (it's on my laptop) but I will try to better explain now. PSEUDO-CODE:
class form1 : form {
backgroundWorker_doWork()
{
Class2.Run();
}
backgroundWorker_OnProgressChange()
{
// do this
}
}
class class2{
Run(){
OtherMethod();ThirdMethod();
}
OtherMethod(){ //need to call backgroundWorker.ReportProcess(int, string)}
ThirdMethod(){ //need to call backgroundWorker.ReportProcess(int, string)}
}
I really don't want to have to pass it every time is the point, i'd like to somehow pass it to class2
You should show your code that isn't working and the exact error message. It should be fine - here's an example:
using System;
class Demo
{
private readonly Action action;
public Demo(Action action)
{
this.action = action;
}
public void FirstMethod()
{
Console.WriteLine("In first method");
action();
}
public void SecondMethod()
{
Console.WriteLine("In second method");
action();
}
}
class Test
{
static void Main()
{
Demo demo = new Demo(() => Console.WriteLine("Action called"));
demo.FirstMethod();
demo.SecondMethod();
}
}
You can use the InvokeMethod function from a backgroundWorker to allow the worker to execute any delegate, example below (also waits for the invoke to finish, which you may not need):
BackgroundWorker Function (C++.net)
BackgroundWorkerFunction()
{
::IAsyncResult ^ThreadResult;
SetTileCount_Delegate ^SetCountDel = gcnew SetTileCount_Delegate(this, &PartDetail::SetTileCount_Function);
//RecordingContainer is the class I am invoking into
ThreadResult = this->RecordingContainer->BeginInvoke(
SetCountDel, ThisTest->RecordingsCache->Count);
WaitForInvokeTimeOutOrCompletion(ThreadResult);
}
System::Void WaitForInvokeTimeOutOrCompletion(IAsyncResult ^ThreadResult)
{
if(ThreadResult == nullptr) return;
long SleepTotal = 0;
long SleepInterval = 100;
while ((SleepTotal <= 2000) && !ThreadResult->IsCompleted)
{
ThreadResult->AsyncWaitHandle->WaitOne(SleepInterval, false);
SleepTotal += SleepInterval;
}
}

Categories

Resources