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