在C#中使用静态类一个简单的状态机来通知通过活动的其他用户 [英] A Simple State Machine using a Static class in C# to notify other subscribers via Events

查看:187
本文介绍了在C#中使用静态类一个简单的状态机来通知通过活动的其他用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试为我的应用程序编写一个简单的静态类状态机,以便在系统状态更改时通知其他控件和代码。我想我几乎有了它,但我遇到了一个小问题,我不知道如何解决。



以下代码:

  //枚举表示3状态
public enum状态{错误= -1,工作,就绪}

//主状态更改类
public static class Sys
{
//系统状态
私有静态状态;

//委托和事件
public static delegate void StateChangeHandler(object sys,SysInfoEventArgs sysStateInfo);
public static event StateChangeHandler OnStateChange;

public static状态状态
{
get {return state; }
set
{
SysInfoEventArgs sysInfo = new SysInfoEventArgs(state,value);
state = value;
OnStateChange(this,sysInfo);
}
}
}

///< summary>包含先前和当前状态信息< / summary>
public class SysInfoEventArgs:EventArgs
{
public readonly状态oldState;
public readonly状态newState;
public SysInfoEventArgs(Status oldState,Status newState)
{
this.oldState = oldState;
this.newState = newState;
}
}

我遇到的问题是: / p>

  OnStateChange(this,sysInfo); 

具体来说,this一词是非法的。我理解为什么:this应该返回一个实例化的对象(而不是一个静态类)的自我。



我宁愿有一个Static类对于我的状态机,而不是一个,我可以实例化多个副本。 (不是那将是一个坏的东西,但我觉得它使代码更清洁有一个静态类。)



那么我应该如何工作? / p>

更新:



作为后续,我选择Jon Skeet的答案正确的一个,因为问题更多是关于我采取的方法,而不是我的技术失败。虽然,下面几乎所有的其他答案解决了我处理的技术故障。



奇怪的是,当我正在与我的同事审查的应用程序,我写道,她指出,程序应该可以跟踪服务器连接的状态以及正在完成的工作的状态。 (是的,弗吉尼亚,这意味着我需要2个状态机... Ergo,删除所有的静态关键字从上面的代码,并使它成为一个常规的类是聪明的方法。)



再次感谢大家!

解决方案

为什么要使用静态类?这是一个状态机器 - 它有状态 - 自然建议使用非静态类。



基本上,你的直觉在我的观点是不正确的 - 有一个普通的类使代码比静态代码更干净。静态类应该很少有任何状态 - 可能是一个缓存(虽然这是可疑的),或计数器用于诊断目的等。试图考虑对象而不是。有两个独立的状态机,具有不同的当前状态和可能不同的事件处理程序是有意义的吗?很容易想象这是case - 这意味着很容易创建新的实例的测试等(它还允许独立测试并行运行)。因此在机器的实例中的状态是一个自然的契合。 p>

有些人认为应该有静态方法,没有静态类等。我认为有点远,但你应该总是至少考虑引入静态的可测试性影响。


I've been trying to write a simple Static-class State Machine for my application to notify other controls and code when the system state changes. And I think I almost have it, but I'm running into a small issue that I'm not sure how to work around.

Here's the code:

// An enum denoting the 3 States
public enum Status { Error = -1, Working, Ready }

// The main state change class
public static class Sys
{
    // system status
    private static Status state;

    // delegate and event
    public static delegate void StateChangeHandler(object sys, SysInfoEventArgs sysStateInfo);
    public static event StateChangeHandler OnStateChange;

    public static Status State
    {
        get { return state; }
        set
        {
            SysInfoEventArgs sysInfo = new SysInfoEventArgs(state, value);
            state = value;
            OnStateChange(this, sysInfo);
        }
    }
}

/// <summary>Contains previous and current state info</summary>
public class SysInfoEventArgs : EventArgs
{
    public readonly Status oldState;
    public readonly Status newState;
    public SysInfoEventArgs(Status oldState, Status newState)
    {
        this.oldState = oldState;
        this.newState = newState;
    }
}

The problem I am having is with this line:

 OnStateChange(this, sysInfo);

Specifically, the word "this" is illegal. And I understand why: "this" is supposed to refer back to the self of an instantiated object (not a static class).

I would prefer to have a Static class for my state machine rather than one that I can instantiate multiple copies of. (Not that it would be such a bad thing, but I feel it makes the code cleaner having a static class.)

So how am I supposed to work this?

Update:

As a follow-up, I selected Jon Skeet's answer as the correct one because the issue was more about the approach I was taking, rather than a technical failure that I was having. Although, pretty much all of the other answers below fix the technical glitch I was dealing with.

Oddly enough, as I was reviewing with my co-worker the application that I wrote, she pointed out that the program should probably track both the state of the server connection as well as the state of the work being done. (Yes, Virginia, this means I need 2 state machines... Ergo, remove all the "static" keywords from the code above and make it a regular class was the smart approach.)

Thanks again, everyone!

解决方案

Why would you want a static class? It's a state machine - it has state - that naturally suggests using a non-static class. You can always have a static variable referring to a single instance of it if you really want to.

Basically, your instinct is incorrect in my view - having a normal class would make the code cleaner than a static one. Static classes should very rarely have any state at all - perhaps a cache (although even that's dubious), or counters for diagnostic purposes etc. Try to think in terms of objects rather than classes. Does it make sense to have two separate state machines, with a different current state and perhaps different event handlers? It's easy to imagine that's the case - and it means it's easy to create new instances for tests etc. (It also allows independent tests to run in parallel.) Having the state in an instance of the machine is therefore a natural fit.

There are some people who believe there should be no static methods, no static classes etc. I think that's taking it a bit far, but you should always at least consider the testability impact of introducing statics.

这篇关于在C#中使用静态类一个简单的状态机来通知通过活动的其他用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆