Can C# Delegates work this way? - c#

I'm trying to use delegates to cut down on my code in this project.
I have 4 DropDownLists in my asp.net page. In my codebehind file I'm binding them to different business object calls with data. Right now I have the following code:
DeptList.DataSource = bl.getAcademicDepts();
DeptList.DataBind();
TermList.DataSource = bl.getTerms();
TermList.DataBind();
InstructorList.DataSource = bl.getInstructors();
InstructorList.DataBind();
EEList.DataSource = bl.getEE();
EEList.DataBind();
This seems really repetitive so I decided to make a function as a shortcut
private void SourceAndBind(DropDownList d, <business layer method call>)
{
d.DataSource = <businesslayer method call>();
d.DataBind();
}
Then my first block of code simply becomes
SourceAndBind(DeptList, bl.getAcademicDepts());
SourceAndBind(TermList, bl.getTerms());
SourceAndBind(InstructorList, bl.getInstructors());
SourceAndBind(EEList, bl.getEE());
However, I don't know what to put for the second parameter. Each one of the business layer calls takes no parameters, but they each return objects of different types. I tried using delegates but I couldn't figure out how to create one without a defined return type or no parameters. Is it possible to achieve what I want with c#? I know that works in python which is where I'm coming from.

You don't need delegates to do this. Just declare the second parameter as object.
// Takes drop down list and data to assign to 'data source'
private void SourceAndBind(DropDownList d, object data) {
d.DataSource = data;
d.DataBind();
}
// Call methods from bussiness layer and bind results
SourceAndBind(DeptList, bl.getAcademicDepts());
SourceAndBind(TermList, bl.getTerms());
SourceAndBind(InstructorList, bl.getInstructors());
SourceAndBind(EEList, bl.getEE());
You could use delegates too. However, since you're only calling the method once, you can call the bussiness layer method to get the data and then pass the result to SourceAndBind. (Delegates would be useful for example if you wanted to choose one of several ways of loading the data, or if you wanted to delay loading until some later point).

Well, Func<object> would be a very general way of doing that. That's "a function with no parameters that returns an object". Any parameterless function returning a reference type should be convertible to that delegate type. However, your "usage" code wouldn't be quite right as it. It would be:
SourceAndBind(DeptList, bl.getAcademicDepts);
SourceAndBind(TermList, bl.getTerms);
SourceAndBind(InstructorList, bl.getInstructors);
SourceAndBind(EEList, bl.getEE);
Note the lack of brackets, which means these are method groups rather than method calls. (To follow .NET naming conventions I'd suggest renaming your methods to start with capital letters, btw.)
That's appropriate if you only want to call the method conditionally. As Tomas says though, you don't need to use delegates here. If you're happy for SourceAndBind to only get called after you've called the method, you can definitely just perform the method call in the argument and pass the result as object.

private void SourceAndBind(DropDownList d, Func<IEnumerable<object>> businessLayerMethod)
{
d.DataSource = businessLayerMethod();
d.DataBind();
}
IEnumerable<object> where object is your datatype.

Related

Is it possible to mirror a method?

for example, there are bunch of overloads of method:
public void MyLongFunctionName(string arg1,...) ...
public void MyLongFunctionName(int arg1,...) ...
//.... many different argument types
To make a shortcut of that long function, i used i.e. my() :
public void my(string arg1,...) ...
public void my(int arg1,...) ...
....
however, is something like this possible to make my() as a shortcut of MyLongFunctionName() , without defining bunch of my() methods (like above) ?
for example, in PHP you can copy function, like :
$my = MyLongFunctionName(arg1, arg2....);
//execute
$my(arg1, arg2....)
P.S. Note to all downvoters and duplicate-markers:
this topic is not duplicate, because that referred topic doesnt answer the question at all. It executes plain function, and even says, that it is not alias at all:
so, that topic doesnt solve the problem. instead, I want to mirror(a.k.a. ALIAS) whole overloads of specific method with i.e. my(), which can accept variation of parameters. so, please stop mindless downvotings of what you dont read.
I'm afraid what you are asking is not possible.
What you want is a kind of delegate for a whole bunch of methods. It's called a method group.
A method group is a set of overloaded methods resulting from a member lookup (ยง7.4).
For example something.ToString is a method group. It may contain one or more methods, depending on whether ToString has overloads for this specific class.
This is a compile time construct. You cannot put a method group into a variable, like you can with a single function. You can make a delegate from a method group, but that involves getting a specific overload and transforming only that into the delegate.

Overhead of delegate definition inside of another method

I'm curious to understand what's happening behind the scenes in a situation like this:
public static void OuterMethod() {
// some random code
var a = 42;
var b = "meaning of life";
Func<string, object> factory = (aString) {
// do something with a and b
return "Hello World";
};
// some more random code
factory("My string");
}
I'm particularly interested in cases where OuterMethod is called very often. In my case it's the MVC request pipeline where OuterMethod is called once for each request.
Am I incurring a lot overhead by having to build factory each time the method is called? I could easily move the Func outside of OuterMethod into its own static method however in my actual scenario because it is defined inside I have access to a lot of variables I need to do my calculation that I would otherwise need to include in the signature of a method defined outside. Maybe this is just a micro optimization but I would like to better understand how the compiler treats these kinds of statements.
The actual lambda is going to result in a new named method (you just don't know what that name is) being created at compile time (the exact semantics will vary based on some of the specifics).
The only work being done on each invocation of the method is the creation of a new delegate object that has its own pointer to the same named method. If constructing that one object instance is really too much for you (hint: its not) then you could save that work by extracting the delegate out of the method.

The usage of delegate

i saw that delegate is used for custom events. as far example
delegate string FuncRef(string Val);
FuncRef fValue = GetFieldName;
fValue("hello");
what i do here just declare delegate and assign a function name to delegate and call like fValue("hello"); whenever it is required.
instead of calling the GetFieldName() through delegate i can call it directly. so i just want to know why should i use delegate to call function where as we can call function directly....what is the advantage of calling any function through delegate.
so please tell me in what kind of scenario delegate usage is required except event handling. please guide me with sample code and simulate a situation where i need to call function through delegate except event handling. please show me some real life scenario where we have to call function through delegate.
The reason to use delegates instead of calling the function directly is the same reason you do
var taxRate = 0.15;
var taxAmount = income * taxRate;
instead of
var taxAmount = income * 0.15;
In other words: using a variable to hold a reference to a callable entity (a delegate is exactly that) allows you to write code that can change its behavior depending on the parameters passed to it (the value of the delagate we 're passing in). This means more flexible code.
For examples of code that uses delegates you can look at LINQ (of course), but there's also the "delegates 101" example which is relevant in any language: filtering a list.
delegate string FuncRef(string Val);
FuncRef fValue; // class member
if (condition1)
fValue = GetFieldName1;
else if (condition2)
fValue = GetFieldName2;
else
fValue = GetFieldName3;
// Another function
fValue("hello");
Microsoft's tutorial code on C# delegates presents another interesting use case. In their example, an object called Bookstore has a method ProcessPaperbackBooks which takes a book processing delegate and applies it to each item in the class.
The cool part is that then, if you need say, a method which collects all the ISBNs of all the books in the store, you don't need to change anything in the bookstore class, but only to define a function which acts on books and pass that into the ProcessPaperbackBooks method. Delegated goodness will occur, and your new function will be applied to every item in the bookstore. Snazzy, no?
http://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx
Basically any place where you want to be able to specify at runtime which function should be called.
The async BeginInvoke/EndInvoke pattern is a perfect example of this; the callback is specified via a delegate.
Shortly: You can use delegates and events members in combination to be able for example to assign an event handler to a class which does not know it before, the button class knows when it has to trigger the click event and does not know yet, internally, you will bind mybutton_Click handler to it.
Linq to objects makes extensive use of delegates:
myAnimals.Where(animal => animal.CanSwim)
the parameter supplied to the Where method ( animal => animal.CanSwim ) is a lambda expression that converts to a delegate that is applied to all elements in myAnimals.
One place I use delegates is my input handler (C#, XNA)
I have a public void OnKeyboardPress() delegate, which I bind to various functions when certain keys are pressed.
Input is a good example; rather than polling for it (i.e. every update you go 'is it ready yet?' you wait for it to call you)..such as a GUI. WPF events are delegates.
Delegates are 1st class objects. IOW you can refer to them, reassign them, etc, just like any other object.

Method writing pattern

I recently noticed the following code which basically defines a class method
public Func<string, string> SampleMethod = inputParam =>
{
return inputParam.ToUpper();
};
which is the same as doing it in the old fashioned way
public string SampleMethod(string inputParam )
{
return inputParam.ToUpper();
}
My question - why would I prefer the first over the second? My eyes are maybe more trained to understand the second style quicker. I find it similar to the difference between SMS lingo and plain old english.
Those two things are fundamentally different. The former is a field of a delegate type while the latter is really a method. The tiniest difference I can think of is that you can modify the first one dynamically at runtime and assign another method reference to it while the second is fixed.
You shouldn't normally prefer the first over the second if your purpose is to write a simple method for a class in C#.
An example that makes the first extremely fragile:
var c = new SomeClass();
c.SampleMethod = inputParam => inputParam.ToLower();
c.DoSomeTaskThatReliesOnSampleMethodReturningAnUpperCaseString();
c.SampleMethod = null;
c.DoSomeTaskThatCallsSampleMethod(); // NullReferenceException
This style of programming is common in language like Javascript where an object is fundamentally a dynamic creature built upon a simple dictionary.
They are actually not the same at all. The second is a regular member method, that returns ToUpper on the input string.
The first, on the other hand, is a Func member variable, that happens to point to a delegate, that implements the same functionality. However, as this is a method pointer, you can substitute the delegate with any other delegate of the same type at runtime. I.e. you can completely redefine what it means to call this method.
One benefit of the second way is it's better from a unit testing perspective - you can test your class and know that the method will correctly return the uppercase string. With the first method, you can change the method at runtime, so unit testing is much harder.

Passing a stored procedure call from a LINQ data context to another method. C#

I feel the answer to this may lie with delegates, but I am having a hard time grasping the concept of delegates. The main problem is that every explanation and example of delegates I have ever read are always round about ways of doing something you could accomplish without delegates so to me it does not teach me anything. I learn best by seeing real world examples.
Now that that is out of the way, here is what I want to accomplish. I have a Data Context (.dbml) with numerous stored procedures. I also have mutliple situations where I am using the exact same 20 lines of code to update one column in a table, but the only difference other than using a different datagrid, is the stored procedure being called. In an effort of reducing the amount of code used, I was hoping for a way to pass the stored procedure call from the data context object as a parameter. That way I can move all that code to one reusable function. Is this even possible? I am using Visual Studio 2008 and C#.
Thanks for any guidance.
While I can't help you with the sql / stored proc side of things, I can try explain delegates, at least from the C# point of view.
While normally you declare functions as being part of a class (and hence they are strongly attached to the class), sometimes you want to put them in a variable. Once you do this, you can then pass it around, much like you would with any other variable.
So we know that a string is the kind of variable that you stick text into. Following that, a delegate is the kind of variable that you stick functions into. This however is very confusing, as C# isn't consistent or clear with how it names things in your code. Observe:
public void WriteText() {
Console.WriteLine("Hello");
}
...
Action x = WriteText;
x(); // will invoke the WriteText function
Note we're using "Action" where logic would imply the code should read delegate x = WriteText. The reason we need this extra mess is because "delegate" itself is like System.Object. It doesn't contain any information, and it's kind of the "base class" behind everything. If we actually want to use one, we have to attach some Type information. This is where Action comes in. The definition of Action is as follows:
public delegate void Action();
What this code says is "we're declaring a new delegate called Action, and it takes no parameters and returns void". Thereafter if you have any functions which also take no parameters and return void, you put them in variables of type Action.
Now, you can stick a normal function into a delegate, but you can also stick an "anonymous" function into a delegate. An "anonymous" function is something that you declare inline, so rather than attaching the already-declared WriteText function, we could build a new one up in the middle of our code like this:
Action x = () => { Console.WriteLine("Hello"); };
x(); // invoke our anonymous function.
What this is doing is using the C# "lambda syntax" to declare a new anonymous function. The code that runs as part of the function (when we invoke it) is the Console.WriteLine.
SO
To put it all together, you could have a "SaveData" function, and pass it a delegate. It could do it's 20 lines of table building, then pass that table to the delegate, and the delegate could invoke the appropriate stored-proc. Here's a simple example:
public void SaveData(Action<Table> saveFunc){
var t = new Table();
... 20 lines of code which put stuff into t ...
saveFunc(t);
}
SaveData( t => StoredProc1.Invoke(t) ); // save using StoredProc1
SaveData( t => StoredProc37.Invoke(t) ); // save using StoredProc37
SO
Having said ALL OF THAT. This isn't how I'd actually solve the problem. Rather than passing the delegate into your savedata function, it would make more sense to have your SaveData function simply return the table, and then you could then invoke the appropriate StoredProc without needing delegates at all

Categories