I just started using C# this afternoon, so be a little gentle.
Currently I am working on a type of "template engine" where one of the callbacks needs to generate a globally unique ID. I am using delegates to manage the callbacks.
Currently the code looks like this (though I have also tried an anonymous function & returning NewGuid directly w/o a variable):
static string UID(List<string> p)
{
string s = Guid.NewGuid().ToString();
return s;
}
Which, when called directly, works fine. However if I try to call it via the delegate (added to a StringDictionary via addCallback("generate UID", new CallbackWrapper(UID))), the program will generate the same GUID regardless of how many times I duplicate it; even though calling the method directly both before & after the event occurs results in a unique ID as expected. I'v
No doubt it's just something simple I've missed, inevitably stemming from me being relatively inexperienced at C#.
Any help would be appreciated.
Thanks.
Well, I've now tried Dictionary with the same result.
CallbackWrapper is just the delegate, it's defined like this:
delegate string CallbackWrapper(List<string> parameters);
The remainder of the work is done in another class, which looks like this:
class TemplateParser
{
private Dictionary<string, CallbackWrapper> callbackMap;
public TemplateParser(string directivePrefix, string directiveSuffix)
{
...
callbackMap = new Dictionary<string,CallbackWrapper>();
}
public TemplateParser() : this("<!-- {", "} -->") {}
{
callbackMap.Add(name, callback);
}
public string parse(string filename)
{
...
string replacement =
callbackMap[directiveName](new List<string>(parameters.Split(new string[] { ";", " " }, StringSplitOptions.RemoveEmptyEntries));
...
}
}
I've stripped out the majority of the string handling code to save some space.
The issue is in your calling code, not in the code itself, nor in the delegate.
Using delegates here definitely works if called correctly.
Furthermore, your code can be slightly simplified:
static string UID(List<string> p)
{
return Guid.NewGuid().ToString();
}
(The variable is utterly redundant.)
use delegate.invoke
The difference between direct function call and delegate.invoke is here
http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/f629c34d-6523-433a-90b3-bb5d445c5587
StringDictionary will automatically cast your CallbackWrapper to a string, meaning it will only run once and store the output of CallbackWrapper.ToString(). This is probably not what you want.
Try using Dictionary<string, CallbackWrapper> instead.
Related
I am working on PCL which along with a lot of functionality also provides log in. Also I recently started using delegates.
The Current Case:
I have a Simple methods that takes in parameters and provide GPlus, Facebook or Simple logIn with Username and Password. as in the code below:
public async Task<SignInResponse> SignInUsingFacebook(IFacebookInitializer faceBookConfiguration)
{
//my code
}
public async Task<SignInResponse> SignInUserNameAndPass(string username,string password)
{
//my code
}
public async Task<SignInResponse> SignInUsingGPlus(IGPlusInitializer gPlusConfiguration)
{
//my code
}
This is great, I can call them from my application directly and handle data but,
I recently came across Delegates and Func<T,TResult>
What I want to do:
I want a simple method that takes in a parameter an enum of LogInType as below:
public enum LogInType
{
UserNameAndPassword,
Facebook,
GooglePlus,
}
and based on the type of login type provided to the method, handles the LogIn process on it's own and just returns the SignInResponse object.
Is there a way this can be done using Delegates. Rather than having 3 individual methods to call for each case. If yes, then can someone please help in the parameters to be passed to the Single method along with The LogInType. I know it has to be a Func but what would the Func look like as it has to take 3 different parameters.
As From the Comments:
Each of those methods is a different signature anyway so you have a Func<IFacebookInitializer, Task<SignInResponse>>, Func<string, string, Task<SignInResponse>> and Func<IGPlusInitializer, Task<SignInResponse>> so you'd still end up with an if statement.
Can I return a Func when the method is called? this ways I can return either of the three func based on a quick switch case. The issue would be (if it's possible) what would be the generic response (or the common response) type of the method that returns either of these three methods
The generic Func works as follows:
The last datatype that you define in Func - "output" in this case should be the return type of the method which you are going to that particular function and the method should also be static.
This might help:
Func<LogInType, string> Login = LoginMethod;
private static string LoginMethod(LogInType loginType)
{
if (loginType == LogInType.Facebook)
return "Facebook";
if (loginType == LogInType.GooglePlus)
return "GooglePlus";
if (loginType == LogInType.UserNameAndPassword)
return "UserNameAndPassword";
return "Default";
}
The return type in the above example is string just for explaining.
ok, so in javascript, we can declare an object like this,
var obj={name:"Irshu",age:22};
console.log(obj);
How do we do the same in c#? the reason i ask because my function need to return a string and a bool together. I dont want to create a class for it, and i dont want to use the dictionary. Are there any alternatives?
public void Message(){
var obj=GetObject(val);
Messagebox.Show(Convert.ToString(obj.ind));
}
public object GetObject(string val){
return new {ind=val,flag=true};
}
This is not valid, is it?
.Net supports ExpandoObject since .NET 4.
http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject%28v=vs.110%29.aspx
It lets you declare the object and add properties as your would in javascript.
Traditionally it is for JS interop and I can't recommend it for production work. Tuple<T> is more appropriate as you get strong typing for free. Ultimately you will write less code and see less runtime errors.
What you have in your code is an anonymous type. Anonymous types cannot exist outside the scope in which they are declared. Generally, we use these for transforming LINQ results to temporary objects.
You can't return anonymous types from a method. You can do however something like this:
public void Message(){
var obj = new { ind = "oaiwejf", flag = true };
Messagebox.Show(obj.ind);
}
EDIT
Check this MSDN article
turns out, its posible, one genius on the internet posted this:
public void Message()
{
var obj=GetObject("Irshu");
var y= Cast(obj, new { ind= "", flag= true });
Messagebox.Show(y.ind); //alerts Irshu
}
public object GetObject(string val){
return new {ind=val,flag=true};
}
T Cast<T>(object obj, T type)
{
return (T)obj;
}
The most confusing error I have ever seen in ASP. I have done method calls like this before, and have no issue in other spots of my code.
First of all the class:
namespace LocApp.Helpers.Classes.LocationHelper
{
public class QueryHelper
{
private LocAppContext db = new LocAppContext();
public static IEnumerable<Service> getAllService()
{
using (var db = new LocAppContext())
{
var service = db.Locations.Include(s => s.LocationAssignment);
var serv = (from s in db.Services
where s.active == true
select s).ToList();
return serv;
}
}
}
}
Pretty easy to understand whats going on. So lets call the method:
IEnumerable<LocApp.Models.Service> Service = new LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService(Model.id);
getAllServices(Model.id) is throwing the error "is a method but treated like a type" , um no its not be treated like a type....
whats going on?
Well it's exactly as the error message says. getAllService() is a method:
public static IEnumerable<Service> getAllService()
But you're trying to use it as if it were a type with a constructor:
Service = new LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService(...)
The new part is the mistake here. You don't want to call a constructor, you just want to call a method. It's a static method, so you don't need an instance - you can just use:
Service = LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService(...)
Note that if you have appropriate using directives, follow .NET naming conventions and take care about singular/plural names, your code will be easier to follow:
var services = QueryHelper.GetAllServices(...);
Do you not simply mean:
IEnumerable<LocApp.Models.Service> Service = LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService();
Get rid of the new bit, essentially, and that method doesn't take any parameters either - I'd assume you'd run into that problem after you removed the new bit.
Your getAllService method doesn't take any arguments, so you should call it without. Also it is a static method so don't use the new keyword:
IEnumerable<LocApp.Models.Service> Service = LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService();
I'm struggling with this new to me Delegates + Handlers thing.
It seems the right solution for me, but I can't tie everything up.
Will try my best to explain what I want to achieve.
First of all, I'm using .NET 4.0 Framework + Photon Server (For multiplayer games)
(There's no need in Photon experience in order to answer me)
So actually, what happens right now, is that the client (a game) sends operation to my server, which I must recognize and call a certain function on my server according to the operation code that I receive.
Here's how it looks right now:
switch (operationRequest.OperationCode)
{
case 1:
if (operationRequest.Parameters.ContainsKey(1))
{
Log.Debug("Received: " + operationRequest.Parameters[1]);
OperationResponse response = new OperationResponse(operationRequest.OperationCode);
response.Parameters = new Dictionary<byte, object> {{1, "Response Received"}};
SendOperationResponse(response, sendParameters);
Flush();
}
break;
}
This actually works fine for me. But, I know for sure there will be like 200+ operation codes.
Not really nice to switch all of them, It's better to call a function (handler) that is assigned to that Operation Code.
According to my knowledge, here where delegate comes handy.
I want to have a Dictonary, that stores "byte,Handler"
where "byte" is operation code
where "Handler" is a delegate to the function
Something like that I assume:
byte operationCode = operationRequest.OperationCode;
if(dictionary.ContainsKey((operaionCode)) {
dictionary[operationCode](someArguments);
}
From this point, I'm totally confused.
How to create such Dictionary, how to create handlers, assuming that I want to store them in different classes, how to delegate them and store in a dictionary.
Here's what my friend suggested me (and then vanished for one week, so I can't ask him again):
Create a dictionary
Dictionary<byte, name> = new Dictionary<byte, name>();
Add handlers to that dictionary
dict.Add(operationCode, MoveUnit);
Initialize delegates (Where!?)
???
Define your handlers
private void MoveUnit(SendParameters sendParameter) {...}
If.. anyone, by any chance, got the idea, please assist me.
Thanks to everyone for time spent on reading this. :|
Assuming all the methods take a SendParameters, then you really want:
private static readonly Dictionary<int, Action<SendParameters>> Actions =
new Dictionary<int, Action<SendParameters>>
{
{ 1, MoveUnit },
{ 2, AttackUnit }
};
...
static void HandleRequest(Request request)
{
Action<SendParameters> action;
if (Actions.TryGetValue(request.OperationCode, out action))
{
action(request.Parameters);
}
}
static void MoveUnit(SendParameters parameters)
{
}
static void AttackUnit(SendParameters parameters)
{
}
It gets slightly trickier for instance methods - the static dictionary doesn't know about instances, so it may make sense to make the action take the instance. Assuming this in a class called Foo, you might want something like:
private static readonly Dictionary<int, Action<Foo, SendParameters>> Actions =
new Dictionary<int, Action<Foo, SendParameters>>
{
{ 1, (foo, parameters) => foo.MoveUnit(parameters) },
{ 2, (foo, parameters) => foo.AttackUnit(parameters) }
};
private void MoveUnit(SendParameters parameters)
{
}
It's a bit uglier, admittedly... you really want to be able to build delegates which implicitly take "this" as the first parameter. There are ways of doing that, but they're a bit more complicated.
I would like to implement what I know as a CVAR System, I'm not entirely sure on what the official name of it is (if any).
It's essentially a system used in some programs and video games, where a user can pull down a console and input a command, such as "variable 500" to set that variable to 500. Instances of this can be found in any Half-Life game, Doom and Quake games, and many more. The general idea seems to be to hide the underlying architecture, but still allow protected access, for instance, one may be able to view the value for, say, gravity, but not change it. Some of these values may also be functions, for instance, a user may be able to input "create " to create an enemy type at their location, or some other location specified.
Looking through the Half Life 2 SDK, and from what I remember on the GoldSrc SDK, it seems like they at least implemented "flagging" of sorts, where certain commands would only work under certain conditions, such as if another value was set, or if the user has some permission level.
My initial thought was to create a Dictionary, or an object similar to do that, and use that to bind string values to function delegates, as well as keep a "protection" level of sorts, to limit usage of certain commands. However, this seems rather cumbersome, as I believe I would have to go through and add in a new entry manually for each value or function I wanted to implement. I also don't know if this would give me the control level I'm looking for.
I believe ideally what I would like would be a CVAR System class, as well as a Register function that can take it say, a variable/function delegate, a string to access it, and whatever protection level I need. This way I can add what I need as I see them, so everything is still in it's related classes and files.
I'm really just looking for some ideas here, so my questions are:
Has anyone ever done something like this before, and if so, how?
Would my implementation work? (Theoretically, if not, can you think of a better way?)
If someone is more knowledgeable with how one of the previously mentioned titles does it, can you elaborate on that a bit? It seems to be hard to find documentation on them.
I'm not really looking for specific code, just more of structuring design. And it doesn't have to be "commercial" or work just like another, I just need something to get me going.
Were you thinking about something like this?
class CVAR
{
[ProtectionLevel(CVARFlags.InGameOnly | CVARFlags.Admin)]
private float gravity = 0.1f;
[ProtectionLevel(CVARFlags.InGameOnly | CVARFlags.Admin)]
private float friction = 0.1f;
[ProtectionLevel(CVARFlags.ReadOnly)]
private string serverVersion = "x.x.x";
public void SetCVARValue(string commandLine) {
string cvarName = GetCvarName(commandLine); // parse the cmd line and get the cvar name from there
object cvarValue = GetCvarValue(commandLine); // parse the value from the string
FieldInfo field = typeof(CVAR).GetField(cvarName);
object[] attributes = field.GetCustomAttributes(typeof(ProtectionLevel), false);
if(attributes.Length > 0) {
ProtectionLevelAttribute attr = (ProtectionLevelAttribute)attributes[0];
if(attr.CheckConditions(World.Instance)) {
field.SetValue(this, cvarValue);
} else {
// error report
}
}
}
}
You could write a parser that looks for commands like
/object_property value
/object_method arg1 arg2
A dictionary, like you suggested, could map those strings to properties and functions. The creation of the dictionary could be done dynamically using reflection by looping through eligible objects, taking their public methods and accessors, and generating a string for them.
Then the dictionary could be mapped in a class for convenience and error checking.
For the methods, the dictionary values could be delegates that take 0..n arguments, for the properties/fields, you will need to be able to some data binding between your actual fields and the dictionary value. UNLESS, your objects themselves refer to the dictionaries for their values, in which case the values only live in place.
To do so, you could simply register your properties using reflection in the object constructor, then call the dictionary in your properties.
[Flags]
public enum CVarAccessibilities
{
Settable,
Gettable
}
public class CVar<T>
{
public CVarAccessibilities Accessibility { get; set; }
T val;
public T Value {
get { return val; }
set
{
if (!Accessibility.HasFlag(CVarAccessibilities.Settable))
return; // just don't set it, maybe print some warning
val = value;
}
}
}
public static class CVarRegistry
{
static Dictionary<string, Object> CVars;
static CVarRegistry { /* use reflections to initialize the dictionary */ }
public static T GetValue<T>(Type owner, string paramName)
{
CVar cvar;
if (!CVars.TryGetValue(owner.Name + "_" + paramName, out cvar)
throw new MyCustomException();
return (T)cvar.Value;
}
public static void SetValue<T>(Type owner, string paramName, T value)
{
CVar cvar;
if (!CVars.TryGetValue(owner.Name + "_" + paramName, out cvar)
throw new MyCustomException();
cvar.Value = value;
}
}
public class MyObject
{
public static int MyRegisteredValue
{
get { return Global.CVarRegistry.GetValue<int>(typeof(MyObject), "MyRegisteredValue"); }
set { Global.CVarRegistry.SetValue(typeof(MyObject), "MyRegisteredValue"); }
}
}
Hope that helps!
This is more commonly known as 'tweak' variables.
Good discussion here: https://gamedev.stackexchange.com/questions/3631/tweaking-and-settings-runtime-variable-modification-and-persistence