2

Java에서 C #으로 일부 코드를 변환하는 중입니다.하지만 문제가있을 수 있습니다. 누군가가 도움을 줄 수 있습니까?

Java에서 널리 사용되는 익명 인터페이스 구현을 복제하는 데 문제가 있습니다. 그러나 방법을 모릅니다.

예를 들면 다음과 같습니다.

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);
                }
            });


  • 1) 무엇을 시도 했습니까? 2) 무엇이 승진됩니까? 3)이 코드에서 무엇을하려합니까? - IronMan84
  • 한 가지 중요한 차이점은수업Java에서는 익명으로 처리되지만행동 양식C #에서는 익명입니다. 아래의 해답은 좋은 것입니다. 자바 코드가 둘 이상의 멤버와 인터페이스를 구현하는 것을 볼 때, 해당 익명 메소드 (즉, 델리게이트)가 같은 클래스에 있는지 여부는 여러분에게 달려 있습니다 . - prprcupofcoffee

5 답변


5

Java에서 널리 사용되는 인라인 함수를 복제하는 데 문제가 있습니다.

이것은 인라인 함수가 아니며, 특정 인터페이스를 구현하는 익명 클래스입니다.

C #은 다음을 제공합니다.대의원인라인 또는 별도의 기능으로 정의 할 수 있습니다.

다음은 정렬하는 예입니다.List<DATA>그 자리에Comparison<T>대리자:

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);
    }
);

이 작업을 수행하려면distanceFunction변수는 호출하는 지점에서 범위에 있어야합니다.queue.Sort. 호출 점 위에 정의 된 지역 변수이거나 호출하는 함수를 묶는 클래스의 멤버 변수 / 속성 일 수 있습니다.


  • +1. 익명 클래스를 허용하지 않는 이유와 동일한 이유로 C #에서 정적이 아닌 내부 클래스도 허용하지 않는다는 점에 유의해야합니다. - Brian
  • @ 브라이언 : " 비 정적 내부 클래스 " 허용되지 않습니까? 유효한 코드는 다음과 같습니다.public class Outer { private class Inner { } } - Daniel Hilgarth
  • 그러나InnerC #에서는 항상 정적입니다. 즉,에 대한 암시 적 참조가 없습니다.Outer. 참조는 내부 클래스의 필드를 통해 명시 적으로 지정되어야합니다. 실제로 정적이 아닌 내부 클래스와 익명 클래스에서의 Java에서 암시적인 참조는 종종 Java 코드의 메모리 누수의 원인입니다. - Brian
  • @DanielHilgarth Ah, 의미론의 차이. 정적에 의해 클래스 선언을 참조하는 의미가 아니라 메서드. 내가 의미 한 것은private class InnerC #에서와 같습니다.private static class InnerJava에서. 어쨌든, 여전히 좋은 대답입니다. - Brian
  • @DanielHilgarth 어떤 자바 호출정적 내부 클래스C #이정적 클래스C #에서는 비 정적 클래스 만 인스턴스화 할 수 있으며 IIRC 중첩 클래스는 전혀 정적이 될 수 없습니다. Java에서 정적 멤버 클래스는 C #의 중첩 클래스와 동일하지만 비 정적 멤버 클래스는 인스턴스화 된 객체에 대한 참조를 유지합니다. C #에는 아날로그가 없지만 참조를 유지하여 쉽게 에뮬레이션 할 수 있습니다.Outer내부 인스턴스Inner개체 및 참조를 설정하는Outer~ 안에Inner생성자. - dasblinkenlight

1

C #에서는 인터페이스 대신 대리자를 사용하는 경우가 있습니다. 특히이 경우 호출자가 메서드를 인라인으로 정의하려는 경우가 있습니다. 람다를 사용하여 대리자가 예상되는 익명 메서드 인라인을 정의 할 수 있습니다.

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

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

C #에는 Java의 익명 인터페이스 구현과 동일한 기능이 없으므로 필요한 인터페이스가있는 경우 (예 :List) 구현하려면 명명 된 클래스를 만들어야합니다.


0

C #은 익명 인터페이스 구현 대신 대리자 개념을 사용합니다.

대체했다고 가정합니다.ArrayList<DATA>닷넷List<DATA>:

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


0

c #에 데이터 목록 개체가 있다고 가정합니다.

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


  • 여기에서 목록을 돌연변이시키지 않으면 이전 모음을 기반으로 새 모음집을 만듭니다. 당신은List.Sort목록 자체를 변경합니다. - Servy

0

원래 Java와 유사한 것을 원하면 다음을 수행하십시오.

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);
    }
}


  • 그것은 익명 인터페이스 구현이 아니거나 익명의 것입니다 ... - Servy
  • 이것은 C #과 동일한 기능입니다. 익명이라고하는 이유는 무엇이라고 생각하십니까? - Dave Doknjas
  • 동일한 C #은 없습니다. C #에는 익명 인터페이스 구현을 만드는 메커니즘이 없습니다. 가장 가까운 메커니즘, 즉 OP가 Java에서 사용하는 대신 일반적으로 사용되는 메커니즘은 명명 된 인터페이스 구현이 아닌 익명 메소드입니다. - Servy
  • 사용법을 시험해 본다면 똑같이 작동한다는 것을 알 수 있습니다. 이는 자바가 백그라운드에서하는 일을 명시 적으로 수행합니다. - Dave Doknjas
  • 그래, 난 동의. 그러나 코드 변환 관점에서 보았습니다. Java에서 익명 인터페이스 구현이 제공 되었기 때문에 C #에서 동일한 결과를 얻는 데 가장 고통이없는 방법은 숨겨진 구현 클래스를 익명으로 만드는 것입니다. - Dave Doknjas

연결된 질문


관련된 질문

최근 질문