c# delegate and abstract class
c#
Solution
The way you're attempting to use delegates (constructing them with `new`, declaring a named delegate type) suggests that you're using C# 1. If you're actually using C# 3, it's much easier than that.
Firstly, your delegate type:
public delegate List<BaseNode> GetAllNodesDelegate(int k);
Already exists. It's just:
Func<int, List<BaseNode>>
So you don't need to declare your own version of it.
Secondly, you should think of a delegate as being like an interface with only one method in it, and you can "implement" it on the fly, without having to write a named class. Just write a lambda, or assign a method name directly.
Func<int, List<BaseNode>> getNodesFromInt;
// just assign a compatible method directly
getNodesFromInt = DoSomethingWithArgAndReturnList;
// or bind extra arguments to an incompatible method:
getNodesFromInt = arg => MakeList(arg, "anotherArgument");
// or write the whole thing specially:
getNodesFromInt = arg =>
{
var result = new List<BaseNode>();
result.Add(new BaseNode());
return result;
};
A lambda is of the form `(arguments) => { body; }`. The arguments are comma-separated. If there's only one, you can omit the parentheses. If it takes no parameters, put a pair of empty parentheses: `()`. If the body is only one statement long, you can omit the braces. If it's just a single expression, you can omit the braces and the `return` keyword. In the body, you can refer to practically any variables and methods from the enclosing scope (apart from `ref`/`out` parameters to the enclosing method).
There's almost never any need to use `new` to create a delegate instance. And rarely a need to declare custom delegate types. Use `Func` for delegates that return a value and `Action` for delegates that return `void`.
Whenever the thing you need to pass around is like an object with one method (whether an interface or a class), then use a delegate instead, and you'll be able to avoid a lot of mess.
In particular, avoid defining interfaces with one method. It will just mean that instead of being able to write a lambda to implement that method, you'll have to declare a separate named class for each different implementation, with the pattern:
class Impl : IOneMethod
{
// a bunch of fields
public Impl(a bunch of parameters)
{
// assign all the parameters to their fields
}
public void TheOneMethod()
{
// make use of the fields
}
}
A lambda effectively does all that for you, eliminating such mechanical patterns from your code. You just say:
() => /* same code as in TheOneMethod */
It also has the advantage that you can update variables in the enclosing scope, because you can refer directly to them (instead of working with values copied into fields of a class). Sometimes this can be a disadvantage, if you don't want to modify the values.
Problem
I currently have 2 concrete methods in 2 abstract classes. One class contains the current method, while the other contains the legacy method. E.g. ``` // Class #1 public abstract class ClassCurrent<T> : BaseClass<T> where T : BaseNode, new() { public List<T> GetAllRootNodes(int i) { //some code } } // Class #2 public abstract class MyClassLegacy<T> : BaseClass<T> where T : BaseNode, new() { public List<T> GetAllLeafNodes(int j) { //some code } } ``` I want the corresponding method to run in their relative scenarios in the app. I'm planning to write a delegate to handle this. The idea is that I can just call the delegate and write logic in it to handle which method to call depending on which class/project it is called from (at least thats what I think delegates are for and how they are used). However, I have some questions on that topic (after some googling): 1) Is it possible to have a delegate that knows the 2 (or more) methods that reside in different classes? 2) Is it possible to make a delegate that spawns off abstract classes (like from the above code)? (My guess is a no, since delegates create concrete implementation of the passed-in classes) 3) I tried to write a delegate for the above code. But I'm being technically challenged: ``` public delegate List<BaseNode> GetAllNodesDelegate(int k); GetAllNodesDelegate del = new GetAllNodesDelegate(ClassCurrent<BaseNode>.GetAllRootNodes); ``` I got the following error: ``` An object reference is required for the non-static field, method, property ClassCurrent<BaseNode>.GetAllRootNodes(int) ``` I might have misunderstood something... but if I have to manually declare a delegate at the calling class, AND to pass in the function manually as above, then I'm starting to question whether delegate is a good way to handle my problem. Thanks.