Contravariant parameters? - c#

This is probably a stupid question but, I have a method I use to make the syntax of a page a little more easy to read
public void Do(Delegate method, DispatcherPriority priority = DispatcherPriority.Normal)
{
this.Window.Dispatcher.BeginInvoke(method, DispatcherPriority.Background);
}
then I can write
Do(new Action(() =>
{
//DoStuff()
}));
However, I'd like to move the Action up into the Do Method so I can write more Simply:
Do(() =>
{
//DoStuff()
}));
But I'm a bit sure how to write the contravariant parameter to do the Do Method?

Lambdas are untyped, so this is not possible.
If you don't care about method-arguments, which appears to be the case, why not change the method signature to :
public void Do(Action method,
DispatcherPriority priority = DispatcherPriority.Normal)
Then, the second sample will work fine since the compiler will be able to implicitly convert the lambda to an Action.
If you really want to accept an instance of any delegate-type that represents a method that takes no arguments, you'll have to stick to something like what you currently have.

Related

C# Question about passing delegates as parameters

I have a question regarding delegates. So in the Threading class, there is a method called public Thread(ThreadStart start) this method takes in a parameter of ThreadStart which is a void delegate defined by Microsoft. What I can't seem to wrap my head around is the fact if I pass a method inside the parameter of Thread(ThreadStart start) it doesn't give me an error which is great. But why is it when I try to pass a delegate inside this parameter that is not type ThreadStart it gives me an error. I understand the signature of this method takes a delegate of type ThreadStart but then why can I put any method in without an issue but forced to use a delegate of ThreadStart for it not to give me an error. But I can enter any method I want as long as it doesn't have a parameter. Sorry if this is a basic question when am doing the stuff I like to know why a certain thing does something otherwise it bugs me. My guess is that maybe when you define a parameter with a type of delegate. It will let you enter any method you want as long as it fits the delegate's signature. But when you pass a delegate inside a parameter that is a specific delegate it will want you to use the same delegate as the type?
In general you can turn a parameterized method into a non parameterized signature call
Just do something like:
var myThread = new Thread(() => MethodWithParemeters(Parameter));
doing () => Foo() uses linq (I think) to create a new method that calls Foo
When a delegate is defined it attaches the signature to the name. So for:
public delegate void ThreadStart();
So any ThreadStart delegate must have a matching signature. So a function with another signature can't be passed to anything expecting a ThreadStart delegate as the parameter.
Since you raised the issue. I suspect what your code is needing is the constructor:
Thread(ParameterizedThreadStart)
Where ParameterizedThreadStart is:
public delegate void ParameterizedThreadStart(object obj);
And the object that you pass is your own class or structure.
If I understand the question correctly you are asking why Case 1 succeed, but case 3 does not compile:
public delegate void MyDelegate1();
public delegate void MyDelegate2();
public void MyMethod() { }
public void AcceptDelegate(MyDelegate1 md) { }
public void Example()
{
AcceptDelegate(MyMethod); // Case 1: Works
AcceptDelegate(() => {}); // Case 2: Also Works
MyDelegate2 delegate2 = MyMethod;
AcceptDelegate(delegate2); // Case 3: Fails, cannot convert delegate
AcceptDelegate(new MyDelegate1(delegate2)); // Case 4: Works, since an explicit conversion was used
AcceptDelegate(() => delegate2());// Case 5: Works
}
The reason that case 3 fails is that the delegate types are different.
The reason that case 1 work is that the compiler uses the overload resolution rules to find a method with name MyMethod and have a compatible signature to MyDelegate. I'm not knowledgeable enough about the compiler to cite the exact rules that applies in this specific case. The important thing is that MyMethod is not e delegate, it is a 'method group' that can resolve down to a specific method that can be converted to a delegate.
See How to convert delegate to identical delegate for more additional info.

Generic method calls another generic with a concrete overload with an out parameter: concrete version is never used

There are several similar questions about generic methods with concrete overloads here on SO and most of them say essentially the same thing: Generic overload resolution is done at compile time so if you want to use a concrete overload, you may need to use dynamic in order to have the runtime decide which overload to use. OK, cool--I understand that. None of the questions I've found deal with an out parameter and I'm wondering if there's a better way to handle this than what I've done. Let's start with the most basic case (my code was all written and tested in LinqPad):
void Main()
{
string x = "";
var g = new GenericTest();
g.RunTest(x); //Ran from TryFoo<T>
g.RunTestWithDynamic(x);//Ran from TryFoo(string)
g.Foo(x); //Ran from TryFoo(string)
}
public class GenericTest
{
//public void RunTest(string withInput) => Foo(withInput); <-- This would fix it
public void RunTest<T>(T withInput) => Foo(withInput);
public void RunTestWithDynamic<T>(T withInput) => Foo((dynamic)withInput);
public void Foo<T>(T withInput) => Console.WriteLine("Ran from TryFoo<T>");
public void Foo(string withInput) => Console.WriteLine("Ran from TryFoo(string)");
}
Here are some things to note:
RunTest is a generic method that calls another generic method, Foo. When I call RunTest, it appears the compiler doesn't follow all the way from the call site to see that g.RunTeset is passing in x which is a string and link it all up so that the Foo(string) overload is called; instead, it just sees that RunTest<T> is calling Foo. It doesn't make different "paths" based on different input values of T. OK, that's fair and understandable.
If I call Foo directly from my Main method, the compiler is smart enough to see that we are calling Foo with a string directly and correctly selects the concrete overload.
As the linked SO posts describe, I can call RunTestWithDynamic which will change which overload is used at runtime based on value. It feels just a bit "hacky", but I'm good with this solution.
I've commented out a line: a concrete overload of RunTest. This would be essentially the same as calling Foo directly. If that were un-commented, it would fix everything. Alas, that is not an option for me in my case.
Now, what if the T is for an out parameter? Consider the pattern used by, say, int.TryParse where you return a bool to indicate if it succeeded or not, but the value you actually want is an out. Now you can't really do dynamic resolution because you can't cast an out parameter. I considered doing something where I make a default(T) and then casting that to dynamic, but if that ever works well anywhere else, there is the problem of reference types that default to null to deal with. Nope, that doesn't work, either.
In the end, the best I could come up with was this:
void Main()
{
string x;
var g = new GenericTest();
g.TryRunTest(out x); //Ran from TryFoo<T>
g.TryRunTestWithDynamic(out x); //Ran from TryFoo(string)
g.TryFoo(out x); //Ran from TryFoo(string)
}
public class GenericTest
{
//This would fix it, but in my case, not an option
//public bool TryRunTest(out string withOutput) => return TryFoo(out withOutput);
public bool TryRunTest<T>(out T withOutput)
{
return TryFoo(out withOutput);
}
public bool TryRunTestWithDynamic<T>(out T withOutput)
{
if(typeof(T) == typeof(string))
{
var retval = TryFoo(out string s);
withOutput = (T)(dynamic)s;
return retval;
}
return TryFoo(out withOutput);
}
public bool TryFoo<T>(out T withOutput)
{
withOutput = default(T);
Console.WriteLine("Ran from TryFoo<T>");
return true;
}
public bool TryFoo(out string withOutput)
{
withOutput = "Strings are special";
Console.WriteLine("Ran from TryFoo(string)");
return true;
}
}
You can see that TryRunTestWithDynamic has to look for the concrete string type specifically. I can't figure out a way to do it so that I can just add overloads and then use dynamic resolution to select the overload I want without having to spell it all out (and let's face it--spelling it all out kind of kills the whole point of having overloads in the first place).
In his post I linked to above (and here for good measure), Jon Skeet mentions using MethodInfo.MakeGenericMethod as an alternative. Here he talks about how to use it. I'm curious if that would help me here, but I can't figure out how to use it with out parameters.
So, here are my specific questions:
While, yes this DOES work, it is VERY clunky. Is there a better way to do this? Most importantly, is there a way I can consume overloads that wouldn't require me checking each type specifically?
Is there a way to use the MethodInfo.MakeGenericMethod route using out parameters and would that help me?
Let's say we could wave a magic wand and all of a sudden a language feature was added to C# that would give us the option to force dynamic resolution for generic methods (either for all cases, or only for the case where the generic parameter is for an out, like my main problem). Taking from the above examples, let's say we had something like this:
//The following are all invalid syntax but illustrate possible
// ways we may express that we want to force dynamic resolution
//For out parameters
public void TryFoo<T>(dynamic out T withOutput){...}
//"dynamic out" could be a special combination of keywords so that this only works
// with output variables. Not sure if that constraint buys us anything.
// Maybe we would want to allow it for regular (not out) generic parameters as well
public void Foo<T>(dynamic T withInput){...}
public void Foo<dynamic T>(T withInput){...}
public void dynamic Foo<T>(T withInput){...}
Let's not focus on the syntax itself; we could easily use a different notation--that isn't the point. The idea is simply that we are telling the runtime that when we get to TryFoo<T>... pause and check to see if there is a different, better fitting overload that we should switch to instead. I'm also not particular on whether we are checking for a better resolution on T specifically, or if it applies to the method in general.
Is there any reason why this might be a BAD thing? As he often does, Eric Lippert makes some interesting points about generic and concrete overloading resolution when inheritance is involved (Jon Skeet is also quoted in other answers, as well) and discusses why choosing the most specific overload isn't always the best choice. I'm wondering if having such a language construct might introduce similar problems.
OK, so I proposed the idea of adding support for opting-in to dynamic binding at the C# GitHub and was given this alternate solution which I like MUCH better than what I am currently doing: ((dynamic)this).TryFoo(out withOutput);
It would look like this:
public bool TryRunTestWithDynamic<T>(out T withOutput)
{
return ((dynamic)this).TryFoo(out withOutput);
}
I will reiterate the warning I was given: this only works for instance methods. In my case, that's fine, but if someone else had a method that was static, it wouldn't help, so the second part of my question (regarding MethodInfo.MakeGenericMethod) may still be relevant.

What means this GoAsync(() => GetPackagesExecute(serviceType)); in C#?

I have a piece of code like this:
GoAsync(() => GetPackagesExecute(serviceType));
how to understand this code?, what means the braces without name method?
It is difficult to tell you exactly what those methods do, because they aren't "standard" methods...
The GoAsync for example could have various signatures:
void GoAsync(Action action);
void GoAsync(Func<FooType> func);
or even more complex, like:
void GoAsync(Expression<Action> action);
void GoAsync(Expression<Func<FooType>> func);
Let's say that the GoAsync has a signature like:
void GoAsync(Action action);
Now, GoAsync accepts as a parameter a delegate, that is a reference to a function. This function mustn't have any parameter and mustn't return anything (if we had chosen the second signature, void GoAsync(Func<FooType> func);, then the function would have returned a FooType object). GoAsync then can execute that function reference and do some operations on it. Note that GoAsync could even not execute that delegate.
() => GetPackagesExecute(serviceType)
This creates an anonymous function that doesn't have any parameter and that has as the body GetPackagesExecute(serviceType), so in its body it simply executes the GetPackagesExecute with a parameter serviceType (that is probably a local variable or a field/property).
In functional language this is called currying (creating a function that calls another function, the called function has more arguments than the created function). In this case the anonymous function has 0 arguments, GetPackagesExecute has one argument.
Technically this anonymous function could return the return value of GetPackagesExecute(), so it is equivalent to both:
void AnonymousMethod()
{
GetPackagesExecute(serviceType);
}
and to
FooType AnonymousMethod()
{
return GetPackagesExecute(serviceType);
}
The exact "type" of the anonymous function is selected by the C# compiler based on the signature of GoAsync(). This is called type inference in lambdas.
Now, the
GoAsync(() => GetPackagesExecute(serviceType));
together will:
Create an anonymous function (it is a little more complex than this... there is some C# compiler-magic here, but you can ignore it)
Create a delegate to that anonymous function (this is implicit, and done by the C# compiler)
Call GoAsync passing this delegate to it
The GoAsync will probably do something with the delegate
It is something called a lambda expression. It is a fairly advanced topic but it is a pretty core piece of functionality. It is really hard to explain it all so I have found this link for you to look through.
https://msdn.microsoft.com/en-us/library/bb397687.aspx
It will explain everything however depending on your level of experience it might not make any sense, it should give you a jumping block to move on and investigate it further.

Passing methods as parameter vs calling methods directly

I have seen methods passed as parameters in some examples. If I can call one method from another method, why should I pass method as a parameter? What is the purpose behind this design?
Calling one method from another
Passing method as parameter using delegate or Action
Passing in a method as a parameter can be used to prevent dependencies and coupling. Let's take a look at how this can be used for the Strategy pattern:
Let's say we have a method PrintReport, which prints a given list of items, which might be sorted by Name or by Type, based on a parameter. This is the naive approach:
public void PrintReport (List<Item> data, SortOrder sortBy)
{
List<Item> sortedItems;
switch (sortBy)
{
case SortOrder.Name: sortedItems = SortByName(data); break;
case SortOrder.Type: sortedItems = SortByType(data); break;
}
Print(sortedItems);
}
It's simple but it works. But what happens when we want to add a new sort order? We need to update the SortOrder enum, go into PrintReport and add a new case and call the new SortByWhatever method.
But if we passed in a method as a parameter, our PrintReport can be simpler and not care about the sort implementation:
public void PrintReport (List<Item> data, Func<List<Item>, List<Item>> sorter)
{
List<Item> sortedItems = sorter(data);
Print(sortedItems);
}
Now the sorting function can be defined anyway, possibly even in a different assembly that PrintReport isn't even aware of. It can be a lambda function or an anonymous method defined ad-hoc. But in all cases, our method will receive the delegate, use it to sort, and then print the report.
Here's a usage example. At first it looks like we merely moved the switch/case outside of the function, which is important enough since it allows different callers to have different logic. But watch for the third case.
public void HandleData()
{
switch (ReportItemOrder)
{
case SortOrder.Name: PrintReport(data, SortByName); break;
case SortOrder.Type: PrintReport(data, SortByType); break;
case SortOrder.Whatever:
Func<List<Item>, List<Item>> customSort = (items) => /* do something */;
PrintReport(data, customSort);
}
}
Delegates are commonly used to decouple classes and interfaces from each other.
Here's a specific example. Suppose you had a UI class that was responsible for drawing a calendar, but you didn't want it to know exactly how to format the DateTime values into string.
You could define the class something like this:
public sealed class MyCalendarDrawer
{
private readonly Func<DateTime, string> _dateFormatter;
public MyCalendarDrawer(Func<DateTime, string> dateFormatter)
{
_dateFormatter = dateFormatter;
}
public void Draw()
{
// Do some work that involves displaying dates...
DateTime date = DateTime.Now;
string dateString = _dateFormatter(date);
// Display dateString somehow.
}
}
That way, MyCalendarDrawer doesn't need to know how to format the dates - it is told how to do it by being passed a delegate Func<DateTime, string> that it can call to do so.
Treating functions as first class types has its advantages. It gives you functional programming possibilities.
Take the classic case of "Event Handling" for example, you will certainly send a function pointer to another function as a call-back on occurance of an event.
Similarly, here is another hypothetical example
private void CallMeBack(out int type, Func<int> action)
{
type = action();
}
Now I can supply any function to this, like CallMeBack(a, ()=>return 1); and CallMeBack(a, ()=>return 2);
You should read about Delegates.
As example, delegates are useful to define a dynamic callback on a given method completion.
Pseudo-code example:
doSomething(); //your code
updateInterface(continueDoingSomething); //a generic method, passing a delegate
...
doAnythingElse();
updateInterface(continueDoingAnythingElse);
In this example, you could define a generic method "updateInterface" which, as a callback, calls a dynamic method passed in as a delegate.
If not using delegates, you would have to implement two (or more) different methods:
void updateInterfaceAndContinueDoingSomething(){}
void updateInterfaceAndContinueDoingAnythingElse(){}
Truth is, every single example where functions are passed to other functions can be expressed in term of objects implementing a given interface passed to functions.
In other words, there are no obvious reasons delegates are better than interfaces. Upcoming lambdas in Java are an example than you don't really need to be able to pass a function to another function to be able to have a concise syntax.
In yet another words, the ability to pass a function to another function is just a tool in your programmer's toolkit just as passing objectd to functions is. And while this is arguable which is better, one can have a language that doesn't support passing functions to functions at all - Java - and still be able to have the same expressiveness.

C# - Is it possible to get the owner type of a method from an Action?

I have a class that implements an Interface with some methods.
I also have method with an Action parameter where I pass the Interface method.
Is it possible to get the type of the owner that has the method?
EDIT
This is the wrapper:
private void Wrapper (params Action[] actions)
{
var action = actions.FirstOrDefault();
var type = action.Method.DeclaringType.Name;
}
private void test()
{
Wrapper(()=> _GC.ChargeCancellation(""));
}
For demonstration purpose I don't iterate through the collection.
I want the type of _GC.
Actually, I should've spotted this to begin with but since Jon didn't either I'm not feeling too bad about it :)
The code you have to begin with in your question does not compile:
Wrapper(() => TestClass.Hello);
This is not complete code. You either have to have:
Wrapper(TestClass.Hello);
^
|
+-- notice the missing () => here
or:
Wrapper(() => TestClass.Hello());
^
|
+-- notice the added parenthesis here
And now that you have edited your question, it is clear you have the second form.
There's a subtle difference between the two. Subtle to us, but important to the compiler:
Wrapper(TestClass.Hello);
^------+------^
|
+-- This is a method group
Wrapper(() => TestClass.Hello());
^------+--------^
|
+-- This is a method call
A method group is a reference to a method (or its overloads), a method call is executable code.
The difference to the compiler is that in the first piece of code, the compiler will wrap up the method group into an action, basically compile it like this:
Wrapper(new Action(TestClass.Hello));
and thus, you're passing that method to the Wrapper method, inside an Action delegate.
However, the second form is handled altogether differently. The compiler now produces a new method to contain your code, and then passes the new method to the Wrapper method instead of the code you had.
Thus, your code actually looks like this:
public static void Main()
{
Wrapper(new Action(TempMethod1));
}
private static void TempMethod1()
{
TestClass.Hello();
}
And that's why you're seeing the form class as the owner of the method, because that's what it is.
The reason I asked in a comment whether you were taking a delegate or an expression is that my brain was working at half speed. It detected something odd, but not the whole picture.
If you want to pass code like this to a method, and work with it, you have two choices:
For a delegate, work with reflection, decompile the code and analyze it, find the method call and figure out which class it is made on
For an expression, analyze the pieces of the expression (this requires C# 3 or above)
Since neither is trivial I'm not going to post any code here, suffice to say that what you're asking warrants a new question. Of the two, I suggest you go with the expression way if you can.
EDIT: I misread the example, and thought it was using a method group conversion. You can certainly get the method in the delegate itself:
public void Wrapper(Action action)
{
MethodInfo method = action.Method;
Type type = method.DeclaringType; // TestClass
string name = method.Name; // Hello
}
I'm not sure off the top of my head which method will be used if you pass in a delegate instance with multiple actions... but it shouldn't be a problem in this case.
Doh - I misread the question. When you use a lambda expression, that's going to build an extra method in the calling class - and that is the method which contains the reference to _GC.
If you don't want this behaviour, you should change Wrapper to accept params Expression<Action>[] actions - you can then examine the expression trees appropriately and find out the calls that way. It's a bit fiddly sometimes, but it's doable. Look at the Body of the expression tree, which will represent the method call. Note that if you still want to execute the actions, you can call Compile on the expression tree to obtain a delegate.

Categories

Resources