Tag Archives: Method

Unity C# – Extension Methods 알아보기

unity_logo

C# 기준 3.0 버전에 추가되었던 멋진 기능중에 확장 메소드(Extension Methods)라는 것이 있습니다. 이 기능을 이용하여 이미 존재하는 타입에 타입을 재정의하거나 상속을 통하지 않고도 새로운 기능을 추가하는 것이 가능합니다.

예를 들어 어떤 문자열(string)이 숫자로 이루어졌는데 아닌지를 확인하고 싶다고 할때, 이런 기능을 수행할 수 있는 새로운 함수를 선언하고 필요할 때마다 이것을 호출하는 방법을 취할 것입니다. 가령 다음과 같은 형태의 유틸리티 클래스를 만들 수 있습니다.

public class MyUtils
{
    public static bool IsNumeric(string s)
    {
        float output;
        return float.TryParse(s, out output);
    }
}

MyUtil이라는 유틸리티성 클래스를 선언하고 클래스를 인스턴스화 하지도 않고 사용할 수 있는 static 메소드 IsNumeric을 만들었습니다. 이제 다음과 같은 방법으로 사용을 할 것입니다.

string test = "4";
if (MyUtils.IsNumeric(test))
    Debug.Log ("Is Numeric: Yes");
else
    Debug.Log ("Is Numeric: No");

하지만 확장 메소드를 사용하게 되면 위와 같은 기능을 string 클래스가 바로 지원하도록 할 수 있습니다. 먼저 static class를 선언하고 원하는 기능을 수행하는 메소드 역시 static으로 선언해 줍니다. 다음과 같은 형태가 될 것입니다.

public static class MyExtensionMethods
{
    public static bool IsNumeric(this string s)
    {
        float output;
        return float.TryParse(s, out output);
    }
}

위의 예제를 보면 다른 일반적인 정적 메소드(Static Methods)와 다른점 한가지는 파라미터 부분에 this 키워드가 사용되었다는 것입니다. 이러한 this를 파라미터로 사용한 메소드가 static으로 선언되었고 그 클래스 역시 static으로 선언이 되었다면 컴파일러는 이 메소드를 string을 위한 확장 메소드라고 인식하게 됩니다.

다시 정리해 보자면 확장 메소드를 선언하기 위한 조건은 다음과 같습니다.

  1. 클래스를 static 으로 선언할 것
  2. 메소드를 static 으로 선언할 것
  3. 메소드의 첫번째 파라미터에 확장할 타입을 this와 함께 선언할 것 (예: string을 확장할 경우 this string)

이제 이렇게 선언한 확장 메소드는 다음과 같이 사용할 수 있습니다.

string test = "4";
if (test.IsNumeric())
    Debug.Log ("Is Numeric: Yes");
else
    Debug.Log ("Is Numeric: No");

만약 추가로 파라미터를 받고 싶다면, this 없이 두번째 파라미터 이상의 선언을 해주시면 됩니다.

public static class MyExtensionMethods
{
    public static int MyDoublePlus(this int i, int x, int y)
    {
    	return i + x + y;
    }
}

int i = 10;
Debug.Log ("Result: " + i.MyDoublePlus(3, 5)); // Result: 18

참고 : http://csharp.net-tutorials.com/csharp-3.0/extension-methods/

[Android] Object [object Object] has no method 오류 해결하기

Android상에서 웹뷰를 사용하면서 Javascript 인터페이스를 사용하여 웹과 네이티브 코드간에 통신을 할 수 있습니다. 하지만 Android 4.2부터는 정상적으로 동작하지 않고 오류가 발생하는것을 발견하였습니다. 다음은 오류를 확인할 수 있는 간단한 코드입니다.

this.webView.getSettings().setJavaScriptEnabled(true);
this.webView.setWebChromeClient(new WebChromeClient());
this.webView.addJavascriptInterface(new Object() {
    public void handshake() {
        Log.d("JS", "handshake no params");
    }

    public void handshake(String json) {
        Log.d("JS", "handshake with params: " + json);
    }
}, "Android");

Javascript에서는 다음과 같이 위의 handshake()를 호출할 수 있습니다.

Android.handshake();

하지만 logcat에 다음과 같은 오류가 발생합니다.

E/Web Console: Uncaught TypeError: Object [object Object] has no method ‘handshake’

여기서 중요한점은 4.2 이전버전들에서는 매우 잘 동작하는 API라는것입니다. 확인해본 결과 4.2(API 17)부터 Javascript에서 접근하려는 메소드에는 어노테이션을 추가해주어야 하도록 변경되었습니다. [확인]

결과적으로 위의 코드는 다음과 같이 @JavascriptInterface를 추가해주면 정상적으로 동작합니다. 물론 빌드 타켓을 API 17이상으로 해줄 필요가 있습니다.

this.webView.getSettings().setJavaScriptEnabled(true);
this.webView.setWebChromeClient(new WebChromeClient());
this.webView.addJavascriptInterface(new Object() {
    public void handshake() {
        Log.d("JS", "handshake no params");
    }

    @JavascriptInterface
    public void handshake(String json) {
        Log.d("JS", "handshake with params: " + json);
    }
}, "Android");

참고 : http://stackoverflow.com/questions/14031635/android-4-2-1-webview-and-javascript-interface-breaks