I have an extension function as such...
public static class EventLibrary
{
[EventCollection]
public static Event Sequence(this Event ev)
{
ev.Started += (args) =>
{
// do something!
}
}
}
I then, inside Event, I look at the delegate subscribers using the following...
var dels = new List<Delegate[]>();
if (Started != null)
dels.Add(Started.GetInvocationList());
The reason is to try and detect whether the function that created the closure has an attribute, as in this example, EventCollection. On the Delegate object, both DelcaringType and ReflectedType return something like EventLibrary+<Sequence>c_AnonStorey1 but this is as far as I get.
I would love to do this without any string operations but I'm not sure it's possible... Does anyone know?
I believe there is no way to do that reliably. The closest you can do is to get the DeclaringType, but there isn't anything like DeclaringMethod.
It seems you already noticed you could try using the name of the lambda method, but doing so would be fragile (what about method overloads?) and might not work the same in other languages (like VB.NET) or future versions of the compiler.
I think the best way to do this is to somehow configure Event to tell it what you want. Possibly something like:
var eventCollectionEvent = ev.EventCollection;
eventCollectionEvent.Started += …;
Related
I have this piece of code that consumes too much vertical space and it's too verbose.
if (property == null)
{
throw new XamlParseException($"Cannot find a property named \"{Name}\" in the type {underlyingType}");
}
Isn't there an equivalent method, but more legible and compact?
Something in the shape of
ThrowIfNull<XamlParseException>(message)
You can always create an extension method:
public static class ClassContracts {
public static void ThrowIfNull(this Object item)
{
if(item == null) throw new XamlParseException("Your message here", null);
}
}
This way you use up less space which is what you were talking about, and you can use the code over and over whenever you need it. I have a library of these for testing for nulls etc. I like doing it this way over Code Contracts, because that requires the binary rewriter and depending on your environment, your build system (if you have one) may not support doing that. Ultimately, Code Contracts do more than just this, but in a pinch this offers a quick and concise way of checking for nulls and other conditions easily in code as you can create other ones like:
public static void CheckForCondition <T>(this T item, Predicate<T> p, Func<Your_Exception_Type> createException)
{
if(p(item)){throw createException();}
}
With this base method, you can then create other ones and create overloads, etc. have the predicate, or the exception method already created.
public static void CheckForNullCondition<T>(this T item)
{
item.CheckForCondition(x => x == null,
() => new Exception("Item is null"));
}
Extension Methods
I have no knowledge of such method but you can either create it by yourself or just move message to the resources file/internal constant (of course if the space taken by it is the case).
Extension approach is also viable option if it is acceptable for you (I mean having such extension for PropertyInfo or any other type).
I want to know whether passed object is actually reference of variable of specific class or not.
Consider below structure of some class 'ClassA':
public classA
{
string variable1;
int variable2;
method1(ref variable1);
}
Now if in class that contains implementation of method1(Obj object1), I want to check that 'object1' is which variable of specific 'ClassA' ?
Because I want to check in if condition like if object1 is variable1 of ClassA then //to proceed with logic....
Please provide a small example for the same.
The closest you could get to this in safe code is using expressions, but honestly you probably don't want to do this. It'd be a nightmare to try and debug, and there's probably another way to go about it. For example, is there any reason variable1 can't be of a specific type?
Now that I've spoken reason, the approach using expressions goes something like this (This is from a debugging helper, I would never use this approach in anything remotely serious. Note: A lot of exception handling and other code is stripped from this, also note how ugly and hackish it looks, that's all why you really shouldn't do this):
public static void DoStuffWithParameter<T>(Expression<Func<T>> paramExpression)
{
if (paramExpression == null) throw new ArgumentNullException("paramExpression");
var body = ((MemberExpression)paramExpression.Body);
var paramName = body.Member.Name;
var param = ((FieldInfo)body.Member)
.GetValue(((ConstantExpression)body.Expression).Value);
var declaringType = param.DeclaringType;
var paramValue = paramExpression
.Compile()
.Invoke();
if(declaringType.Equals(typeof(ClassA)))
{
//do stuff
}
}
To use that you'd use something like:
DoStuffWithParameter(()=>myClass.VarA);
I found solution. The simplest way to do this is to pass object of sender in method1 and proceed, like below.
method1(Object sender, ref Object var)
{
if(sender is classA)
{
classA senderObj= (classA) sender;
if((string)var == senderObj.variable1)
{
// Logic for variable1
}
else if((int)var == senderObj.variable2)
{
// Logic for variable2
}
. . .
}
}
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 want to start a subprocess and watch it's redirected output. That not
a problem for me in C#, but I try to understand RX, so the game begins ...
I have a static extension method for process, which looks like this:
public static IObservable<IEvent<DataReceivedEventArgs>> GetOutput(this Process that)
{
return Observable.FromEvent<DataReceivedEventArgs>(that, "OutputDataReceived");
}
I create an observable and subscribe to it like this:
Process p = ........
var outObs = p.GetOutput();
var outSub = outObs.Subscribe(data => Console.WriteLine(data));
This is not completely wrong, but I am getting:
System.Collections.Generic.Event`1[System.Diagnostics.DataReceivedEventArgs]
while I am expecting to get strings :-(
So, I think, my extensionmethod returns the wrong type.
It would be really good, if someone could explain me, what's
wong with my extension methods signature.
Thanks a lot,
++mabra
So, I think, my extensionmethod returns the wrong type
That's exactly it.
IEvent wraps both the sender and the EventArgs parameters of a tradition Event delegate. So you need to modify your code to look something like
public static IObservable<string> GetOutput(this Process that)
{
return Observable.FromEvent<DataReceivedEventArgs>(that, "OutputDataReceived")
.Select(ep => ep.EventArgs.Data);
}
If you're using the latest Rx, then the code is a bit different
public static IObservable<string> GetOutput(this Process that)
{
return Observable.FromEventPattern<DataReceivedEventArgs>(that, "OutputDataReceived")
.Select(ep => ep.EventArgs.Data);
}
the key here is to Select the EventArgs from the EventPattern/IEvent, and then grab the Data
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.