I have the following code in my class:
private static void SetUserMeta(string pUserToken, string pMetaKey, string pMetaValue, Action<bool> callback)
{
BuddyClient client = CreateBuddy();
bool rValue = false;
client.LoginAsync((user, state) =>
{
if (state.Exception != null)
{
rValue = false;
}
else
{
client.Metadata.SetAsync((result, resultState) =>
{
if (resultState.Exception != null)
{
rValue = false;
}
else
{
rValue = true;
}
}, key: pMetaKey, value: pMetaValue);
}
callback(rValue);
}, token: pUserToken);
}
and I want to get rValue and return it from my other method which is the following
public static void SetBuddyData(string pUserToken, BuddyData pMetaValue, Action<bool> callback)
{
//my problem is here and I don't know how to get and return data from SetUserMeta
return SetUserMeta(pUserToken, "SavedGameData", pMetaValue.Serialize());
}
And also I want to call this return value from my application. These codes are in my library. How can I do it?
Just pass callback to SetUserMeta like
public static void SetBuddyData(string pUserToken, BuddyData pMetaValue, Action<bool> callback)
{
SetUserMeta(pUserToken, "SavedGameData", callback);
}
And call SetBuddyData like this
SetBuddyData("my user token", myBundle, isLoggedIn => HandleUserLogin(isLoggedIn));
Where at HandleUserLogin you will process bool callback data, returned at callback(rValue); in SetUserMeta method. It's body example is shown
next
public static void HandleUserLogin(bool isLogged)
{
Console.WriteLine("user is {0} logged in", isLogged ? "" : "not");
}
You also can take advantage of method group syntax and call SetBuddyData method like:
SetBuddyData("my user token", myBundle, HandleUserLogin);
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 1 year ago.
Improve this question
I work at an application that receives data from user and I try to write a validator function for it, but I'm not sure if this is the correct way to proceed.
Example: The user will input a number (as string, don't ask why I don't use an int, let it be a string), let's say "103", and I'will use this number inside a function, but first, at the beginning of that function I call a validator function:
private bool ValidateCommandCode(string code)
{
bool isValid = false;
byte commandByte = new byte();
if (byte.TryParse(code, out commandByte))
{
isValid = true;
}
else
{
Log.Error($"Command number {CommandCode} for the request is not valid!");
isValid = false;
}
return isValid;
}
private async void MainFunction()
{
if (ValidateCommandCode(CommandCode) == false)
return;
// ... do the magic with the CommandCode ...
}
in the same manner, I want to validate another field filled by the user:
e.g of data: 000A000B
private bool ValidateRequestData(string data)
{
bool isValid = false;
if (!String.IsNullOrEmpty(Payload) && !String.IsNullOrWhiteSpace(Payload))
{
if (Payload.Trim().Replace(" ", "").Length % 2 != 0)
{
Log.Error($"Payload (Data) {Payload} for the request doesn't have an even number of bytes!");
isValid = false;
}
else
{
isValid = true;
}
}
else
{
isValid = true;
}
return isValid;
}
Is this a good way to proceed? Aren't so many flags "isValid" too confusing?
I would create a separate class for validation and decouple logging by passing a logger to the validator.
public interface ILogger
{
void Error(string message);
}
public class Logger : ILogger
{
public void Error(string message) { }
}
public class LoggingValidator
{
private readonly ILogger _logger;
// Payload looks like a hex number, so we check this.
private static readonly Regex _payloadExp = new Regex(#"^\s*([0-9A-F]{2} *)+\s*$", RegexOptions.Compiled);
public LoggingValidator(ILogger logger)
{
_logger = logger;
}
public bool CheckCommand(string value)
{
if (byte.TryParse(value, out _)) // Discard operator _
return true;
_logger.Error("Your message.");
return false;
}
public bool CheckPayload(string value)
{
if (_payloadExp.IsMatch(value ?? ""))
return true;
_logger.Error("Your message.");
return false;
}
}
public class Program
{
private static void Main(string[] args)
{
var validator = new LoggingValidator(new Logger());
string value = "123";
if (validator.CheckCommand(value)) { /* ... */ }
if (validator.CheckPayload(value)) { /* ... */ }
}
}
I would like to code a framework in C# Console Application(CLI), details aren't important.
I don't know, how to recognize commands cleanly, and shortly.
I tried with switch-case:
public static void command_recognizing(string command) // random example
{
string[] tmp_array = command.Split(' ');
switch(tmp_array[0])
{
case("help"):
method_library.help(); // no need argument
break;
case("time"):
method_library.time(); // no need argument
break;
case("shutdown"):
method_library.shutdown(tmp_array); // need argument
break;
default:
Console.WriteLine("Error! {0} is not a known command!",tmp_array[0]);
break;
}
}
I also tried if-else:
public static void command_recognizing(string command) // random example
{
string[] tmp_array = command.Split(' ');
if(command.Contains("help"))
{
method_library.help(); // no need argument
}
else if(command.Contains("time"))
{
method_library.time(); // no need argument
}
else if(command.Contains("shutdown"))
{
method_library.shutdown(tmp_array); // need argument
}
else
{
Console.WriteLine("Error! {0} is not a known command!",tmp_array[0]);
}
}
I tried to store the commands in a string array, still the same, long and ugly.
There is any other way, to make the command recognizing shorter, cleaner and easier to modify?
Foregive me for my english. Feel free to correct me!
You could use Reflection to execute methods of a class.
void Main() {
var cmd = new Commands();
while (!cmd.Exitting) {
var cmdline = Console.ReadLine();
var cmdargs = Regex.Split(cmdline.Trim(), #"\s+");
if (!cmd.TryInvokeMember(cmdargs[0], cmdargs.Skip(1).ToArray()))
Console.WriteLine($"Unknown command: {cmdargs[0]}");
}
}
// Define other methods and classes here
public class Commands {
public bool Exitting { get; private set; }
public Commands() {
Exitting = false;
}
public void exit() {
Exitting = true;
}
public int sum(object[] args) {
return args.Select(s => Convert.ToInt32(s)).Sum();
}
public bool TryInvokeMember(string methodName, object[] args) {
var method = typeof(Commands).GetMethod(methodName.ToLower());
if (method != null) {
object res;
if (method.GetParameters().Length > 0)
res = method.Invoke(this, new object[] { args });
else
res = method.Invoke(this, new object[0]);
if (method.ReturnType != typeof(void))
Console.WriteLine(res.ToString());
return true;
}
else
return false;
}
}
today i was looking for some projects with ilspy i did not understand how Actions can be used like this, in one class this method is called
public void Login(Action success, Action<bool> failure)
{
if (!FB.IsInitialized)
{
Debug.Log("[FB] Not yet initialized. Will init again!");
FB.Init(new InitDelegate(this.OnInitComplete), null, null);
return;
}
new LoginWithReadPermissions(this.READ_PERMISSIONS, delegate
{
ServiceLocator.GetDB().SetBool("facebookBound", true, false);
this.OnLoginCompleted(success, failure);
}, delegate
{
failure(false);
});
}
and this is the other class that is called by above method
public class LoginWithReadPermissions
{
private readonly Action _failureCallback;
private readonly Action _successCallback;
public LoginWithReadPermissions(string[] scope, Action success, Action failure)
{
this._successCallback = success;
this._failureCallback = failure;
FB.LogInWithReadPermissions(scope, new FacebookDelegate<ILoginResult>(this.AuthCallback));
}
private void AuthCallback(ILoginResult result)
{
if (result.Error == null && FB.IsLoggedIn)
{
this._successCallback();
}
else
{
this._failureCallback();
}
}
}
Can someone please explain what is going on there I have never faced with this kind of Action usage. Thanks for replies.
public void Login(Action success, Action<bool> failure)
{
if (!FB.IsInitialized)
{
Debug.Log("[FB] Not yet initialized. Will init again!");
FB.Init(new InitDelegate(this.OnInitComplete), null, null);
return;
}
new LoginWithReadPermissions(this.READ_PERMISSIONS, delegate
{
ServiceLocator.GetDB().SetBool("facebookBound", true, false);
this.OnLoginCompleted(success, failure);
}, delegate
{
failure(false);
});
}
The code above is just shorthand for this:
public void Login(Action success, Action<bool> failure)
{
Action successAction = () =>
{
ServiceLocator.GetDB().SetBool("facebookBound", true, false);
this.OnLoginCompleted(success, failure);
};
Action failureAction = () =>
{
failure(false);
};
if (!FB.IsInitialized)
{
Debug.Log("[FB] Not yet initialized. Will init again!");
FB.Init(new InitDelegate(this.OnInitComplete), null, null);
return;
}
new LoginWithReadPermissions(this.READ_PERMISSIONS, successAction, failureAction);
}
have a php code like this,going to convert it in to C#.
function isValid($n){
if (preg_match("/\d+/",$n) > 0 && $n<1000) {
return true;
}
return false;
}
Here is my try,BUT error shown Error is "expected class, delegate, enum, interface or struct error C#"
public string IsValidate(string Item)
{
string Result = Item;
try
{
Result = System.Text.RegularExpressions.Regex.Replace(InputTxt, #"(\\)([\000\010\011\012\015\032\042\047\134\140])", "$2");
}
catch(Exception ex)
{
console.WriteLine(ex.Message)
}
return Result;
}
What is the error,Is there any other way to implement this better than my try ?
i got this snippet from here code
You haven't define this method inside a class/struct that is why you are getting this error. You may define this method inside a class.
public class MyValidator
{
public string IsValidate(string Item)
{
//Your code here
}
}
Later you can use it like:
MyValidator validator = new MyValidator();
validator.IsValid("Your string");
Also you are missing semicolon at the end of the Console.Write statement, plus 'c' for Console should be in uppercase
Edit:
Since in your php code, it looks like you are trying to see if the string passed is an integer and it is less than 1000, you may use the int.TryParse like the following:
public class MyValidator
{
public bool IsValidate(string Item)
{
string Result = Item;
int val;
if (int.TryParse(Item, out val) && val > 0 && val < 1000)
{
return true;
}
else
{
return false;
}
}
}
In you main method you can do:
static void Main()
{
MyValidator validator = new MyValidator();
Console.WriteLine(validator.IsValidate("asdf123")); // This will print false
Console.WriteLine(validator.IsValidate("999")); //This will print true
Console.WriteLine(validator.IsValidate("1001")); //This will print false
}
In C# a method must be placed inside a class or struct:
public class Validator {
public string IsValidate(string item) {
...
}
}
In this case I would probably translate it like this:
public static class Validator {
public static bool IsValid(string item) {
int value;
return int.TryParse(item, out value)
&& value > 0 && value < 1000;
}
}
You could define your function inside a static class such that you dont have to create an instance of it before invoking the function. Like,
public static class Validator
{
public static string IsValidate(string item)
{
// ...
}
}
Then, you can call it using:
Validator.IsValidate("String to validate")
EDIT: You could then check that your function is returning what you expect by doing:
if(Validator.IsValidate("String to validate") == "Expected result")
{
/* Logic to be executed here */
}
I've this little method which is supposed to be thread safe. Everything works till i want it to have return value instead of void. How do i get the return value when BeginInvoke is called?
public static string readControlText(Control varControl) {
if (varControl.InvokeRequired) {
varControl.BeginInvoke(new MethodInvoker(() => readControlText(varControl)));
} else {
string varText = varControl.Text;
return varText;
}
}
Edit: I guess having BeginInvoke is not nessecary in this case as i need value from GUI before the thread can continue. So using Invoke is good as well. Just no clue how to use it in following example to return value.
private delegate string ControlTextRead(Control varControl);
public static string readControlText(Control varControl) {
if (varControl.InvokeRequired) {
varControl.Invoke(new ControlTextRead(readControlText), new object[] {varControl});
} else {
string varText = varControl.Text;
return varText;
}
}
But not sure how to get value using that code either ;)
You have to Invoke() so you can wait for the function to return and obtain its return value. You'll also need another delegate type. This ought to work:
public static string readControlText(Control varControl) {
if (varControl.InvokeRequired) {
return (string)varControl.Invoke(
new Func<String>(() => readControlText(varControl))
);
}
else {
string varText = varControl.Text;
return varText;
}
}
EndInvoke may be used to get a return value from a BeginInvoke call. For example:
public static void Main()
{
// The asynchronous method puts the thread id here.
int threadId;
// Create an instance of the test class.
AsyncDemo ad = new AsyncDemo();
// Create the delegate.
AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
// Initiate the asychronous call.
IAsyncResult result = caller.BeginInvoke(3000,
out threadId, null, null);
Thread.Sleep(0);
Console.WriteLine("Main thread {0} does some work.",
Thread.CurrentThread.ManagedThreadId);
// Call EndInvoke to wait for the asynchronous call to complete,
// and to retrieve the results.
string returnValue = caller.EndInvoke(out threadId, result);
Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
threadId, returnValue);
}
}
public static string readControlText(Control varControl)
{
if (varControl.InvokeRequired)
{
string res = "";
var action = new Action<Control>(c => res = c.Text);
varControl.Invoke(action, varControl);
return res;
}
string varText = varControl.Text;
return varText;
}
If you want a return value from you method, you shouldn't be using async version of the method, you should use .Invoke(...). Which is synchronous, that is it will execute your delegate, and won't return until it's complete. In your example as it is now, BeginInvoke will send the request to execute your delegate, and return right away. So there is nothing to return.
Is something like this what you wanted?
// begin execution asynchronously
IAsyncResult result = myObject.BeginInvoke("data.dat", null, null);
// wait for it to complete
while (result.IsCompleted == false) {
// do some work
Thread.Sleep(10);
}
// get the return value
int returnValue = myObject.EndInvoke(result);
delegate string StringInvoker();
string GetControlText()
{
if (control.InvokeRequired)
{
string controltext = (string)control.Invoke(new StringInvoker(GetControlText));
return(controltext);
}
else
{
return(control.Text);
}
}
//simple & elegant but it is needed to wait for another thread to execute delegate; however if you cannot proceed without the results...
Here is more cleaner solution
public delegate void InvokeIfRequiredDelegate<T>(T obj) where T : ISynchronizeInvoke;
public static void InvokeIfRequired<T>(this T obj, InvokeIfRequiredDelegate<T> action) where T : ISynchronizeInvoke
{
if (obj.InvokeRequired)
obj.Invoke(action, new object[] { obj });
else
action(obj);
}
public static string GetThreadSafeText(this Control control)
{
string value = string.Empty;
control.InvokeIfRequired((c) => value = c.Text);
return value;
}
public static void SetThreadSafeText(this Control control, string value)
{
control.InvokeIfRequired((c) => c.Text = value);
}
Usage:
public string Name
{
get => txtName.GetThreadSafeText();
set => txtName.SetThreadSafeText(value);
}