Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.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
Class 什么是无状态类?_Class_C# 4.0_Stateless - Fatal编程技术网

Class 什么是无状态类?

Class 什么是无状态类?,class,c#-4.0,stateless,Class,C# 4.0,Stateless,我想知道无状态类(如果有的话)的缺点是什么? 有没有人见过一个真实的应用程序,其中一些用例要求创建一个无状态类(请不要hello world)? 我认为无状态类是指没有任何字段的类。如果您指的是一类不可变对象,那么缺点是变异操作需要复制对象,而不是就地更改对象。那可能很贵 我经常使用这些东西,几乎每当一个对象的行为由某个可以同时处理的输入决定时。最近的一个例子是我实现的:模型参数完全是在构造函数中根据训练输入确定的,然后可以查询模型以获得未看到文本的概率估计,但不能修改。不变性不是严格要求的,但

我想知道无状态类(如果有的话)的缺点是什么? 有没有人见过一个真实的应用程序,其中一些用例要求创建一个无状态类(请不要hello world)? 我认为无状态类是指没有任何字段的类。

如果您指的是一类不可变对象,那么缺点是变异操作需要复制对象,而不是就地更改对象。那可能很贵

我经常使用这些东西,几乎每当一个对象的行为由某个可以同时处理的输入决定时。最近的一个例子是我实现的:模型参数完全是在构造函数中根据训练输入确定的,然后可以查询模型以获得未看到文本的概率估计,但不能修改。不变性不是严格要求的,但修改对象没有意义,因为以后不需要添加数据(在这种情况下,大部分计算都必须重新进行)。

我从来没有听说过“无状态类”,但我认为你指的是不可变对象(非常有用的概念!)。
或者可能是一个没有任何字段的类,所以它通常看起来只是一堆纯函数。

我也不确定这个术语的含义,但我假设它是指一个没有字段的类,因为对象的状态实际上是其字段的内容

现在,通常您会将此类类用作相关函数的集合—例如,某个
Utils
类。使用此类类的常用方法是将其方法设置为静态,因此实际上不必创建类的实例


我能想到的实际创建这样一个无状态对象的唯一原因是,您是否希望在运行时确定实际的功能。因此,如果您有一个
UtilsBase
类,该类提供了一组虚拟方法,一个
UtilsDerived
类覆盖了一些方法,那么您可以向需要使用utils的人传递一个对
UtilsBase
的引用,并根据具体需要在运行时创建实际的utils对象。

在无状态类中,所有字段成员都应为只读类型。尽管c#没有任何在编译时检查无状态的功能,如:

public readonly class MyReadonlyClass
{
    public readonly double X {get;set;}
    public readonly double Y {get;set;}
    public readonly double Z {get;set;}

    public MyReadonlyClass(double x_,double y_,double z_)
    {
        X=x_;Y=y_;Z=z_;
    }
}

public readonly static class MyStaticReadonlyClass
{
    public readonly static double X {get;set;}
    public readonly static double Y {get;set;}
    public readonly static double Z {get;set;}

    static MyStaticReadonlyClass(double x_,double y_,double z_)
    {
        X=x_;Y=y_;Z=z_;
    }

}

下面是一个真实的例子:

在该文档中,您将看到一条注释:“插件的Execute方法应该被写入无状态”。 基本上,无状态类的含义是不应该有全局变量(除了一些特殊情况,除非有人问我,否则我不会讨论这些特殊情况)

CRM对插件开发人员强制执行的原因是,CRM试图通过缓存和重用插件类的实例来提高性能。 CRM执行插件的方式大致如下:

主线程:

YourCustomPlugin yourCustomPluginCached = new YourCustomPlugin();
随后: 线程1:

和线程2:

yourCustomPluginCached.Execute(context2);
一些开发人员的错误之处在于,他们将创建一个全局变量来存储上下文,并将其设置为Execute()方法中的第一行。这样他们就不必在所有方法之间传递信息。但这实际上是一个巨大的错误。
因为如果他们这样做,并且在上面的场景中,如果thread2中的执行在thread1中的执行完成之前开始。这意味着线程1中的context1将被context2覆盖。现在这个插件会有一些意想不到的结果。在99%的情况下,即使以这种方式错误地开发,也没有问题,或者没有明显的问题。但在1%的情况下,它会导致出现错误,开发人员很难找出错误所在,并且在测试/调试时可能永远不会发生。因此,它可能会在很长一段时间内不固定。

无状态是指不应保留其状态的东西,或者换句话说,我们可以说,每次使用该类的任何功能或成员时,之前使用的/设置的变量不应影响该类/功能的下一次使用

考虑以下代码片段(忽略标准)——

如果其他正在运行的线程在数学类中更改了radius的值,那么getCircleArea()将给出不同的结果,因为变量“radius”的状态可以更改,因为它是一个全局变量。这个问题主要发生在我们使用bean容器的web应用程序中。大多数bean是单例的,只有一个副本。如果我们使用全局变量,则全局变量的值可能会发生变化

要创建无状态类,请尝试使用局部变量,以限制变量的范围。 上面的getCircleArea()示例如下


这是个奇怪的问题。你想解决什么问题?我知道它有点抽象,但我目前正试图理解我是否应该考虑修改我当前的工作代码来合并无状态类(我没有无状态类的经验)…希望我稍微清楚一点……它根本不清楚你所说的“无状态类”是什么意思。你用什么语言?你是说没有数据成员的类,还是其他什么(可能是不可变的对象)?我被要求或者更确切地说是被要求将类myclass{..}更改为内部静态类myclass{..}Humm。。。我不确定我是否同意不可变对象是无状态的。但我想这可能是ashutosh所要求的。我不知道还有什么是无状态类,除非OP使用普通函数需要
类{}的那种语言
block和两个标识符来命名它。你能给我一个例子吗,你一开始没有一个无状态类,然后有一个给你带来了好处?@ashutshraina:不,因为函数式编程已经感染了我的大脑,我倾向于设计不可变的对象,然后在它们看起来绝对必要时添加变异子。这通常是为了表演
yourCustomPluginCached.Execute(context2);
class Maths {
int radius;

public void setRadius(int r) {
    this.radius = r;
}

public float getCircleArea() {
    return (float) (3.14 * radius * radius);
}
}

public class Geometry {
public static void main(String[] args) {
    Maths m = new Maths();
    m.setRadius(14);
    System.out.println(m.getCircleArea());
}
}
public float getCircleArea(int radius) {
    return (float) (3.14 * radius * radius);
}