【问题标题】:New Class Object - Old Values Remain新类对象 - 保留旧值
【发布时间】:2018-10-22 05:21:00
【问题描述】:

我已经使用 C# 大约 3 到 4 年了,但我从来没有真正为使用 Class 系统而烦恼,因为我从来没有真正需要它。

但现在我的项目已经到了可以从中受益的地步。所以我开始创建和使用一个。

所以我有一个 internal 构造函数,它接受 2 个参数(我们只是说字符串)并将它们存储在内部构造函数之外的私有字符串中。

然后我new MyClass("str1", "str2"); 并使用它的所有其他公共方法。 (例如.StartBenchmark()

如果我有 private string thisMustAlwaysStartAs="ThisString123456789";,那就奇怪了 (在构造函数中更改为changed123

当我 new MyClass() 我期待 thisMustAlwaysStartAsThisString123456789 开头但它已经是 changed123 但我创建了一个全新的实例?

(例如,构造函数代码如下,因此您创建 1 个实例,然后创建另一个实例,您将获得 2 个 MessageBox 弹出窗口,第一个是字符串的开头,第二个不是,但那是怎么回事? )

MessageBox.Show(thisMustAlwaysStartAs);
thisMustAlwaysStartAs="changed123";

注意事项: MyClass 没有实现 IDisposable,所以我从不处理它,但这不重要,对吧? thisMustAlwaysStartAs "string" 是一个例子,它实际上不是一个字符串,它是一个 CancellationTokenSource,如果我 Cancel() 它并创建一个新实例,它会创建为已取消。这是否可能是因为 CancellationTokenSource 是 IDisposable 意味着当我完成它时我的意思是 Dipose 它?我知道这会起作用,但是当我创建一个新的 MyClass 时,我假设它实际上创建了一个全新的 CancellationTokenSource 实例,而不是重用另一个 MyClass 实例中的实例。

我是否理解正确?

Q1:为什么即使我 new MyClass() 并从新实例检查,CancellationTokenSource 仍将其 IsCancellationRequested 设置为 true?

Q2:如果是因为我必须 Dispose() CancellationTokenSource,即使我正在创建一个全新的 MyClass(),为什么?

Q3:如果 Q2 正确,我是否应该为 MyClass 和 Dispose CancellationTokenSource 创建一个 IDisposable 实现并在 using() 中使用 MyClass?

如果有什么我遗漏或完全错误的地方,请告诉我!


向我们展示代码

namespace NotEveryQuestionNeedsExamples {
    class Lazy {
        private static CancellationTokenSource CancellationTokenSource = new CancellationTokenSource();
        public bool Stopped => CancellationTokenSource.Token.IsCancellationRequested;
        internal Lazy() {
            if(Stopped) { MessageBox.Show("This shouldn't show up"); }
            CancellationTokenSource.Cancel();//This will make Stopped return true
        }
    }
}

Testing:
new Lazy();
new Lazy();
//If you got ANY messagebox, then CancellationTokenSource somehow got the .IsCancellationRequested from the first Lazy() instance

如果我在internal Lazy() 开头执行CancellationTokenSource = new CancellationTokenSource();,则不会出现此消息框问题

【问题讨论】:

  • 向我们展示代码...
  • @ZoharPeled 完成...
  • 你的CancellationTokenSource静态的...你可以有100个实例,它会使用同一个,因为它是静态的。
  • @MaDude 静态字段是在类的所有实例之间共享的字段。 - 这就是 static 关键字所做的一切,使字段在所有实例之间共享。
  • @MaDude 我真的不明白你怎么能在不知道这些非常基本的东西的情况下使用 c# 工作 3-4 年。我认为您可能已经过了阅读好的 oop/c# 教程的时间了。

标签: c#


【解决方案1】:

Q1:为什么即使我 new MyClass() 并从新实例检查,CancellationTokenSource 仍将其 IsCancellationRequested 设置为 true?

因为它是static,这意味着,对于所有实例(由new 创建的每个对象),它们之间只会共享一个CancellationTokenSource 实例(IsCancellationRequested 只有一个值)。 每个对象都为非静态成员获取自己的值(例如,每个对象都有一个非共享值 Stopped)。

Q2:如果是因为我必须 Dispose() CancellationTokenSource,即使我正在创建一个全新的 MyClass(),为什么?

不,这里和dispose无关,因为是static

Q3:如果 Q2 是正确的,我是否应该为 MyClass 创建一个 IDisposable 实现并从中处理 CancellationTokenSource 并在 using() 中使用 MyClass?

不管 Q2 是否不正确,您的类确实应该实现 IDisposable 来处理它拥有的对象,例如 CancellationTokenSource 的实例,即它们是非静态成员。

我猜 CancellationTokenSource 不应该是 static 在这堂课上

请参阅C# - Static 获取有关静态的教程,第二部分非静态类中的静态成员适用于这种情况。

【讨论】:

    猜你喜欢
    • 2019-07-08
    • 1970-01-01
    • 2020-09-01
    • 2015-07-04
    • 2016-03-08
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多