I need to write a delegate function that can 'wrap' some while/try/catch code around a basic UDP call to verify the link.
I made it work for Func for a function that has no arguments, but I can't make it work for Action, which has an argument (but no return). I can't seem to pass in the argument in a logical way without the compiler complaining.
Am I going about this all wrong? I'm new to C# and I'm essentially trying to mimick the idea of a function pointer. Should I not be overloading this function? I know you can't overload delegates (I assume that's why Func and Action exist).
This works:
protected TResult udpCommand<TResult>(Func<TResult> command)
{
TResult retValue = default(TResult);
while (!linkDownFail)
{
try
{
retValue = command();
break;
}
catch
{
LinkStateCallBack(ip, getLinkStatus());
if (linkDownFail) throw new LinkDownException();
Thread.Sleep(100);
}
}
return retValue;
}
But this does not:
protected void udpCommand<T>(Action<T> command(T value))
{
while(!linkDownFail)
{
try
{
command(value);
break;
}
catch
{
LinkStateCallBack(ip, getLinkStatus());
if (linkDownFail) throw new LinkDownException();
Thread.Sleep(100);
}
}
return;
}
Calling convention (for one that works):
udpCommand<uint>(someUdpCommand);
If you want this to be generic enough to handle any number of arguments, try using the non-genernic Action delegate:
protected void udpCommand(Action command)
{
while(!linkDownFail)
{
try
{
command();
break;
}
catch
{
LinkStateCallBack(ip, getLinkStatus());
if (linkDownFail) throw new LinkDownException();
Thread.Sleep(100);
}
}
return;
}
In C# 3.0, you can call it like this:
udpCommand(() => noParameterMethod());
udpCommand(() => singleParameterMethod(value));
udpCommand(() => manyParameterMethod(value, value2, value3, value4));
In C# 2.0 it's a little uglier:
udpCommand(delegate { noParameterMethod(); });
udpCommand(delegate { singleParameterMethod(value); });
udpCommand(delegate { manyParameterMethod(value, value2, value3, value4); });
This gives you deferred execution without locking you into a particular method signature.
EDIT
I just notice I kinda stole Marc Gravell's comment... apologies Marc. To answer how you might reduce your duplication, you can have the Action method call the Func<T> method, like this:
protected void udpCommand(Action command)
{
udpCommand(() => { command(); return 0; });
}
I believe (and I may be wrong) that returning 0 is no more costly than (implicitly) returning void, but I may be way off here. Even it it does have a cost, it would only put a tiny itty bitty snoodge extra on the stack. In most cases, the additional cost won't ever cause you any grief.
Do you mean:
protected void udpCommand<T>(Action<T> command, T value) {...}
With calling:
udpCommand(someUdpCommand, arg);
Note that this may work better on C# 3.0, which has stronger generic type inference than C# 2.0.
I think you just need to take out the (T value) after 'command'.
Are you trying to do this ...
protected void udpCommand<T>(Action<T> command, T value)
{
while(!linkDownFail)
{
try
{
command(value);
// etc.
}
}
}
Then it would work like this ...
public void ActionWithInt( int param )
{
// some command
}
Action<int> fp = ActionWithInt;
udpCommand<int>( fp, 10 ); // or whatever.
Related
Hi I was integrating facebook SDK in unity and basically I worked in java earlier and I am new to c# script and a question came to my mind.
I have searched a lot found nothing, may be my searching query is good enough or not but my question is ...
as a function FB.init called here
void Awake ()
{
FB.Init(InitCallback, OnHideUnity);
}
here when init function will be called it will call InitCallBack and OnHideUnity functions and both are returning void these are used form facebook-unity-sdk docs
private void InitCallback ()
{
if (FB.IsInitialized) {
// Signal an app activation App Event
FB.ActivateApp();
// Continue with Facebook SDK
// ...
} else {
Debug.Log("Failed to Initialize the Facebook SDK");
}
}
private void OnHideUnity (bool isGameShown)
{
if (!isGameShown) {
// Pause the game - we will need to hide
Time.timeScale = 0;
} else {
// Resume the game - we're getting focus again
Time.timeScale = 1;
}
}
My question is if I call a function like this and that function return something e.g String and I want wanted to store it something like this
String result="";
SomeFunctions(FunctionOne,result=FunctionTwo);
String FunctionTwo()
{
return "a String";
}
Is this possible?
Is there any way to get value returned by such function call?
Or is this possible that a function that returns value can be called in this way?
It seems like you are confusing a delegate for a function expression. The delegate will have no return value until it is invoked as a function.
void SomeFunction(Func<string> func) {
var result = func(); // only here will the function return value be accessible
Console.WriteLine(result);
}
SomeFunction(() => "test");
Although you do not have access to the return value of the function, the delegate could assign a variable you choose inside it's method body, instead of using it's return value:
string result;
SomeFunction(() => {
result = "test";
return result;
});
// result would now contain "test"
I am not sure what you want to achieve here, but you could use out to change the reference of the parameter.
string result="";
MyMethod(out result);
Debug.Log(string.Format("Result: {0}", result));
void MyMethod(out string pValue)
{
pValue = "my changed value";
}
The out keyword causes arguments to be passed by reference. This is like the ref keyword, except that ref requires that the variable be initialized before it is passed. To use an out parameter, both the method definition and the calling method must explicitly use the out keyword.
https://msdn.microsoft.com/en-us/library/t3c3bfhx.aspx
But in a case like this, you could just return the correct value. In the example below its not even worth passing the parameter since we are not using it.
string result = MyMethod(result);
string MyMethod(string pValue)
{
pValue = "My changed value";
return pValue;
}
I found the method below in a Windows Phone 7 C# sample. In it you can see the terms success and failure used inside the method. I tried Go To Definition with either term and Visual Studio did not jump to a definition for either term. I tried searching Google using the terms "Action", "success", "failure", "C#", and "parameter" and did not find anything useful. Are success and failure in this context macros or something similar? Where can I get an explanation of what they do and how to use them? Note, the tooltip help when hovered over failure shows "parameter Action<string> failure".
public void SendAsync(string userName, string message, Action success, Action<string> failure)
{
if (socket.Connected) {
var formattedMessage = string.Format("{0};{1};{2};{3};{4}",
SocketCommands.TEXT, this.DeviceNameAndId, userName, message, DateTime.Now);
var buffer = Encoding.UTF8.GetBytes(formattedMessage);
var args = new SocketAsyncEventArgs();
args.RemoteEndPoint = this.IPEndPoint;
args.SetBuffer(buffer, 0, buffer.Length);
args.Completed += (__, e) => {
Deployment.Current.Dispatcher.BeginInvoke(() => {
if (e.SocketError != SocketError.Success) {
failure("Your message can't be sent.");
}
else {
success();
}
});
};
socket.SendAsync(args);
}
}
They are delegates that are being used as "callback functions". Basically, they are functions that are provided to another function that can be called inside that function. Perhaps a smaller sample would make more sense:
static void PerformCheck(bool logic, Action ifTrue, Action ifFalse)
{
if (logic)
ifTrue(); // if logic is true, call the ifTrue delegate
else
ifFalse(); // if logic is false, call the ifFalse delegate
}
False is printed in the below example, because 1 == 2 evaluates to false. So, logic is false within the PerformCheck method.. so it calls the ifFalse delegate. As you can see, ifFalse prints to the Console:
PerformCheck(1 == 2,
ifTrue: () => Console.WriteLine("Yep, its true"),
ifFalse: () => Console.WriteLine("Nope. False."));
Whereas this one will print true.. because 1 == 1 evaluates to true. So it calls ifTrue:
PerformCheck(1 == 1,
ifTrue: () => Console.WriteLine("Yep, its true"),
ifFalse: () => Console.WriteLine("Nope. False."));
You can think of Action (and also Func) as variables that hold other methods.
You can pass, assign and basically do anything to an Action that you would any other variable, but you can also call it like a method.
Say you have two methods in your code:
public void Main(){
Action doWork;
doWork = WorkMethod;
doWork();
}
private void WorkMethod(){
//do something here
}
You assign WorkMethod to the action like you would do any assignment to the variable. Then, you can call doWork as though it were a method. It isn't particularly useful in this example, but you can probably see how all the benefits of standard variables apply.
You use an Action and a Func in pretty much the same way. The only real difference is that an Action represents a void and a Func requires a return type.
You can also use generics. For example Action<int> respresents a method with the signature
void methodName(int arg){}
Action<int, string> would be
void methodName(int arg1, string arg2){}
Func is similar, Func<int> would be:
int methodName(){}
Func<string, int> would be:
int methodName(string arg){}
It's important to remember that the last type in the Func definition is the return type, even though it appears first in the actual method signature.
I'm building a messaging app in csharp (.net 4.0), my class has basic methods for sending/receiving messages:
void sendMessage( string msgBody, string properties);
object getNextMessage();
object getMessageById( string msgId);
Each of these methods depends on an underlying connection; if the connection is stale, I use try/catch and some retry logic to make additional attempts, something like this:
public object getNextMessage(){
object nextMessage = null;
int retryAttempts = 0;
int MAX_ATTEMPTS = 3;
while( retryAttempts < MAX_ATTEMPTS){
retryAttempts++;
try{
nextMessage = connection.getMessage("queueName");
}catch(Exception e){
}
}
return nextMessage;
}
Since the retry logic is generic, I want to avoid repeating the same code in each method. I want to create a common retry function and do something like this:
public object makeAttempt( CodeBlock codeBlock){
while( retryAttempts < MAX_ATTEMPTS){
retryAttempts++;
try{
return codeBlock.invoke()
}catch(Exception e){
}
}
return null;
}
..I want to use makeAttempt like this, or something similar:
public object getNextMessage(){
makeAttempt() => {
return connection.getMessage("queueName");
}
}
I reviewed this, but it relates to passing entire functions as arguments, which I'm not doing. I also reviewed .net Lambda Expressions, but I'm not seeing a connection.
I haven't done much C# so forgive the n00b question :-)
You're nearly there at the end - you just need to enclose the lambda expression in () as it's a method argument. You also need to use the return value from makeAttempt to provide a return value for your getNextMessage method. So:
public object getNextMessage(){
return makeAttempt(() => {
return connection.getMessage("queueName");
});
}
Or more simply, use an expression lambda:
public object getNextMessage(){
return makeAttempt(() => connection.getMessage("queueName"));
}
This is all assuming that CodeBlock is a delegate type, of course, e.g.
public delegate object CodeBlock();
You also need to change makeAttempt to call Invoke rather than invoke - C# is case-sensitive. I'd strongly urge you to follow .NET naming conventions, too, where methods are PascalCased instead of camelCased.
EDIT: As noted in comments, you could make this generic:
public T CallWithRetries<T>(Func<T> function)
{
for (int attempt = 1; attempt <= MaxAttempts; attempt++)
{
try
{
return function();
}
catch(Exception e)
{
// TODO: Logging
}
}
// TODO: Consider throwing AggregateException here
return default(T);
}
Going from a lambda to an Expression is easy using a method call...
public void GimmeExpression(Expression<Func<T>> expression)
{
((MemberExpression)expression.Body).Member.Name; // "DoStuff"
}
public void SomewhereElse()
{
GimmeExpression(() => thing.DoStuff());
}
But I would like to turn the Func in to an expression, only in rare cases...
public void ContainTheDanger(Func<T> dangerousCall)
{
try
{
dangerousCall();
}
catch (Exception e)
{
// This next line does not work...
Expression<Func<T>> DangerousExpression = dangerousCall;
var nameOfDanger =
((MemberExpression)dangerousCall.Body).Member.Name;
throw new DangerContainer(
"Danger manifested while " + nameOfDanger, e);
}
}
public void SomewhereElse()
{
ContainTheDanger(() => thing.CrossTheStreams());
}
The line that does not work gives me the compile-time error Cannot implicitly convert type 'System.Func<T>' to 'System.Linq.Expressions.Expression<System.Func<T>>'. An explicit cast does not resolve the situation. Is there a facility to do this that I am overlooking?
Ooh, it's not easy at all. Func<T> represents a generic delegate and not an expression. If there's any way you could do so (due to optimizations and other things done by the compiler, some data might be thrown away, so it might be impossible to get the original expression back), it'd be disassembling the IL on the fly and inferring the expression (which is by no means easy). Treating lambda expressions as data (Expression<Func<T>>) is a magic done by the compiler (basically the compiler builds an expression tree in code instead of compiling it to IL).
Related fact
This is why languages that push lambdas to the extreme (like Lisp) are often easier to implement as interpreters. In those languages, code and data are essentially the same thing (even at run time), but our chip cannot understand that form of code, so we have to emulate such a machine by building an interpreter on top of it that understands it (the choice made by Lisp like languages) or sacrificing the power (code will no longer be exactly equal to data) to some extent (the choice made by C#). In C#, the compiler gives the illusion of treating code as data by allowing lambdas to be interpreted as code (Func<T>) and data (Expression<Func<T>>) at compile time.
private static Expression<Func<T, bool>> FuncToExpression<T>(Func<T, bool> f)
{
return x => f(x);
}
What you probably should do, is turn the method around. Take in an Expression>, and compile and run. If it fails, you already have the Expression to look into.
public void ContainTheDanger(Expression<Func<T>> dangerousCall)
{
try
{
dangerousCall().Compile().Invoke();;
}
catch (Exception e)
{
// This next line does not work...
var nameOfDanger =
((MemberExpression)dangerousCall.Body).Member.Name;
throw new DangerContainer(
"Danger manifested while " + nameOfDanger, e);
}
}
public void SomewhereElse()
{
ContainTheDanger(() => thing.CrossTheStreams());
}
Obviously you need to consider the performance implications of this, and determine if it is something that you really need to do.
If you sometimes need an expression and sometimes need a delegate, you have 2 options:
have different methods (1 for each)
always accept the Expression<...> version, and just .Compile().Invoke(...) it if you want a delegate. Obviously this has cost.
NJection.LambdaConverter is a library that converts a delegate to an expression
public class Program
{
private static void Main(string[] args) {
var lambda = Lambda.TransformMethodTo<Func<string, int>>()
.From(() => Parse)
.ToLambda();
}
public static int Parse(string value) {
return int.Parse(value)
}
}
You can go the other way via the .Compile() method however - not sure if this is useful for you:
public void ContainTheDanger<T>(Expression<Func<T>> dangerousCall)
{
try
{
var expr = dangerousCall.Compile();
expr.Invoke();
}
catch (Exception e)
{
Expression<Func<T>> DangerousExpression = dangerousCall;
var nameOfDanger = ((MethodCallExpression)dangerousCall.Body).Method.Name;
throw new DangerContainer("Danger manifested while " + nameOfDanger, e);
}
}
public void SomewhereElse()
{
var thing = new Thing();
ContainTheDanger(() => thing.CrossTheStreams());
}
Expression<Func<T>> ToExpression<T>(Func<T> call)
{
MethodCallExpression methodCall = call.Target == null
? Expression.Call(call.Method)
: Expression.Call(Expression.Constant(call.Target), call.Method);
return Expression.Lambda<Func<T>>(methodCall);
}
JB Evain from the Cecil Mono team is doing some progress to enable this
http://evain.net/blog/articles/2009/04/22/converting-delegates-to-expression-trees
Change
// This next line does not work...
Expression<Func<T>> DangerousExpression = dangerousCall;
To
// This next line works!
Expression<Func<T>> DangerousExpression = () => dangerousCall();
In a normal loop you can break out of a loop using break. Can the same be done using an anonymous delegate?
Example
inputString and result are both declared outside the delegate.
blackList.ForEach(new Action<string>(
delegate(string item)
{
if(inputString.Contains(item)==true)
{
result = true;
// I want to break here
}
}
));
Edit:
Thanks for the replies, I'm actually reading your book at the minute John :) Just for the record i hit this issue and switched back to a normal foreach loop but I posted this question to see if i missed something.
As others have posted, you can't exit the loop in ForEach.
Are you able to use LINQ? If so, you could easily combine TakeWhile and a custom ForEach extension method (which just about every project seems to have these days).
In your example, however, List<T>.FindIndex would be the best alternative - but if you're not actually doing that, please post an example of what you really want to do.
There is no loop that one has access to, from which to break. And each call to the (anonymous) delegate is a new function call so local variables will not help. But since C# gives you a closure, you can set a flag and then do nothing in further calls:
bool stop = false;
myList.ForEach((a) => {
if (stop) {
return;
} else if (a.SomeCondition()) {
stop = true;
}
});
(This needs to be tested to check if correct reference semantics for closure is generated.)
A more advanced approach would be to create your own extension method that allowed the delegate to return false to stop the loop:
static class MyExtensions {
static void ForEachStoppable<T>(this IEnumerable<T> input, Func<T, bool> action) {
foreach (T t in input) {
if (!action(t)) {
break;
}
}
}
}
Do you have LINQ available to you? Your logic seems similar to Any:
bool any = blackList.Any(s=>inputString.Contains(s));
which is the same as:
bool any = blackList.Any(inputString.Contains);
If you don't have LINQ, then this is still the same as:
bool any = blackList.Find(inputString.Contains) != null;
If you want to run additional logic, there are things you can do (with LINQ) with TakeWhile etc
I don't think there's an elegant way to do it when using the ForEach method. A hacky solution is to throw an exception.
What's preventing you from doing an old fashioned foreach?
foreach (string item in blackList)
{
if (!inputString.Contains(item)) continue;
result = true;
break;
}
If you want a loop, use a loop.
Action allows for no return value, so there's no way the ForEach function could possibly know that you want to break, short of throwing an exception. Using an exception here is overkill.
The only way to "exit" the loop is to throw an exception. There is no "break" style way of exiting the .ForEach method like you would a normal foreach loop.
The ForEach method is not mean to do this. If you want to know if a collection contains an item you should use the Contains method. And if you want to perform a check on all items in a collection you should try the Any extention method.
bool #break = false;
blackList.ForEach(item =>
{
if(!#break && inputString.Contains(item))
{ #break = true;
result = true;
}
if (#break) return;
/* ... */
});
Note that the above will still iterate through each item but return immediately. Of course, this way is probably not as good as a normal foreach.
class Program
{
static void Main(string[] args)
{
List<string> blackList = new List<string>(new[] { "jaime", "jhon", "febres", "velez" });
string inputString = "febres";
bool result = false;
blackList.ForEach((item) =>
{
Console.WriteLine("Executing");
if (inputString.Contains(item))
{
result = true;
Console.WriteLine("Founded!");
}
},
() => result);
Console.WriteLine(result);
Console.ReadLine();
}
}
public static class MyExtensions
{
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action, Func<bool> breakOn)
{
foreach (var item in enumerable)
{
action(item);
if (breakOn())
{
break;
}
}
}
}
Would this work for you:
bool result = null != blackList.Find( item => inputString.Contains(item)) );
blackList.ForEach(new Action<string>(
delegate(string item)
{
if(inputString.Contains(item)==true)
{
result = true;
// I want to break here
return;
}
}
));
if you realy want to exist a loop foreach in a list you could use the exception like this code:
public class ExitMyForEachListException : Exception
{
public ExitMyForEachListException(string message)
: base(message)
{
}
}
class Program
{
static void Main(string[] args)
{
List<string> str = new List<string>() { "Name1", "name2", "name3", "name4", "name5", "name6", "name7" };
try
{
str.ForEach(z =>
{
if (z.EndsWith("6"))
throw new ExitMyForEachListException("I get Out because I found name number 6!");
System.Console.WriteLine(z);
});
}
catch (ExitMyForEachListException ex)
{
System.Console.WriteLine(ex.Message);
}
System.Console.Read();
}
}
hope this help to get other point of view.