2013-04-05 1 views
2

간단한 가볍고 값이 싼 호출을 사용하면 개체가 명명 된 메서드를 지원하는지 확인할 수 있습니까? 그래서,이 obj.respondsTo 훌륭한 것입니다.메서드가 있으면 호출하십시오.

dynamic _toJson(dynamic obj) { 
    return obj.respondsTo('toJson'))? obj.toJson() : obj; 
} 

class Foo { 
    String foo = "Foo.foo"; 
    Bar bar = new Bar(); 
    Map toJson() { 
    return { 
     "foo" : _toJson(foo), 
     "bar" : _toJson(bar) 
    }; 
    } 
} 

하나의 대안은 단지 그것을 호출하고 noSuchMethod 예외를 잡아,하지만 난 그 나쁜 연습과 비용이 상상하는 것? 짧은 대답은 '전혀'없다

bool respondsTo(dynamic obj, String methodName) 
{ 
    var mirror = reflect(obj); 
    return mirror.type.methods.values.map((MethodMirror method) => method.simpleName) 
            .contains(methodName); 
} 

답변

1

, 당신은 같은 것을 쓸 수 있어야합니다. 프레디 릭 하미 디 (Frédéric Hamidi)가 제공 한 대답은 틀린 것이 아니지만 dart2js에서는 작동하지 않습니다 (다트 : 미러는 대부분 dart2js에서 구현되지 않았습니다).

또한 다른 언어 (예 : Ruby)에서는 개체가 특정 메서드에 응답하는지 여부를 확인하지만 특히 나에게 Dart-y처럼 보이지는 않습니다. Dart에서 미러가 완전히 지원되면 변경 될 수 있습니다.

거울을 기반으로하는 반사가 '경량/저가'인지 여부는 말하기 어렵습니다. 유스 케이스와 이러한 용어를 정의하는 방법에 따라 다릅니다.

나는 최선의 방법은 개체의 메서드를 호출하고 NoSuchMethod 예외를 catch하고 일부 기본 오류 처리 동작을 구현한다고 말합니다. 이것은 일반적으로 메서드가 존재한다고 예상 할 때 특히 유용합니다.

2

객체가 인터페이스 유형일 경우 추상 메소드를 사용하여 인터페이스/추상 클래스를 정의한 다음 현재 알고있는 메소드를 호출 할 수 있습니다. 약간 다른 방법을 사용

abstract class JsonEncodable { 
    Map toJSON(); 
} 

Object _toJson(Object obj) { 
    return (obj is JsonEncodable)? obj.toJson() : obj; 
} 

class Foo implements JsonEncodable { 
    Map toJSON() { 
     // toJSON implementation 
    } 
} 
1

, 나는 주어진 방법은 인스턴스 기능의 목록을 확인하여 존재하는지 확인하고 있습니다 :

InstanceMirror im = reflect(this); 
Symbol fn = new Symbol('$functionName'); 
if (im.type.instanceMembers.keys.contains(fn)) { 
    im.invoke(fn, params); 
} 
0

경량하지,하지만 mirrors을 필요로하지 않습니다 (그리고 수락 된 답변을 다시 읽은 후 기본적으로 수락 된 답변이 가능성으로 제시 한 것입니다.) :

dynamic _toJson(dynamic obj) { 
    try { 
    return obj.toJson(); 
    } catch(NoSuchMethodError) { 
    return obj; 
    } 
} 

디버깅/문제 해결 목적으로 만 -이 코드를 절대로 생산에 사용하지 않을 것입니다. 이상적으로, 당신은 어떤 종류의 인터페이스를 정의하고 그것을 @thetrompf가 제안하는 것처럼 동적 인 것이 아니라 obj으로 전달하는 것이 훨씬 낫습니다.