[英]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.