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.
public class Outer { private class Inner { } }
- Daniel HilgarthInner
is always static in C#. That is, it doesn't have an implicit reference to Outer
. The reference has to be explicitly specified via a field in the inner class. In fact, the implicit reference in Java in non-static inner classes and anonymous classes is often the source of memory leaks in Java code. - Brianprivate class Inner
in C# is the same as private static class Inner
in Java. In any case, still a good answer. - BrianOuter
instance inside the Inner
object, and setting the reference to Outer
in the Inner
's constructor. - dasblinkenlight
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));
List.Sort
to mutate the list itself. - Servy
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);
}
}