如何使这个System.Serializable类不可知?

时间:2017-12-16 09:47:10

标签: c# unity3d

这是原则:

  • 我有很多Ajax交流
  • 我有一个System.Serializable类是Ajax调用的结果
  • 我总是有两个功能:
    • 拨打电话的功能
    • 分析通话的功能

使调用的函数获得一个回调作为参数,进行调用,并在完成后,使用System.Serializable类回调。

以下是一个例子:

[System.Serializable]
public class JsonState
{
    public int state;
    public string message;
    public JsonData data;
}

在我班上:

public class DataController : MonoBehaviour {
    public delegate void CallbackAjaxStateFinished(JsonState j);
    public CallbackAjaxStateFinished cbAjaxStateFinished = null;

    public void AjaxStateGet(CallbackAjaxStateFinished cb=null)
    {
        /* make the Ajax call*/
        cbAjaxStateFinished = cb;
        new HTTPRequest(
            new Uri(baseURL + _urlGetState),
            HTTPMethods.Get, AjaxStateGetFinished
        ).Send();
    }

    private void AjaxStateGetFinished(
        HTTPRequest request, HTTPResponse response
    ) {
        if (response == null) {
            return;
        }
        JsonState j = null;
        try {
            j = JsonUtility.FromJson<JsonState>(response.DataAsText);
            if (cbAjaxStateFinished != null) {
                cbAjaxStateFinished(j);
            }
        } catch (ArgumentException) { /* Conversion problem */
            TryDisplayFatalError(FatalErrors[FatalError.ConversionProblem2]);
        }
    }
}

问题是我已经有3个像这样的Ajax调用,总是相同的原则,这里有3个回调,给你一个概述:

public CallbackAjaxStateFinished cbAjaxStateFinished = null;
public CallbackAjaxGamesToJoinFinished cbAjaxGamesToJoinFinished = null;
public CallbackAjaxGameDetailFinished cbAjaxGameDetailFinished = null;

但我会添加另一个并复制/粘贴代码以发送/接收上面只有2个小修改:

  • 更改CallbackXxx类型
  • 更改System.Serializable

我是C#的新手,有没有办法让这个通用?

1 个答案:

答案 0 :(得分:2)

假设您的回调始终采用void(SomeStateclass)形式,此过程并不复杂。

在上面的代码中用通用T替换JSonState就可以了。这就是你最终的结果:

// The DataController takes a generic T respresenting one of your State classes
// notice that we need a constraint for the type T to have a parameterless constructor
public class DataController<T> : MonoBehaviour where T: new()
{ 
    // the delegate takes the generic type, so we only need one
    public delegate void CallbackAjaxFinished(T j);

    public CallbackAjaxFinished cbAjaxFinished = null;

    public void AjaxStateGet(CallbackAjaxFinished cb=null)
    {
        /* make the Ajax call*/
        cbAjaxFinished = cb;
        new HTTPRequest(
            new Uri(baseURL + _urlGetState),
            HTTPMethods.Get, AjaxStateGetFinished
        ).Send();
    }

    private void AjaxStateGetFinished(
        HTTPRequest request, HTTPResponse response
    ) {
        if (response == null) {
            return;
        }
        // here we use the default keyword to get 
        // an instance of an initialized stronglytyped T
        T j = default(T);
        try {
            // the T goes into the FromJson call as that one was already generic
            j = JsonUtility.FromJson<T>(response.DataAsText);
            if (cbAjaxFinished != null) {
                cbAjaxFinished(j);
            }
        } catch (ArgumentException) { /* Conversion problem */
            TryDisplayFatalError(FatalErrors[FatalError.ConversionProblem2]);
        }
    }
}

就是这样。您的datacontroller类现在是通用的。

你会像这样使用它:

var dc = new DataController<JsonState>()
dc.AjaxStateGet( (v) => {
   v.Dump("jsonstate");
});

var dc2 = new DataController<JsonState2>();
dc2.AjaxStateGet( (v) => {
   v.Dump("jsonstate2");
});