Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
提高代码重用(c#?)的Python风格装饰器)_C#_Python_Dry - Fatal编程技术网

提高代码重用(c#?)的Python风格装饰器)

提高代码重用(c#?)的Python风格装饰器),c#,python,dry,C#,Python,Dry,我正在从python迁移到c#,我错过的一件事是python风格的装饰器。如果我在一堆函数的顶部重复代码(验证检查等),我可以创建一个装饰器来完成这项工作 我已经看到有某种c#decorator,但它们看起来更像是在类级别上工作。虽然我被他们弄糊涂了 不管怎样-您将如何改进此函数中的代码重用/干燥?函数中的所有内容都是通用的,除了标记的两个位置。它对服务器的回调驱动的Tcp请求,带有一个阻止多个并发请求的块(检查空闲状态) public void MyFunction(字符串、操作onSucce

我正在从python迁移到c#,我错过的一件事是python风格的装饰器。如果我在一堆函数的顶部重复代码(验证检查等),我可以创建一个装饰器来完成这项工作

我已经看到有某种c#decorator,但它们看起来更像是在类级别上工作。虽然我被他们弄糊涂了

不管怎样-您将如何改进此函数中的代码重用/干燥?函数中的所有内容都是通用的,除了标记的两个位置。它对服务器的回调驱动的Tcp请求,带有一个阻止多个并发请求的块(检查空闲状态)

public void MyFunction(字符串、操作onSuccess=null、操作onError=null)
{
//如果已忙于操作,则引发异常
如果(!state.Has(state.Idle)){抛出新操作进程();}
//定义回调操作
动作回调=委托(TcpRequest请求)
{
//将空闲状态添加回
state.Add(state.Idle);
//检查请求是否成功
if(request.OK)
{
/**
*这里的唯一代码
*/
}
//请求失败。如果提供,请调用OneError回调
else{onError?.Invoke(request);}
};
//清除空闲状态
state.Remove(state.Idle);
/**
*此处的唯一代码,稍后将触发回调
*/
}
编辑:我不是真的认为这是一个代码审查任务,但现在我可以看到它是。下面是整个类,展示了状态/变量如何交互。Server类处理我们(客户端)和Web服务器之间的交互,以处理游戏登录和创建/加入匹配

我并不固定在任何特定的结构上,但在某些情况下,我希望将UI按钮连接到简单的函数,如
Server.Login()
Server.JoinMatch()
,而不需要生成混乱的类

public class Server
{
    #region Fields
    public string playerName { get; private set; }
    public string playerID { get; private set; }
    public string playerToken { get; private set; }
    public string currentMatchID { get; private set; }
    private Patterns.State<ServerState> state = new Patterns.State<ServerState>();
    #endregion

    public Server()
    {
        state.Add(ServerState.Idle);
    }

    public void Login(string playerName, Action<TcpRequest> onSuccess = null, Action<TcpRequest> onError = null)
    {
        // Throw exception already busy with an operation
        if (!state.Has(ServerState.Idle)) { throw new OperationInProgress(); }

        // Define login callback action
        Action<TcpRequest> loginCallback = delegate (TcpRequest request)
        {
            // Add idle state back in
            state.Add(ServerState.Idle);

            // Check if the request succeeded
            if (request.OK)
            {
                // Store player data in class
                playerName = (string)request.requestJson["player_name"];
                playerID = (string)request.responseJson["player_id"];
                playerToken = (string)request.responseJson["player_token"];

                // Add the logged in state
                state.Add(ServerState.LoggedIn);

                // Call the onSuccess callback if provided
                onSuccess?.Invoke(request);
            }
            // Login failed, call the onError callback if provided
            else { onError?.Invoke(request); }
        };

        // Remove idle state
        state.Remove(ServerState.Idle);

        // Perform request
        Request("login", callback: loginCallback, requestJson: new Dictionary<string, object> { { "player_name", playerName }, { "client_version", "test1" } });
    }

    public void CreateMatch(string matchName, Action<TcpRequest> onSuccess = null, Action<TcpRequest> onError = null)
    {
        // Throw exception already busy with an operation
        if (!state.Has(ServerState.Idle)) { throw new OperationInProgress(); }

        // Define callback action
        Action<TcpRequest> callback = delegate (TcpRequest request)
        {
            // Add idle state back in
            state.Add(ServerState.Idle);

            // Check if the request succeeded
            if (request.OK)
            {
                // Add the inLobby state
                state.Add(ServerState.InLobby);

                // Call the onSuccess callback if provided
                onSuccess?.Invoke(request);
            }
            // Request failed. Call the onError callback if provided
            else { onError?.Invoke(request); }
        };

        // Remove idle state
        state.Remove(ServerState.Idle);

        // Perform request
        AuthenticatedRequest("match/create", callback: callback, requestJson: new Dictionary<string, object> { { "match_name", matchName } });
    }

    public void JoinMatch(string matchID, Action<TcpRequest> onSuccess = null, Action<TcpRequest> onError = null)
    {
        // Throw exception already busy with an operation
        if (!state.Has(ServerState.Idle)) { throw new OperationInProgress(); }

        // Define callback action
        Action<TcpRequest> callback = delegate (TcpRequest request)
        {
            // Add idle state back in
            state.Add(ServerState.Idle);

            // Check if the request succeeded
            if (request.OK)
            {
                // Add the inLobby state
                state.Add(ServerState.InLobby);

                // Set currentMatchID in class
                currentMatchID = (string)request.responseJson["match_id"];

                // Call the onSuccess callback if provided
                onSuccess?.Invoke(request);
            }
            // Request failed. Call the onError callback if provided
            else { onError?.Invoke(request); }
        };

        // Perform request
        AuthenticatedRequest("match/join", callback: callback, requestJson: new Dictionary<string, object> { { "match_id", matchID } });
    }

    private void Request(string resource, Action<TcpRequest> callback = null, Dictionary<string, object> requestJson = null)
    {
        // Start async request, invoke callback when done
    }

    private void AuthenticatedRequest(string resource, Action<TcpRequest> callback = null, Dictionary<string, object> requestJson = null)
    {
        // Add login auth data into the requestJson dict or throw exception if we aren't logged in
        // Call Request()
    }
}
公共类服务器
{
#区域字段
公共字符串播放器名称{get;private set;}
公共字符串播放器ID{get;private set;}
公共字符串播放器主题{get;private set;}
公共字符串currentMatchID{get;private set;}
private Patterns.State=new Patterns.State();
#端区
公共服务器()
{
state.Add(ServerState.Idle);
}
public void登录(字符串playerName,Action onSuccess=null,Action onError=null)
{
//抛出异常已忙于某个操作
如果(!state.Has(ServerState.Idle)){抛出新操作进程();}
//定义登录回调操作
Action loginCallback=委托(TcpRequest请求)
{
//将空闲状态添加回
state.Add(ServerState.Idle);
//检查请求是否成功
if(request.OK)
{
//在类中存储播放器数据
playerName=(string)request.requestJson[“player_name”];
playerID=(字符串)request.responseJson[“player_id”];
playerToken=(字符串)request.responseJson[“玩家令牌”];
//添加登录状态
state.Add(ServerState.LoggedIn);
//调用onSuccess回调(如果提供)
onSuccess?.Invoke(请求);
}
//登录失败,请调用OneError回调(如果提供)
else{onError?.Invoke(request);}
};
//清除空闲状态
state.Remove(ServerState.Idle);
//执行请求
请求(“login”,回调:loginCallback,requestJson:newdictionary{{“player\u name”,playerName},{“client\u version”,“test1”});
}
public void CreateMatch(字符串匹配名,操作onSuccess=null,操作onError=null)
{
//抛出异常已忙于某个操作
如果(!state.Has(ServerState.Idle)){抛出新操作进程();}
//定义回调操作
动作回调=委托(TcpRequest请求)
{
//将空闲状态添加回
state.Add(ServerState.Idle);
//检查请求是否成功
if(request.OK)
{
//添加inLobby状态
state.Add(ServerState.InLobby);
//调用onSuccess回调(如果提供)
onSuccess?.Invoke(请求);
}
//请求失败。如果提供,请调用OneError回调
else{onError?.Invoke(request);}
};
//清除空闲状态
state.Remove(ServerState.Idle);
//执行请求
AuthenticatedRequest(“匹配/创建”,回调:回调,requestJson:new Dictionary{{{“match_name”,matchName}});
}
public void JoinMatch(字符串matchID,Action onSuccess=null,Action onError=null)
{
//抛出异常已忙于某个操作
如果(!state.Has(ServerState.Idle)){抛出新操作进程();}
//定义回调操作
动作回调=委托(TcpRequest请求)
{
//将空闲状态添加回
state.Add(ServerState.Idle);
//检查请求是否成功
if(request.OK)
{
//添加inLobby状态
state.Add(ServerState.InLobby);
//在类中设置currentMatchID
currentMatchID=(字符串)请求.responseJson[“匹配id”];
//调用onSuccess回调(如果提供)
onSuccess?.Invoke(请求);
}
//请求失败。如果提供,请调用OneError回调
else{onError?.Invoke(request);}
};
//执行请求
AuthenticatedRequest(“match/join”,callback:callback,requestJson:newdictionary{{“match_id”,matchID}});
public abstract class MyClass
{
    public void MyFunction(string apples, Action<TcpRequest> onSuccess=null, Action<TcpRequest> onError=null)
    {
        // Throw exception if already busy with an operation
        if (!state.Has(State.Idle)) { throw new OperationInProgress(); }

        // Define callback action
        Action<TcpRequest> callback = delegate (TcpRequest request)
        {
            // Add idle state back in
            state.Add(State.Idle);

            // Check if the request succeeded
            if (request.OK)
            {
                SomethingUnique1();
            }
            // Request failed. Call the onError callback if provided
            else { onError?.Invoke(request); }
        };

        // Remove idle state
        state.Remove(State.Idle);

        SomethingUnique2(callback);
    }
    protected abstract void SomethingUnique1();
    protected abstract void SomethingUnique2(Action<TcpRequest> callback);
}
public sealed class MyClassVariant1 : MyClass
{
    protected override SomethingUnique1() { /*...*/ }
    protected override SomethingUnique2(Action<TcpRequest> callback) { /*...*/ }
}

public sealed class MyClassVariant2 : MyClass
{
    protected override SomethingUnique1() { /*...*/ }
    protected override SomethingUnique2(Action<TcpRequest> callback) { /*...*/ }
}
public sealed class MyClass
{
    private readonly Action somethingUnique1;
    private readonly Action<TcpRequest> somethingUnique2;
    public MyClass(Action somethingUnique1, Action<TcpRequest> somethingUnique2)
    {
        this.somethingUnique1 = somethinUnique1;
        this.somethinUnique2 = somethingUnique2;
    }
    public void MyFunction(string apples, Action<TcpRequest> onSuccess=null, Action<TcpRequest> onError=null)
    {
        // Throw exception if already busy with an operation
        if (!state.Has(State.Idle)) { throw new OperationInProgress(); }

        // Define callback action
        Action<TcpRequest> callback = delegate (TcpRequest request)
        {
            // Add idle state back in
            state.Add(State.Idle);

            // Check if the request succeeded
            if (request.OK)
            {
                somethingUnique1();
            }
            // Request failed. Call the onError callback if provided
            else { onError?.Invoke(request); }
        };

        // Remove idle state
        state.Remove(State.Idle);

        somethingUnique2(callback);
    }
}
var variant1 = new MyClass(() => { /* ... */ }, (TcpRequest r) => { /* ... */ }); 
var variant2 = new MyClass(() => { /* ... */ }, (TcpRequest r) => { /* ... */ });