繁体   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