WPF Command Line Argument Routing - c#

I have a WPF application that I'm starting to develop. I have a 40 or so methods that are accessible through the UI, but also need to be executed by passing parameters via the command line.
Currently i have the following, that allows me to catch the arguments on the App.xaml.cs...
public partial class App : Application
{
string[] args = MyApplication.GetCommandLineArgs();
Dictionary<string, string> dictionary = new Dictionary<string, string>();
private void Application_Startup(object sender, StartupEventArgs e)
{
for (int index = 1; index < args.Length; index += 2)
{
dictionary.Add(args[index], args[index + 1]);
}
if (dictionary.Keys.Contains("/Task"))
{
MessageBox.Show("There is a Task");
}
}
}
}
I am looking to pass a argument at the start of every call through the command line. If i pass
/Task ThisIsTheTask
I can read this from the dictionary. And then execute the related method.
My question is what is the best way of "routing" the task parameter to a specific method. I will also be passing additional parameters after the task that will need to be passed to the method.

It could be considered an implementation of the service-locator anti-pattern, but one simple approach would be to have something like the following:
private readonly Dictionary<string, Action<string[]>> commands = new Dictionary<string, Action[]>
{
{"Task1", args => Task1Method(args[0], Int32.Parse(args[1]))}
}
private static Task1Method(string firstArgs, int secondArg)
{
}
Your code can then locate an Action<string[]> for the task specified on the command line, and pass the remaining parameters to the Action, e.g.
var commandLineArgs = Environment.GetCommandLineArgs();
var taskName = commandLineArgs[1];
// Locate the action to execute for the task
Action<string[]> action;
if(!commands.TryGetValue(taskName, out action))
{
throw new NotSupportedException("Task not found");
}
// Pass only the remaining arguments
var actionArgs = new string[commandLineArgs.Length-2];
commandLineArgs.CopyTo(actionArgs, 2);
// Actually invoke the handler
action(actionArgs);

If you are able to use third-party, open source libraries I would suggest taking a look at ManyConsole, it is available via NuGet here.
ManyConsole allows you to define ConsoleCommand implementations (see here for an example implementation), which can have many parameters. You are then able to use a ConsoleCommandDispatcher to route to the appropriate ConsoleCommand implementation based upon the command-line arguments (see here for an example).
I am in no way affiliated with ManyConsole, but I have used the library and found it to be very effective.

I'd suggest one (or more) properties on the application class of your program that expose them. Access during runtime can then be done by using something like
(Application.Current as App).MyTask
which can then be further wrapped for convenience.
Also, you can write your own "Main" method in WPF too - that way you would have easier access to the parameters array and could do processing before WPF starts up if you need to. I'll edit in how if you need that.

Related

Is it possible to get the current dialog step name?

I am writing a bot and I want to create a step by step help system. I setup a dictionary that allow each dialog to overwrite the help text for each step in it:
public abstract class BaseDialog : ComponentDialog
{
private static Dictionary<string, string> StepHelp = new Dictionary<string, string>();
protected static void AddStepHelp(string function, string text)
{
StepHelp.Add(function, text);
}
private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken)
{
Activity helpMessage;
string curStepName = ""; //???
if (userText == "help" && StepHelp.ContainsKey(curStepName))
{
helpMessage = MessageFactory.Text(StepHelp[curStepName], StepHelp[curStepName], InputHints.ExpectingInput);
}
await innerDc.Context.SendActivityAsync(helpMessage, cancellationToken);
}
}
Then I add the text in the chidl dialog:
public class MyChildDialog: BaseDialog
{
static MyChildDialog()
{
AddStepHelp(nameof(Step1), "Help text for step1");
}
public MyChildDialog()
{
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
{
Step1
}));
InitialDialogId = nameof(WaterfallDialog);
}
private async Task<DialogTurnResult> Step1(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
}
}
You can see in the InterruptAsync function above that I call the dictionary to get the help message in the base dialog, but how do I get the current step name?
You can get the current step index as well as the dialog name, so you should be able to create a unique identifier from that information (as long as you didn't name all the dialogs "waterfallDialog" from the example like I did!). I'm using node but I'm assuming getting the data from your stepContext is similar or the same.
The dialog name can be found at stepContext.stack[stepContext.stack.length-1].id.
The step index can be found at stepContext.stack[stepContext.stack.length-1].state.stepIndex.
I can't recall if you can end up with nested dialogs inside a waterfall dialog. I know your main/outer context will have the whole stack, but I think you'll always just have the one element inside your particular waterfall. That said, the current dialog should be the last one the stack, so accessing it as stepContext.stack.length-1 should work in either case. In the event the current dialog is at element 0, obviously you could just access it as such.
So long as your waterfall dialog names are unique, you'd end up with identifiers like waterfallDialog0, waterfallDialog1, etc. that you could then map in your dictionary to help texts.
It occurred to me you might be trying to access this from outside the waterfall dialog. In that case you should still be able to get that from your outer dialog context. You would likely have to use a recursive function to get it, something like
getInnermostActiveDialog(dc) {
var child = dc.child;
return child ? this.getInnermostActiveDialog(child) : dc.activeDialog;
}
where dc is your outer dialog context. I haven't gone this deep into things but you should then be able to get the same id and stepIndex values.
While it's easy to get the step index as billoverton explained, getting the step name is difficult. The _steps field is private and so is the method that returns the step name so you won't be able to access the steps even if your class derives from WaterfallDialog. The step names are only exposed through the telemetry client so you might consider writing a custom telemetry client that somehow exposes the information to your bot but at that point it's probably easier just to use reflection to access the private members.
Since you only really want the step name to use as a key for your dictionary, just using the step index instead is a much better option. You could use a Dictionary<int, string> but it makes sense to use a List<string> if you intend to have a help string for every step in the waterfall.

"Simulate" command line argument in unit-tests

I have some functionality, which depends on command line arguments, and different arguments should lead to different results.
I can't directly "simulate" this arguments, since there are some sort of chain dependencies - I need to unit-test some xaml control, which depends on view-model, which depends on certain additional class, which fetches command line arguments using Environment.GetCommandLineArgs, and I can't directly impact on this last class to set arguments manually instead of using GetCommandLineArgs.
So, I'd like to know, is there any way to make Environment.GetCommandLineArgs return value I want it to return, for certain unit-test.
You need to abstract Environment.GetCommandLineArgs or what ever is eventually calling it behind something you can mock
public interface ICommandLineInterface {
string[] GetCommandLineArgs();
}
Which can eventually be implemented in a concrete class like
public class CommandInterface : ICommandLineInterface {
public string[] GetCommandLineArgs() {
return Environment.GetCommandLineArgs();
}
}
And can be Tested using Moq and FluentAssertions
[TestMethod]
public void Test_Should_Simulate_Command_Line_Argument() {
// Arrange
string[] expectedArgs = new[] { "Hello", "World", "Fake", "Args" };
var mockedCLI = new Mock<ICommandLineInterface>();
mockedCLI.Setup(m => m.GetCommandLineArgs()).Returns(expectedArgs);
var target = mockedCLI.Object;
// Act
var args = target.GetCommandLineArgs();
// Assert
args.Should().NotBeNull();
args.Should().ContainInOrder(expectedArgs);
}
Since you are dealing with environment variables, why don't we wrap the outside dependencies into one EnvironmentHelper class, then inject the dependencies?
Here is my suggestion:
public class EnvironmentHelper
{
Func<string[]> getEnvironmentCommandLineArgs;
// other dependency injections can be placed here
public EnvironmentHelper(Func<string[]> getEnvironmentCommandLineArgs)
{
this.getEnvironmentCommandLineArgs = getEnvironmentCommandLineArgs;
}
public string[] GetEnvironmentCommandLineArgs()
{
return getEnvironmentCommandLineArgs();
}
}
Here is the Mock method:
public static string[] GetFakeEnvironmentCommandLineArgs()
{
return new string[] { "arg1", "arg2" };
}
In your source code:
EnvironmentHelper envHelper = new EnvironmentHelper(Environment.GetCommandLineArgs);
string[] myArgs = envHelper.GetEnvironmentCommandLineArgs();
In your unit test code:
EnvironmentHelper envHelper = new EnvironmentHelper(GetFakeEnvironmentCommandLineArgs);
string[] myArgs = envHelper.GetEnvironmentCommandLineArgs();
You can do it much more easier with Typemock Isolator.
It allows to mock not only interfaces, so. Take a look:
[TestMethod, Isolated]
public void TestFakeArgs()
{
//Arrange
Isolate.WhenCalled(() => Environment.GetCommandLineArgs()).WillReturn(new[] { "Your", "Fake", "Args" });
//Act
string[] args = Environment.GetCommandLineArgs();
//Assert
Assert.AreEqual("Your", args[0]);
Assert.AreEqual("Fake", args[0]);
Assert.AreEqual("Args", args[0]);
}
Mocking Environment.GetCommandLineArgs() took only one line:
Isolate.WhenCalled(() => Environment.GetCommandLineArgs()).WillReturn(new[] { "Your", "Fake", "Args" });
And you don't need to create new Interfaces and to change production code.
Hope it helps!
If you want something unit-testable it should have its dependencies on a abstraction that is at least as strict as its implementation.
Usually you'd get the dependencies through your constructor of your class or a property method. Constructor is preferred, generally, because now a consumer of your class knows at compile-time what dependencies are needed.
public void int Main(string[] args)
{
// Validate the args are valid (not shown).
var config = new AppConfig();
config.Value1 = args[0];
config.Value2 = int.Parse(args[1]);
// etc....
}
public class MyService()
{
private AppConfig _config;
public MyService(AppConfig config)
{
this._config = config;
}
}
I normally don't put a config object behind an interface because it only has data - which is serializable. As long as it has no methods, then I shouldn't need to replace it with a subclass with override-d behavior. Also I can just new it up directly in my tests.
Also, I've never ran into a situation when I wanted to depend on an abstraction of the command line arguments themselves to a service - why does it need to know it's behind a command-line? The closest I've gotten is use PowerArgs for easy parsing, but I'll consume that right in Main. What I normally do is something like maybe read in the port number for a web server on the command-line arguments (I let the user of the app choose so that I can run multiple copies of my web server on the same machine - maybe different versions or so I can run automated tests while I'm debugging and not conflict ports), parse them directly in my Main class. Then in my web server I depend on the parsed command-line arguments, in this case an int. That way the fact that the configuration is coming from a command-line is irrelevant - I can move it to an App.config file later (which is also basically bound to the lifecycle of the process) if I prefer - then I can extract common configuration to configSource files.
Instead of depending on an abstraction for command-line in general (which each service consuming would have to re-parse if you kept it pure), I usually abstract the command-line and App.config dependencies to a strongly-typed object - maybe an app-level config class and a test-level config class and introduce multiple configuration objects as needed - (the app wouldn't necessarily care about this, while the E2E test infrastructure would need this in a separate part of the App.config: where do I grab the client static files from, where do I grab the build scripts in a test or developer environment to auto-generate/auto-update an index.html file, etc.).

Multithreaded access to singleton class

I'm having a hard time wrapping my head around accessing a singleton class with multiple threads.
This article has given me a nice starting point to get my singleton thread safe: http://csharpindepth.com/Articles/General/Singleton.aspx
My singleton class is supposed to treat a group of files as a single unity of data, but process them in a parallel fashion.
I store information of each file in a dictionary and return to the calling thread a unique key (which will be created using a DateTime and a random number) so that each thread can later refer to its own file.
public string AddFileForProcessing(FileForProcessing file)
{
var id = CreateUniqueFileId();
var resultFile = CreateResultFileFor(file);
//These collections are written here and only read elsewhere
_files.Add(id, file);
_results.Add(id, resultFile)
return id;
}
Then later threads call methods passing this id.
public void WriteProcessResultToProperFile(string id, string[] processingResult)
{
//locate the proper file in dictionary using id and then write information...
File.AppendAllLines(_results[key].FileName, processingResult);
}
Those methods will be accessed inside a class that:
a) Responds to a FileWatcher's Created event and creates threads that call AddFileForProcessing:
public void ProcessIncomingFile(object sender, EventArgs e)
{
var file = ((FileProcessingEventArg)e).File;
ThreadPool.QueueUserWorkItem(
item =>
{
ProcessFile(file);
});
}
b) Inside ProcessFile, I add the file to the dictionary and start processing.
private void ProcessFile(FileForProcessing file)
{
var key = filesManager.AddFileForProcessing(file);
var records = filesManager.GetRecordsCollection(key);
for (var i = 0; i < records.Count; i++)
{
//Do my processing here
filesManager.WriteProcessResultToProperFile(key, processingResult);
}
}
Now I don't get what happens when two threads call these methods, given they're both using the same instance.
Each thread will call AddFileForProcessing and WriteProcessResultToProperFile with a different parameter. Does that make them two different calls?
Since it will operate on a file that will be uniquely identified by the id that belongs to a single thread (i.e.. no file will suffer from multiple accesses), can I leave this method as is or do I still have to "lock" my method?
Yes, as long as you only read from the shared dictionary all should be fine. And you can process the files in parallel as long as they are different files, as you correctly mention.
The documentation explains:
A Dictionary<TKey, TValue> can support multiple readers concurrently, as long as the collection is not modified.
So, you can't do anything in parallel if anyone can call AddFileForProcessing (without lock). But with calls only to WriteProcessResultToProperFile, it will be fine. This implies that if you want to call AddFileForProcessing in parallel, then you need locks in both methods (in fact: all parts of code that will touch this dictionary).

C# How to tell if an object implements a particular method

So I have a number of different potential object that can output data (strings). What I want to be able to do, is to Run a generic Output.WriteLine function, with the potential arguments that define where you want it to be outputted to. What I've got for code -
//Defined in static class Const
public enum Out : int { Debug = 0x01, Main = 0x02, Code = 0x04 };
static class Output
{
private static List<object> RetrieveOutputMechanisms(Const.Out output)
{
List<object> result = new List<object>();
#if DEBUG
if (bitmask(output, Const.Out.Debug))
result.Add(1);//Console); //I want to add Console here, but its static
#endif
if (bitmask(output, Const.Out.Main))
if (Program.mainForm != null)
result.Add(Program.mainForm.Box);
if (bitmask(output, Const.Out.Code))
if (Program.code!= null)
result.Add(Program.code.Box);
return result;
}
public static void WriteLine(Color color, string str, Const.Out output = Const.Out.Debug & Const.Out.Main)
{
Console.WriteLine(
List<object> writers = RetrieveOutputMechanisms(output);
foreach (object writer in writers)
writer.WriteLine(str, color);
}
}
The point of this, is that the output destinations are not always existent, as they are on forms that may or may not exist when these calls are called. So the idea is to determine which ones you're trying to print to, determine if it exists, add it to the list of things to be printed to, then loop through and print to all of them if they implement the "WriteLine" method.
The two problems that I've come across, are
That Console is a static class, and can't properly (as far as my knowledge goes) be added to the object list.
I don't know how I can assert that the objects in the list define WriteLine, and cast them to something that would apply to more than one base Type. Assuming I can get Console to work properly in this scheme, that would be the obvious problem, its not of the same base type as the actual Boxes, but also, if I had something that wasnt a Box, then it would be lovely to do something like
foreach (object writer in writers)
.WriteLine(str, color)
so that I wouldn't have to individually cast them.
The bigger reason that I don't simply WriteLine from the RetrieveOutputMechanisms function, is that I want this to cover more than just WriteLine, which means that I would need to copy the bitmask code to each function.
EDIT: I realise that adding public properties to Program is a bad idea, if you know how I can avoid it (the necessity coming from needing to be able to access any WriteLine-able form objects that come and go, from anywhere), by all means please elaborate.
One way would be to use an Action (a delegate) and store those in your List. This will work for Console and any other class as you can easily write a lambda (or a 2.0 delegate) to map your output variables to the right parameters in the called method. There will be no need for casting. It could work something like this:
(This assumes you are using C# 3.5 or later but you can do all this in anything from 2.0 and on using delegates)
static class Output
{
private static List<Action<string, Color>> RetrieveOutputMechanisms(Const.Out output)
{
List<Action<string, Color>> result = new List<string, Color>();
#if DEBUG
if (bitmask(output, Const.Out.Debug))
result.Add((s, c) => Console.WriteLine(s, c)); //I want to add Console here, but its static
#endif
if (bitmask(output, Const.Out.Main))
if (Program.mainForm != null)
result.Add((s, c) => Program.mainForm.Box.WriteLine(s, c));
if (bitmask(output, Const.Out.Code))
if (Program.code!= null)
result.Add((s, c) => Program.code.Box.WriteLine(s, c));
return result;
}
public static void WriteLine(Color color, string str, Const.Out output = Const.Out.Debug & Const.Out.Main)
{
var writers = RetrieveOutputMechanisms(output);
foreach (var writer in writers)
writer(str, color);
}
}
(edit to add)
You could change this more significantly to allow classes to "register" to be able to do the writing for a specific "output mechanism" in the Output class itself. You could make Output a singleton (there are arguments against doing that but it would be better than sticking public static variables in your main program for this purpose). Here is an example with more significant changes to your original class:
public sealed class Output
{
private Dictionary<Out, Action<string, Color>> registeredWriters = new Dictionary<Out, Action<string, Color>>();
public static readonly Output Instance = new Output();
private void Output() { } // Empty private constructor so another instance cannot be created.
public void Unregister(Out outType)
{
if (registeredWriters.ContainsKey(outType))
registeredWriters.Remove(outType);
}
// Assumes caller will not combine the flags for outType here
public void Register(Out outType, Action<string, Color> writer)
{
if (writer == null)
throw new ArgumentNullException("writer");
if (registeredWriters.ContainsKey(outType))
{
// You could throw an exception, such as InvalidOperationException if you don't want to
// allow a different writer assigned once one has already been.
registeredWriters[outType] = writer;
}
else
{
registeredWriters.Add(outType, writer);
}
}
public void WriteLine(Color color, string str, Const.Out output = Const.Out.Debug & Const.Out.Main)
{
bool includeDebug = false;
#if DEBUG
includeDebug = true;
#endif
foreach (var outType in registeredWriters.Keys)
{
if (outType == Const.Out.Debug && !includeDebug)
continue;
if (bitmask(output, outType))
registeredWriters[outType](str, color);
}
}
}
Then elsewhere in your program, such as in the form class, to register a writer, do:
Output.Instance.Register(Const.Out.Main, (s, c) => this.Box.WriteLine(s, c));
When your form is unloaded you can then do:
Output.Instance.Unregister(Const.Out.Main);
Then another way would be to not use a singleton. You could then have more than one Output instance for different purposes and then inject these into your other classes. For instance, change the constructor for your main form to accept an Output parameter and store this is an object variable for later use. The main form could then pass this on to a child form that also needs it.
If your objects that have data that need to be written behave like this:
A always writes to console and log
B always writes to log
C always writes to console
For all data, then your best bet would be to declare an interface and have each of them implement the interface method for output. Then, in your calling code, declare them not as their actual types but instead of type IOutput or whatever interface u call that has the method. Then have two helper methods, one for actually outputting to console and one for actually outputting to a log file. A would call both helpers, B and C their respective ones.
If, on the other hand, your objects will write to various logs at differing times:
A, B and C sometimes write to console and sometimes to log, depending on some property
Then I would recommend you create an event handler for when a class wants something to be written. Then, have the logic that discerns what writes to console and what writes to log in a listener class and attach the appropriate ones to that output event. That way, you can keep the logic about what is being written to where in classes that encapsulate just that functionality, while leaving the A, B and C classes free of dependencies that may come to bite you down the road. Consider having a monolithic method as you describe which uses a bitmask. As soon as the behavior of A, B or C's logging changes, or if you need to add a new output, you suddenly need to worry about one class or method affecting all of them at once. This makes it less maintainable, and also trickier to test for bugs.
MethodInfo methodname = typeof(object).GetMethod("MethodA");
Then just use a if statement to check if methodname is null or not.

C# - Can someone tell me why and where I should use delegates? [duplicate]

This question already has answers here:
Where do I use delegates? [closed]
(8 answers)
Closed 9 years ago.
I think I understand the concept of a delegate in C# as a pointer to a method, but I cant find any good examples of where it would be a good idea to use them. What are some examples that are either significantly more elegant/better with delegates or cant be solved using other methods?
The .NET 1.0 delegates:
this.myButton.Click += new EventHandler(this.MyMethod);
The .NET 2.0 delegates:
this.myOtherButton.Click += delegate {
var res = PerformSomeAction();
if(res > 5)
PerformSomeOtherAction();
};
They seem pretty useful. How about:
new Thread(new ThreadStart(delegate {
// do some worker-thread processing
})).Start();
What exactly do you mean by delegates? Here are two ways in which they can be used:
void Foo(Func<int, string> f) {
//do stuff
string s = f(42);
// do more stuff
}
and
void Bar() {
Func<int, string> f = delegate(i) { return i.ToString(); }
//do stuff
string s = f(42);
// do more stuff
}
The point in the second one is that you can declare new functions on the fly, as delegates. This can be largely replaced by lambda expressions,and is useful any time you have a small piece of logic you want to 1) pass to another function, or 2) just execute repeatedly. LINQ is a good example. Every LINQ function takes a lambda expression as its argument, specifying the behavior. For example, if you have a List<int> l then l.Select(x=>(x.ToString()) will call ToString() on every element in the list. And the lambda expression I wrote is implemented as a delegate.
The first case shows how Select might be implemented. You take a delegate as your argument, and then you call it when needed. This allows the caller to customize the behavior of the function. Taking Select() as an example again, the function itself guarantees that the delegate you pass to it will be called on every element in the list, and the output of each will be returned. What that delegate actually does is up to you. That makes it an amazingly flexible and general function.
Of course, they're also used for subscribing to events. In a nutshell, delegates allow you to reference functions, using them as argument in function calls, assigning them to variables and whatever else you like to do.
I primarily use the for easy asynch programming. Kicking off a method using a delegates Begin... method is really easy if you want to fire and forget.
A delegate can also be used like an interface when interfaces are not available. E.g. calling methods from COM classes, external .Net classes etc.
Events are the most obvious example. Compare how the observer pattern is implemented in Java (interfaces) and C# (delegates).
Also, a whole lot of the new C# 3 features (for example lambda expressions) are based on delegates and simplify their usage even further.
For example in multithread apps. If you want several threads to use some control, You shoul use delegates. Sorry, the code is in VisualBasic.
First you declare a delegate
Private Delegate Sub ButtonInvoke(ByVal enabled As Boolean)
Write a function to enable/disable button from several threads
Private Sub enable_button(ByVal enabled As Boolean)
If Me.ButtonConnect.InvokeRequired Then
Dim del As New ButtonInvoke(AddressOf enable_button)
Me.ButtonConnect.Invoke(del, New Object() {enabled})
Else
ButtonConnect.Enabled = enabled
End If
End Sub
I use them all the time with LINQ, especially with lambda expressions, to provide a function to evaluate a condition or return a selection. Also use them to provide a function that will compare two items for sorting. This latter is important for generic collections where the default sorting may or may not be appropriate.
var query = collection.Where( c => c.Kind == ChosenKind )
.Select( c => new { Name = c.Name, Value = c.Value } )
.OrderBy( (a,b) => a.Name.CompareTo( b.Name ) );
One of the benefits of Delegates is in asynchronous execution.
when you call a method asynchronously you do not know when it will finish executing, so you need to pass a delegate to that method that point to another method that will be called when the first method has completed execution. In the second method you can write some code that inform you the execution has completed.
Technically delegate is a reference type used to encapsulate a method with a specific signature and return type
Some other comments touched on the async world... but I'll comment anyway since my favorite 'flavor' of doing such has been mentioned:
ThreadPool.QueueUserWorkItem(delegate
{
// This code will run on it's own thread!
});
Also, a huge reason for delegates is for "CallBacks". Let's say I make a bit of functionality (asynchronously), and you want me to call some method (let's say "AlertWhenDone")... you could pass in a "delegate" to your method as follows:
TimmysSpecialClass.DoSomethingCool(this.AlertWhenDone);
Outside of their role in events, which your probably familiar with if you've used winforms or asp.net, delegates are useful for making classes more flexible (e.g. the way they're used in LINQ).
Flexibility for "Finding" things is pretty common. You have a collection of things, and you want to provide a way to find things. Rather than guessing each way that someone might want to find things, you can now allow the caller to provide the algorithm so that they can search your collection however they see fit.
Here's a trivial code sample:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Delegates
{
class Program
{
static void Main(string[] args)
{
Collection coll = new Collection(5);
coll[0] = "This";
coll[1] = "is";
coll[2] = "a";
coll[3] = "test";
var result = coll.Find(x => x == "is");
Console.WriteLine(result);
result = coll.Find(x => x.StartsWith("te"));
Console.WriteLine(result);
}
}
public class Collection
{
string[] _Items;
public delegate bool FindDelegate(string FindParam);
public Collection(int Size)
{
_Items = new string[Size];
}
public string this[int i]
{
get { return _Items[i]; }
set { _Items[i] = value; }
}
public string Find(FindDelegate findDelegate)
{
foreach (string s in _Items)
{
if (findDelegate(s))
return s;
}
return null;
}
}
}
Output
is
test
there isn't really anything delgates will solve that can't be solved with other methods, but they provide a more elegant solution.
With delegates, any function can be used as long as it has the required parameters.
The alternative is often to use a kind of custom built event system in the program, creating extra work and more areas for bugs to creep in
Is there an advantage to use a delegate when dealing with external calls to a database?
For example can code A :
static void Main(string[] args) {
DatabaseCode("test");
}
public void DatabaseCode(string arg) {
.... code here ...
}
Be improved in code B :
static void Main(string[] args) {
DatabaseCodeDelegate slave = DatabaseCode;
slave ("test");
}
public void DatabaseCode(string arg) {
.... code here ...
}
public delegate void DatabaseCodeDelegate(string arg);
It seems that this is subjective, but an area where there are strong conflicting view points?

Categories

Resources