1

I'm writing a K-Nearest Neighbors classifier class. I would like to allow the client the ability to specify the distance function to be used.

Can the constructor of my KNNClassifier object take a method as a parameter? In Python I'm doing this as follows:

class KNNClassifier:

    def __init__(self, examples, membership, n_classes, distance_func):

        self.examples      = examples
        self.membership    = membership
        self.n_classes     = n_classes
        self.distance_func = distance_func

        self.m = len(self.membership)
        self.n = len(self.examples[0])`

Can this be done in C#? I'm new to C# and an elementary example would be appreciated.

Filburt
  • 17,626
  • 12
  • 64
  • 115

2 Answers2

4

You'd use delegates. Here's a simple example using generics:

public class MyClass<T>
{
    private Func<T, T, int> _distanceFunc

    public MyClass(Func<T, T, int> distanceFunc)
    {
        this._distanceFunc = distanceFunc;
    }
}

This declares a generic class, MyClass, that takes one generic type parameter, T, and has a single constructor that takes one parameter. That parameter is itself a function that accepts two parameters of type T and returns an int. Within MyClass, the delegate that _distanceFunc points to may be invoked with parentheses, just like any other function:

T instanceA = ...
T instanceB = ...
int result = this._distanceFunc(instanceA, instanceB);

You could even combine this with lambda expressions, like this:

var foo = new MyClass<string>((a, b) => Math.Abs(a.Length - b.Length));
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • While correct, note that you don't have to use generics to make this work. – BradleyDotNET Mar 06 '14 at 20:30
  • @LordTakkera Yes you're right, generics aren't absolutely necessary to answer the question, but I felt it would be helpful to illustrate their use in this case. – p.s.w.g Mar 06 '14 at 20:32
  • I just pointed it out because it sounds like the OP is not familiar with C#, and my have trouble understanding generics, let alone generics inside of a generic delegate. – BradleyDotNET Mar 06 '14 at 20:42
1

Yes, you can use Func, Action, and delegates to do this:

Action: http://www.dotnetperls.com/action

Func: http://www.dotnetperls.com/func

delegate: http://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx

Caleb
  • 1,088
  • 7
  • 7