I use the code line:
MethodBase senderMethod = MethodBase.GetCurrentMethod();
inside a method to get the information of the method's identity.
I then invoke another method using the senderMethod as argument in the method call:
RefreshLineSelection(_cursorLocation, senderMethod);
In the method RefreshLineSelection I need to check the identity of the calling method, as this method is invoked from two different methods.
I do this thus:
string name = senderMethod.Name;
if (name == "Panel_MouseMove")
{
}
It seems to me that there should be a more elegant way.
I tried:
if (senderMethod == Panel_MouseMove)
{
}
and also:
if (senderMethod.Equals(Panel_MouseMove))
{
}
but I get error messages I do not know how to resolve.
In one sentence, my question is: What is the correct syntax for:
if (senderMethod.Equals(Panel_MouseMove))
{
}
Any help would be greatly appreciated.
Thank you in advance.
Related
I am trying to stub a RestClient to return a specific response for a specific request, which is recognized by checking the end of the URL that is used. This is the code I have come up with:
_clientStub = Substitute.For<IRestClient>();
_responseStub = Substitute.For<IRestResponse>();
_clientStub
.Get(
Arg.Is<IRestRequest>(
request => request.Resource.EndsWith("config.json")
)
)
.Returns(_responseStub);
I receive a NullReferenceException for the Arg.Is<IRestRequest> part and if I try to save it in a variable for reuse like this the variable evaluates to null:
protected static readonly IRestRequest CONFIG_QUERY =
Arg.Is<IRestRequest>(
request => request.Resource.EndsWith("config.json")
);
I was following the second example in the documentation so I am not exactly sure what is going wrong. Any help?
Clarification
For reproducability I created a minimal example:
[Fact]
public void StackOverflowTest()
{
RestSharp.IRestClient clientStub = Substitute.For<RestSharp.IRestClient>();
RestSharp.IRestResponse responseStub = Substitute.For<RestSharp.IRestResponse>();
clientStub
.Get(
Arg.Any<RestSharp.IRestRequest>()
)
.Returns(responseStub);
}
Yes, there are no assertions in this test. I don't even get to them anyways since the last command already throws and NullReferenceException. The interfaces are from RestSharp, but that should not really matter.
Update
To narrow the problem down I created an even simpler example and now it works:
public interface IStackOverflowResponse { };
public interface IStackOverflowRequest { };
public interface IStackOverflowClient
{
IStackOverflowResponse Get(IStackOverflowRequest request);
}
[Fact]
public void StackOverflowTest()
{
IStackOverflowClient clientStub = Substitute.For<IStackOverflowClient>();
IStackOverflowResponse responseStub = Substitute.For<IStackOverflowResponse>();
clientStub
.Get(
Arg.Any<IStackOverflowRequest>()
)
.Returns(responseStub);
}
So now I guess that there is a specific problem with mocking RestSharp.RestClient. I guess the problem lies with mocking/stubbing extension methods as the IRestClient does not have a Get method by itself, but instead there is an extension method for it.
The problem lies with the Get function of IRestClient... as it has none. This is just an extension method in RestClientExtensions. As you can see in the source code it simply calls Execute with Method.GET as parameter. So the correct way to stub
clientStub
.Get(
Arg.Any<RestSharp.IRestRequest>()
)
.Returns(responseStub);
is to do this:
clientStub
.Execute(
Arg.Any<RestSharp.IRestRequest>(),
Method.GET
)
.Returns(responseStub);
Winforms, C#, VS2010.
I have a polling thread that runs for the lifetime of my app.
Occasionally it calls an event on my main form. I've not touched the code for years and it's run successfully but now I need to add an "out" parameter to the list of parameters. I've searched online but all the threads I've found have been regarding reflection and been complex to attempt to convert to my context. Mine doesn't use reflection.
Can somebody help over how to fix this pls? On the reflection threads I read people seem to check some object array for the out parameter result, which I don't use in my code, and I wouldn't know where to get it anyway.
private bool OnNeedUpdateCreateEvent(string title, string message,
bool creatingNew, out string newPlanName)
{
newPlanName = "";
// 1st pass through this function.
// Check to see if this is being called from another thread rather
// than the main thread. If so then invoke is required
if (InvokeRequired)
{
// Invoke and recall this method.
return (bool)Invoke(new onNeedToUpdatePlanEvent(OnNeedUpdateCreateEvent),
title, message, creatingNew, out newPlanName); <- wrong out param
}
else
{
// 2nd pass through this function due to invoke, or invoke not required
return InputDlg(this, title, message, creatingNew, out newPlanName);
}
}
It is much like you already know, you just haven't found the array yet. It is automatically created by the compiler. The signature of the Invoke method is:
public object Invoke(
Delegate method,
params object[] args
)
It is the params keyword that gets the compiler to auto-create the array. Nice syntax sugar, but it doesn't help you here. You just have to do it yourself, like this:
if (!creatingNew) {
// Invoke and recall this method.
object[] args = new object[] { title, message, creatingNew, null };
var retval = (bool)Invoke(new onNeedToUpdatePlanEvent(OnNeedUpdateCreateEvent), args);
newPlanName = (string)args[3];
return retval;
}
// etc..
I can use HasProperty to check if a property exists. Only if the property exists a method should be executed.
How can the compiler successfully compile even if the property doesn't exist? E.g.
if (UIApplication.SharedApplication.Delegate.HasProperty("Instance"))
{
AppDelegate customAppDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;
customAppDelegate.Instance.SomeMethod(true); // can't be compiled because Instance doesn't exist
}
The thing is this: First, I check if the propery exists. If yes I execute my method. So normally the code is never executed (except the property exists), but the compiler isn't able to differentiate this. It only checks if the property exists and doesn't take the if clause into account.
Is there a solution for this?
You have to include the reference to Microsoft.CSharp to get this working and you need using System.Reflection;. This is my solution:
if(UIApplication.SharedApplication.Delegate.HasMethod("SomeMethod"))
{
MethodInfo someMethodInfo = UIApplication.SharedApplication.Delegate.GetType().GetMethod("SomeMethod");
// calling SomeMethod with true as parameter on AppDelegate
someMethodInfo.Invoke(UIApplication.SharedApplication.Delegate, new object[] { true });
}
Here is the code behind HasMethod:
public static bool HasMethod(this object objectToCheck, string methodName)
{
var type = objectToCheck.GetType();
return type.GetMethod(methodName) != null;
}
Thanks to DavidG for helping me out with this.
Hey i was wondering if i can convert an Expression to an Action.
I need to use the Expression to get the details of the lambda expression and at the same time i need to execute it using a different method. I need to get the Expression and the actual action with just using a single parameter (either Action or Expression):
BTW i need this for Getting details on what kind of assert i did. ex(Assert.true, Assert.False)
public void otherMethod()
{
SomeMethod(() => Assert.Equals("Dog","Cat"));
}
public void SomeMethod(Expression<Action> neededAction) //or public void SomeMethod(Action neededAction)
{
//i need to run the neededAction and get the details whether what assert i did and the inputs i used for the assertion
}
So basically i need to run the Action and i need to get its method infos.
Thanks~
You need to call Compile() on the expression.
// Compile it.
var actualNeededAction = neededAction.Compile();
// Execute it.
actualNeededAction();
This question already has answers here:
How can I find the method that called the current method?
(17 answers)
Closed 6 years ago.
Is it possible to determine the calling method name "Eat Pizza" in PostError?
I guess I could pass "EatPizza" as one of the arguments, but that would require changes each time the method name changes (unnecessary maintenance). But then, I wasn't even able to find the method name "EatPizza" in the context of "EatPizza" (using stacktrace, getframe, getmethod).
public void EatPizza(Pizza p){
if(p==null){ //A arbitrary made up error
Utilities.PostError();
}
else{
p.Slices -= 1;
}
}
...
public void PostError(){
//Basically posting to database the name of the method
//Tried this, didn't work: (new StackTrace(true)).GetFrame(5).GetMethod().Name
//Is it possible to determine the calling method name "Eat Pizza" in this context?
}
When I try different values (0 to StackTrace.FrameCount-1) in StackTrace.GetFrame, I get the following values, when I just want "EatPizza":
.ctor
ThreadStart
Main
_nExecuteAssembly
RunUsersAssemblyDebugInZone
You were on the right track with creating a StackTrace object, but you seem to have misunderstood the argument to GetFrame. Frames are numbered from the bottom-most frame, so:
GetFrame(0) would return PostError
GetFrame(1) would return the caller of PostError
So just try this:
var trace = new StackTrace(true);
WriteToDB(trace.GetFrame(1).GetMethod().Name);
Personally, I would prefer to get the entire stack trace rather than just the caller, so I'd do this:
var trace = new StackTrace(true);
WriteToDB(trace.ToString());
Is it possible to determine the calling method name "Eat Pizza" in PostError? I guess I could pass "EatPizza" as one of the arguments, but that would require changes each time the method name changes (unnecessary maintenance).
Calling PostError in all the methods in which something could go wrong is also "unnecessary maintenance". It also complicates the execution flow of your program, because you will have to check for errors all over the place, and high-level processes will have to check if the low level processes completed successfully.
It is better to use the exception handling structures provided by the CLR and C#.
The exact location in which the error occured is stored in the exception's StackTrace property.
pubic void BigDinnerEatingProcess()
{
try
{
WhateverHappensAtTheTopLevel();
}
catch (PizzaNotDeliveredException ex)
{
Utilities.PostError(ex);
MessageBox.Show("Dinner was not eaten. Please make sure the pizza is delivered.");
}
}
public void EatPizza(Pizza p)
{
if (p == null)
throw new PizzaNotDeliveredException();
p.RemoveOneSlice();
}
private void PostError(Exception ex)
{
string errorLocation = ex.StackTrace;
//...
}