【问题标题】:How can I set the value of a private field in a private nested class?如何在私有嵌套类中设置私有字段的值?
【发布时间】:2013-10-12 00:01:45
【问题描述】:

我有以下具有嵌套私有类的类,我想将NID 的值分配给Context。我使用过 getter 和 setter,但是 NID (Sequencer.Context = value;) 的值永远不会分配给 (SeqNode = Node.LoadNode(Context);)。我做错了什么?

//Instantiation
Increment.NID = "/Root/Dir/NodetoIncrement";
String getSequence = Convert.ToString(Increment.SID);

// The Class
public static class Increment
{
    //Value of the node Context location in the tree to increment ( Increment.NID )
    public static string NID
    {
        set { Sequencer.Context = value; } //The "/Root/Dir/NodetoIncrement";
    }

    //Get the sequence ID
    public static int SID
    {
        get { return Sequencer.GetSeqId; }
    }

    //Nested sequencer class. This increments the node.

    private class Sequencer
    {   
        private Node SeqNode;
        private static int SequenceNumber;
        private volatile bool Run = true;

        public static string Context { get; set; } //gets 

        public static int GetSeqId
        {
            get
            {
                return Interlocked.Add(ref SequenceNumber, 1);
            }
        }

        public Sequencer() //Constructor Here!
        {
            SeqNode = Node.LoadNode(Context);
            SequenceNumber = Convert.ToInt16(SeqNode["LastSequenceNo"]);

            //NEVER DO THIS .. causes the system to lockup see comments.
            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                while (Run)
                {
                    Save();
                    Thread.Sleep(5000);
                }
            });
        }

        private void Save()
        {
            //optimistic concurrency recommended!!
            var retryMaxCount = 3;             // maximum number of attempts
            var cycles = 0;                    // current attempt
            Exception exception = null;        // inner exception storage
            while (cycles++ < retryMaxCount)   // cycle control
            {
                try
                {
                    SeqNode["LastSequenceNo"] = Convert.ToString(SequenceNumber);
                    SeqNode.Save();

                    // successful save, exit loop
                    exception = null;
                    break;
                }
                catch (NodeIsOutOfDateException e)
                {
                    exception = e; // storing the exception temporarily
                    SeqNode = Node.LoadNode(Context);
                }
            }
            // rethrow if needed
            if (exception != null)
                throw new ApplicationException("Node is out of date after 3 attempts.", exception);
        }


        ~Sequencer() { Save(); }

    }
}

public class XYHandler : Node
{
    public override void Save(NodeSaveSettings settings)
    {
        base.Name = Convert.ToString(Increment.SID);
        base.Save();
    }

    public override bool IsContentType
    {
        get { return true; }
    }
}

【问题讨论】:

  • 将字段设为私有没有任何意义,该类已经是私有的。这样只需将其公开并解决您的问题。
  • 我认为您提供的信息不足以让我们帮助您。
  • 我也添加了实例化。

标签: c#


【解决方案1】:

我做错了什么?

您正在等待静态初始化程序中的另一个线程。 永远不要这样做。我不能足够强烈地强调这是多么疯狂的危险。

有关原因的解释,请参阅此答案:

https://stackoverflow.com/a/8883117/88656

【讨论】:

  • 感谢您的提醒,但我现在的问题是;在这种情况下实现线程并避免锁定的最佳方法是什么?
  • @xdrone:别去那里。静态构造函数应该初始化一些静态字段,仅此而已。不要做任何花哨的事情。
【解决方案2】:

这里有一些时间耦合吗?

SeqNode 是在 Sequencer 被实例化时设置的,但我在您的示例中看不到实例化。

静态构造函数将在第一次调用属性设置器之前运行,然后在 5 秒后重试 - 何时设置属性?

【讨论】:

  • 是的,时间耦合在这里起作用!要递增的节点在 Sequencer 可以递增之前传递给 SeqNode。 “静态构造函数将在第一次调用属性设置器之前运行,然后在 5 秒后重试 - 何时设置属性?”没有构造函数( SeqNode = Node.LoadNode(Context); )应该触发 Context getter,它应该返回 NID 的值。
【解决方案3】:

我看不到 Sequencer 的构建位置(也许我错过了它)。由于它不是静态构造函数,因此必须至少调用一次 LoadNode 才能运行。您是否也打算使该构造函数成为静态的?

【讨论】:

  • 我在构造函数上添加了注释。
  • 添加注释不会使构造函数变为静态。看看这个:msdn.microsoft.com/en-us/library/k9x6w0hc.aspx
  • 我回复说“我看不到 Sequencer 的构建位置(也许我错过了)。”
猜你喜欢
  • 1970-01-01
  • 2015-01-15
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多