locked
What does this mean? RRS feed

  • Question

  • public class Man
    {
    public string Name;
    public bool LikesWater;
    public bool LikesHumans;
    
    public Man(){}
    public Man(string n) { Name = n;}
    }
    
    
    
    Man temp1 = new Man();
    temp1.Name = "Bo";
    temp1.LikesWater = true;
    temp1.LikesHumans = true;
    Man b1 = temp1;
    
    Man temp2 = new Man("Bo");
    temp2.LikesWater = true;
    temp2.LikesHumans = true;
    Man b2 = temp2;
    
    

    What does this mean:

    The temporary variables are to exnsure that if an exception is thrown during initialization you can't end up with half-initialized object.

    How & why do the temps help?

    Sunday, September 15, 2013 12:39 PM

Answers

  • "I also executed your code,and I don't see any true or false at all,it appears b1 remain null."

    But that's the whole point, b1 remains null instead of referencing a partially initialized object. Consider what happens if you assign to b1 directly instead of using temp1:

            static void Main(string[] args) {
                Man b1 = null;
    
                try {
                    b1 = new Man();
                    b1.Name = null;
                    b1.LikesWater = true;
                    b1.LikesHumans = true;
                }
                catch {
                    if (b1 != null)
                        Console.WriteLine(b1.LikesWater);
                }
            }
    

    This prints 'false' because LikesWater has never been assigned the value 'true' due to the exception thrown by the Name property - b1 references a partially initialized object.

    • Proposed as answer by BonnieBMVP Sunday, September 15, 2013 11:29 PM
    • Marked as answer by Caillen Sunday, September 22, 2013 1:03 PM
    Sunday, September 15, 2013 7:43 PM

All replies

  • Well, it means pretty much what it says. If you assign the new object to b1 and an exception is thrown after assigning to b1 but before those 3 fields are assigned values then it would be possible for some code to use b1 even though not all those fields have been assigned value - a half-initialized object.

    But in the given example an exception is practically impossible, the only exception that could occur during those field assignments is a ThreadAbortException and that's relatively rare.

    Here's an example that attempts to better illustrate this:

        public class Man {
            private string name;
    
            public string Name {
                get { return name; }
                set { if (name == null) throw new ArgumentNullException("value"); name = value; }
            }
    
            public bool LikesWater;
            public bool LikesHumans;
        }
    
        class Program {
            static void Main(string[] args) {
                Man b1 = null;
    
                try {
                    Man temp1 = new Man();
                    temp1.Name = null;
                    temp1.LikesWater = true;
                    temp1.LikesHumans = true;
                    b1 = temp1;
                }
                catch {
                    if (b1 != null)
                        Console.WriteLine(b1.LikesWater);
                }
            }
        }
    

    Note how the exception handler checks for null and doesn't display anything in that case. If you were to assign directly to b1 then this code would print 'false' because LikesWater was never assigned due to the exception thrown by the Name property setter.

    • Proposed as answer by BonnieBMVP Sunday, September 15, 2013 11:29 PM
    Sunday, September 15, 2013 1:56 PM
  • I don't get it,why is there a need for b1 at all? The exception is thrown when the name = null. Are you telling me that after the exception gets thrown,then likeswater & likeshumans get initialized?

    I also executed your code,and I don't see any true or false at all,it appears b1 remain null.

    Sunday, September 15, 2013 7:28 PM
  • "I also executed your code,and I don't see any true or false at all,it appears b1 remain null."

    But that's the whole point, b1 remains null instead of referencing a partially initialized object. Consider what happens if you assign to b1 directly instead of using temp1:

            static void Main(string[] args) {
                Man b1 = null;
    
                try {
                    b1 = new Man();
                    b1.Name = null;
                    b1.LikesWater = true;
                    b1.LikesHumans = true;
                }
                catch {
                    if (b1 != null)
                        Console.WriteLine(b1.LikesWater);
                }
            }
    

    This prints 'false' because LikesWater has never been assigned the value 'true' due to the exception thrown by the Name property - b1 references a partially initialized object.

    • Proposed as answer by BonnieBMVP Sunday, September 15, 2013 11:29 PM
    • Marked as answer by Caillen Sunday, September 22, 2013 1:03 PM
    Sunday, September 15, 2013 7:43 PM