簡體   English   中英

C#泛型+多態性解決方法?

[英]C# generics + polymorphism workaround?

因此,我目前有一些包裝Unity WWW類的方法。 HandleTexture,HandleText,HandleBytes ...,但這是很多復制粘貼的浪費。 我試圖將其全部包裝在一個通用的HandleResult方法下,該方法將事情交給幕后的_HandleResult。 在這一點上,C#編譯器抱怨無法將T靜態地鍵入到Texture(帶有closure(...);每一行closure(...);

private IEnumerator _HandleResult<T> (System.Action<T> closure, System.Action<string> onError){
    yield return webRequest;

    // Can't do a switch statement on Type, needs to be if/else chain :(
    if (SuccessWithoutErrors(onError)) {
        if(typeof(T) == typeof(Texture))
            closure(webRequest.texture);
        else if(typeof(T) == typeof(string))
            closure(webRequest.text);
        else if(typeof(T) == typeof(MovieTexture))
            closure(webRequest.movie);
        else if(typeof(T) == typeof(byte[]))
            closure(webRequest.bytes);
        else
            throw new System.NotSupportedException("Could not interpret response data as " + typeof(T).Name + ". Supported types include Texture, MovieTexture, byte[] and string.");
    }
}

我已經在這一點上停留了一段時間。 我對C#相當陌生,所以也許我想要的根本不可行。 非常感謝來自對類型系統有更多了解的人的輸入,或者為減少重復代碼,我應該尋求哪些替代品以實現相同的效果。

如果直接轉換為泛型類型,C#似乎不喜歡它。 但是您可以先轉換為object ,然后轉換為通用類型:

private IEnumerator _HandleResult<T> (System.Action<T> closure, System.Action<string> onError){
    yield return webRequest;

    if (SuccessWithoutErrors(onError)) {
        if(typeof(T) == typeof(Texture))
            closure((T)(object)webRequest.texture);
        else if(typeof(T) == typeof(string))
            closure((T)(object)webRequest.text);
        else if(typeof(T) == typeof(MovieTexture))
            closure((T)(object)webRequest.movie);
        else if(typeof(T) == typeof(byte[]))
            closure((T)(object)webRequest.bytes);
        else
            throw new System.NotSupportedException("Could not interpret response data as " + typeof(T).Name + ". Supported types include Texture, MovieTexture, byte[] and string.");
    }
}

較干凈的選項可能是提供執行屬性選擇的功能:

private IEnumerator _HandleResult<T> (System.Action<T> closure, Func<WebRequest, T> selector, System.Action<string> onError){
    yield return webRequest;

    if (SuccessWithoutErrors(onError)) { 
        closure(selector(webRequest)); 
    }
}

然后,您可以擁有一個函數簽名並調用以下站點:

void DoSomethingWithTexture(Texture t) {}

_HandleResult<Texture>(DoSomethingWithTexture, wr => wr.Texture, onError);

第二種方法更干凈,更靈活(如果以后要向要處理的對象添加Texture2屬性,該怎么辦?)但是需要更改API,並且可能更難以在現有代碼中實現。

嘗試這個:

    private IEnumerator _HandleResult<T>(object closure, System.Action<string> onError)
    {
        yield return webRequest;

        // Can't do a switch statement on Type, needs to be if/else chain :(
        if (true)
        {
            if (typeof(T) == typeof(Texture))
                ((System.Action<Texture>)closure)(webRequest.texture);
            else if (typeof(T) == typeof(string))
                ((System.Action<string>)closure)(webRequest.text);
            else if (typeof(T) == typeof(MovieTexture))
                ((System.Action<MovieTexture>)closure)(webRequest.movie);
            else if (typeof(T) == typeof(byte[]))
                ((System.Action<byte[]>)closure)(webRequest.bytes);
            else
                throw new System.NotSupportedException("Could not interpret response data as " + typeof(T).Name + ". Supported types include Texture, MovieTexture, byte[] and string.");
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM