I have a need to wrap a number of functions with code that will pre-process input data for these functions ("Wrapper"). Here's the code written using delegates (the code is simplified as much as possible, while still functional and immediately compilable):
namespace ConsoleApp
{
class ClientContext
{
public int i = 1;
}
class SPRemoteEventProperties
{
}
class Program
{
public delegate void Del(ClientContext clientContext, SPRemoteEventProperties properties);
public static void Wrapper(Del f, ClientContext clientContext, SPRemoteEventProperties properties)
{
ClientContext newClientContext = new ClientContext
{
i = clientContext.i * 2
};
f(newClientContext, properties);
}
static void Main(string[] args)
{
Function1(new ClientContext(), new SPRemoteEventProperties());
Function2(new ClientContext(), new SPRemoteEventProperties());
Wrapper(Function1, new ClientContext(), new SPRemoteEventProperties());
Wrapper(Function2, new ClientContext(), new SPRemoteEventProperties());
Console.Read();
}
static void Function1(ClientContext clientContext, SPRemoteEventProperties properties)
{
Console.WriteLine("Function1: " + clientContext.i);
}
static void Function2(ClientContext clientContext, SPRemoteEventProperties properties)
{
Console.WriteLine("Function2: " + clientContext.i);
}
}
}
Now, to simplify the code I'd like to rewrite it using Action<> syntax and inline the functions' code. Here's what I tried to do, but I can't manage to write a correct and functioning program:
using System;
namespace ConsoleApp
{
class ClientContext
{
public int i = 1;
}
class SPRemoteEventProperties
{
}
class Program
{
Action<ClientContext, SPRemoteEventProperties> Act;
// error in next line =>
public static void Wrapper(Act f, ClientContext clientContext, SPRemoteEventProperties properties)
{
ClientContext newClientContext = new ClientContext
{
i = clientContext.i * 2
};
f(newClientContext, properties);
}
static void Main(string[] args)
{
Function1(new ClientContext(), new SPRemoteEventProperties());
Function2(new ClientContext(), new SPRemoteEventProperties());
// error in next 2 lines =>
Wrapper((new ClientContext(), new SPRemoteEventProperties()) => Console.WriteLine("Function1: " + clientContext.i));
Wrapper((new ClientContext(), new SPRemoteEventProperties()) => Console.WriteLine("Function2: " + clientContext.i));
Console.Read();
}
static void Function1(ClientContext clientContext, SPRemoteEventProperties properties)
{
Console.WriteLine("Function1: " + clientContext.i);
}
static void Function2(ClientContext clientContext, SPRemoteEventProperties properties)
{
Console.WriteLine("Function2: " + clientContext.i);
}
}
}
Can you help me correct this code?
I'm not sure i fully understand what you are trying to do, am i close?
public static void Wrapper(ClientContext clientContext, SPRemoteEventProperties properties, Action<ClientContext, SPRemoteEventProperties> action)
{
action(newClientContext, properties);
}
...
Wrapper( new ClientContext(), new SPRemoteEventProperties(),(context, properties) => Console.WriteLine("Function1: " + context.i));
The usage of Action is different than a delegate:
While the delegate syntax define a type declaration that you can use to define a variable, the Action syntax is already the type, and you can use it to create your variable.
I'm not sure i'm clear, but, following is the correct syntax to use:
public static void Wrapper(Action<ClientContext, SPRemoteEventProperties> f, ClientCo ...
An Action has the diamond notation (<>) after it, which is a sign that it is a generic type. Unlike delegate, it contains everything the compiler needs to make it type safe. This differs from delegate which is not really typed until you define a specific delegate, which tells the compiler the types of all the parameters. With the Action you just need to put the types into the diamond and voila, it is a complete type now.
Since the parameter name is always preceded by its type, your prototype should read like this:
public static void Wrapper(Action<ClientContext, SPRemoteEventProperties> f, ClientContext clientContext, SPRemoteEventProperties properties)
{
That is everything the compiler needs to know about what is going to be contained in that argument, type-wise.
I am tryin to test a private static method like so:
public void myMethodTest()
{
MyClass target = new MyClass();
PrivateType pt = new PrivateType(target.GetType());
var x = pt.InvokeStatic("MyMethod");
//Some type of Assert here
}
The method also uses a private static variable within its class to check if its null, MyMethod is what im trying to test
private static HashSet<AnotherClass> fakeName{get;set;}
private static void MyMethod()
{
if (null== fakeName)
{
fakeName = new HashSet<AnotherClass>();
}
}
Thanks guys, if you need more clarification please let me know
In my Test if I do ,
Assert.IsNotNull(x);
the test fails, im just wondering if the method is actually been called , i followed this answer to run this test Stack answer
Using Typemock Isolator you can:
public void myMethodTest()
{
MyClass target = new MyClass();
Isolate.Invoke.Method<MyClass>("MyMethod");
Isolate.Verify.NonPublic.WasCalled(typeof(Dependency), "MyMethod");
}
but it's commercial.
I get an error here saying that the program could not exit the infinite loop.
public static class Program
{
public static void Main(string[] args)
{
Object obj = new Object();
Console.WriteLine(obj.GetClassName());
}
public static string GetClassName(this object value)
{
return value.GetClassName();
}
}
you need to change your extension method to say:
return obj.GetType().Name;
your extension method is calling itself which is causing the infinite loop/recursion problem.
How to get delegate name inside delegated method?
Here is my program for testing:
namespace Test
{
class Program
{
public Action action;
void real()
{
// I hoped it would output "action" here, but it was "real"
Console.WriteLine(MethodInfo.GetCurrentMethod().Name);
}
public Program()
{
action = real;
}
static void Main(string[] args)
{
Program pr = new Program();
pr.action();
}
}
}
So how can I get the name of delegate action instead of method read?
I've tried MethodInfo.GetCurrentMethod(), but it didn't work.
Consider
static void Main(string[] args)
{
Program pr = new Program();
Action tempName1 = pr.action;
Action tempName2 = tempName1;
//pr.action();
tempName2();
}
Which name would you like to get? tempName1, tempName2, pr.action or just action?
From these choices it follows that you can't get an unambiguous variable name.
I hope this is a simple question. I'm building a simple console application in C#. I have a class:
using System;
using Filter;
public class Params
{
public string key;
public bool distinct;
public List<string> fields;
public string filter;
public int limit;
public int skip;
public bool total;
public List<Tuple<string, GroupType>> group;
public List<Tuple<string, OrderType>> order;
public Params()
{
key = "";
distinct = false;
fields = new List<string>();
filter = "";
group = new List<Tuple<string, GroupType>>();
limit = 0;
order = new List<Tuple<string, OrderType>>();
skip = 0;
total = false;
}
public void AddGroup(string field, GroupType type)
{
group.Add(new Tuple<string, GroupType>(field, type));
}
public void AddOrder(string field, OrderType type)
{
order.Add(new Tuple<string, OrderType>(field, type));
}
}
My program .cs class is:
namespace csharpExample
{
class Program
{
public static void Main(string[] args)
{
Params p = new Params();
Console.WriteLine("Test");
}
}
}
I want to use Params in my program.cs class where Main() is called. I thought I could simply use Params like above. I've also tried to do a using Params; both of these are errors in VS since it can't find the directive. I've also tried adding my own namespace: namespace MyNameSpace; around my Params class. When I do this I still am unable to do a using MyNameSpace; statement as it can't find it.
I just want to extract out a bunch of functions into a class that I can reuse. How do i call this class once it's created?
-Thanks
Thanks for the help.
If you want to access the Params object in the Main function, just add Params p = new Params (); to the Main function at the top.
Most likely your problem is that Main is static, meaning that it can't access other things that aren't static which are outside of it. If you declared Params in the Program class, unless you made it static, it can't be accessed in Main.
Are you talking about calling the constructor or the properties you are setting? You can set the class at the top of your base class and then call the instance of it. But since it is a static class you should probably use a helper method in the main.
namespace Example
{
public class Program
{
Params p = new Params();
string writefromParams() // I exist just to give the string back from params with a nonstatic method
{
return p.key;
}
static void Main(string[] args)
{
Program p2 = new Program(); // set up a new instance of this very class
Console.WriteLine(p2.writefromParams()); // get non static method from class
Console.ReadLine();
}
}
}