سؤال

I'm working on translating some code from Java to C# but am having some trouble, maybe someone out there can help?

I have problems trying to replicate anonymous interface implementations that are widely used in Java, but have no idea how to.

An example is:

List<DATA> queue1 = new ArrayList<DATA>(dataSet);
            // Sort by distance to the first promoted data
            Collections.sort(queue1, new Comparator<DATA>() {
                @Override
                public int compare(DATA data1, DATA data2) {
                    double distance1 = distanceFunction.calculate(data1, promoted.first);
                    double distance2 = distanceFunction.calculate(data2, promoted.first);
                    return Double.compare(distance1, distance2);
                }
            });
هل كانت مفيدة؟

المحلول

I have problems trying to replicate the inline functions that are widely used in Java

These are not inline functions, that's anonymous classes implementing a specific interface.

C# provides delegates that you can define inline or in a separate function.

Here is an example of sorting a List<DATA> in place using the Comparison<T> delegate:

List<DATA> queue = new List<DATA>();
queue.Sort(
    (left, right) => {
        double distance1 = distanceFunction.Calculate(left, promoted.first);
        double distance2 = distanceFunction.Calculate(right, promoted.first);
        return Double.Compare(distance1, distance2);
    }
);

Note that in order for this to work, the distanceFunction variable needs to be in scope at the spot where you invoke queue.Sort. It can be a local variable defined above the invocation point, or a member variable/property of the class enclosing the function that makes the call.

نصائح أخرى

In C# you end up using delegates instead of interfaces in may cases, especially in cases like this where it's likely the caller will want to define the method inline. You can use a lambda to define an anonymous method inline where any delegate is expected.

List<String> list = new List<String> { "B", "D", "E" };

list.Sort((a, b) => a.CompareTo(b));

There is no equivalent to Java's anonymous interface implementations in C#, so if there is an interface required (which isn't the case for sorting a List) you'll need to create a named class to implement it.

C# uses the concept of delegates in the place of anonymous interface implementations.

Assuming you've replaced ArrayList<DATA> with the .Net List<DATA>:

IEnumerable<DATA> sorted =
    queue1.OrderBy(q => distanceFunction.calculate(q, promoted.first));

assume that you have an a List of Data objects in c#:

queue1.OrderBy(a => distanceFunction.Calculate(a, promoted.First));

If you want something that parallels the original Java, then:

internal virtual void test()
{
    List<int> queue1 = new List<int>(dataSet);
    queue1.Sort(new ComparatorAnonymousInnerClassHelper());
}

private class ComparatorAnonymousInnerClassHelper : IComparer<int>
{
    public virtual int compare(int data1, int data2)
    {
        double distance1 = distanceFunction.calculate(data1, promoted.first);
        double distance2 = distanceFunction.calculate(data2, promoted.first);
        return distance1.CompareTo(distance2);
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top