views:

1098

answers:

1

Hi. 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.

+1  A: 

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

Orion Edwards
Thank you very much. That helped a lot. I got it figured out now
Ziltoid
Glad my giant pile of writing was useful :-)
Orion Edwards