locked
how to return null from a constructor

    Question

  • say, i a m trying to do something like:

     

    class something

     

    something(streamreader){

        if (wrong format or end of file)

                caller receives null as result

        else

                build object from what has been read in file

    }

     

    i tried 'return null', but it says it can not do that since a constructor is 'void', so i can not place a return sentence. i'm not sure something like this.dispose would retunr a null, since the 'dispose' may be asynchronous (or something)

     

    i have the next alternative

    class something blah blah

     

    somehting(string)

    (build object from string, check if string==null or wrong format before calling)

    static bool checkformat(string)

    check to see if string is adecuate to build something object

    but if i use this, that would mean that i have to parse the string twice, onece to check format and once to build it, so im not too in favour of it, how do i return null from a cosntructor if params are not adecuate?

    Thursday, November 30, 2006 9:07 PM

Answers

  • Hi,
    you can't return null in the constructor. You can try and change the way you're doing things, e.g: you could have a class that would check these parameters for you and if they were correct then it would create an instance of "something" or you could have a method in "something" called Initialize that would perform these kind of verifications and then you could return null.
    Thursday, November 30, 2006 9:26 PM
  • Another option would be to create the class with a private constructor and include a static factory method to validate the input parameters before calling the constructor to create the return object. If the input fails validation then you could return null or throw an exception. Of course, this is not a useful option if the class in question will be base type for other classes.

     

    public class Something
    {
         private Something(int someInput)
         {
              //Initialize object
         }

         public static void Create(int someInput)
         {
              if(someInput is not valid)
              {
                    return null;

              }
         
              return Something(someInput);

         }

    }

    Saturday, December 02, 2006 5:12 AM

All replies

  • a constructor doesnt return anything. It's only job in life is to construct the object. That's all. Nothing else.

    you can only return a value if the method has a return type (non void). also you can return null from string return types or other objects, except for say, integer values

    Thursday, November 30, 2006 9:16 PM
  • Hi,
    you can't return null in the constructor. You can try and change the way you're doing things, e.g: you could have a class that would check these parameters for you and if they were correct then it would create an instance of "something" or you could have a method in "something" called Initialize that would perform these kind of verifications and then you could return null.
    Thursday, November 30, 2006 9:26 PM
  • hmm.. i think i didnt make myself clear.. a constructor, whether is called a constructor or not, is a function, it returns something, actually a pointer to some object of the type of the class it was declared. a variable declared as some kind of object, or whatever inherits form 'object' class, can point to that type of object or have a null value, now, if i call a function and that function returns null for an object, thats a valid value. i am asking how to do that in a constructor. for example, if i was talking about 'plain c', and i made an alloc or malloc or whatever, it may return the pointer to the allocated space or it may return a null if it was not possible to allocate the space. i want to return the object if the object was created succesfully or null if the parameters to create the objet in the cosntructor function, which is an ordinary function in most senses, stated to return an object of some class, are not adecuate
    Thursday, November 30, 2006 9:30 PM
  • it seems thats what i must do, but as stated above, i was trying to avoid that, since i would have to check for validity twice. im not happy about it tough
    Thursday, November 30, 2006 9:32 PM
  • What about making your constructor throw an exception when it isn't created properly, and then use try and catch statements in the function that's calling the constructor?
    Friday, December 01, 2006 4:23 AM
  • it wouldnt be recommended and its bad practice. you should really validate your inputs/objects before creating the class object
    Friday, December 01, 2006 12:38 PM
  • Also note that it is NOT the constructor that is returning the constructed object, but the new operator.

    I'm curious - why is it bad practice to throw an exception in a constructor? I know this is frowned upon in C++ - is the same true for C#, and why?

    Friday, December 01, 2006 1:40 PM
  • well because exceptions are expensive and because it's the way the design pattern is really. Maybe the same reason for C/C++? (I dont dev in C/C++)

    It's just not recommended and I've not seen any classes that throw an exception via the constructor, except for maybe invalid inputs but even then its recommended to check/validate your inputs before constructing an object - its better design.

    Friday, December 01, 2006 2:07 PM
  • It isn't bad practice to throw an exception from a constructor. If the inputs are invalid or the object cannot be constructed then you should throw exceptions as with any other member. You have to write your class with no control over how it will be called (unless it is an internal class) so the only defence you have against invalid inputs is exceptions.

     

    Friday, December 01, 2006 2:58 PM
  • Note, it is not a bad practiceto throw an exception is a ctor (either in C# or C++).

    It isa bad practice to allow an exception to leave an object in a "half-constructed" state.

    For example (in C++):

    class MyClass
    {
          char* ptr1;
          char* ptr2;

    public:
         MyClass()
        {
             ptr1 = new char[100];
             ptr2 = new char[10000];
        }
    }

    In that example, if the new for ptr2 throw an out of memory exception, the memory of ptr1 would be lost as a memory leak.  The ctor should be written as:

         MyClass()
        {
             ptr1 = NULL;
             ptr2 = NULL;

           try {
             ptr1 = new char[100];
             ptr2 = new char[10000];
          }
         catch(...)
         {  
             delete[] ptr1;
             delete[] ptr2;
             throw;
         }
       }

    Friday, December 01, 2006 4:13 PM
  • Ahmedilyas: "it wouldnt be recommended and its bad practice. you should really validate your inputs/objects before creating the class object "

    No mate. Validating a function's (or constructor's) arguments outside the function itself is the bad practice. If the function's interface changes even a tiny bit, you have a lot of search/replacing to do or you'll be throwing exceptions anyways.

    And arguments about exceptions are way more expensive than the exceptions themselves. Since they're only supposed to be used in *exceptional* circumstances, they should never slow anything down in normal use. Especially in a constructor, where there's just been a slow memory allocation.

    Bad practice is obfuscating and duplicating code to avoid throwing exceptions.
    Friday, December 01, 2006 10:55 PM
  • ah well we have our own views but I still wouldnt recommend it. Always been told throwing an exception in a Constructor is not the way to go about doing things and should be validated before hand before constructing an object.

    as long as the original question is resolved...

    Friday, December 01, 2006 10:57 PM
  • I don't think the original question has been resolved. The OP is talking about "validating twice." This is exactly why I say not throwing exceptions from a constructor is bad practice.

    As far as I can see, there are only two proper ways to safely handle object initialization:
    • Throw exceptions from the constructor
    • Don't use exceptions, use empty constructors, and have an Init() method with a return value to indicate success or failure
    Throughout the .NET framework, the first choice is prevalent.
    Friday, December 01, 2006 11:05 PM
  • Another option would be to create the class with a private constructor and include a static factory method to validate the input parameters before calling the constructor to create the return object. If the input fails validation then you could return null or throw an exception. Of course, this is not a useful option if the class in question will be base type for other classes.

     

    public class Something
    {
         private Something(int someInput)
         {
              //Initialize object
         }

         public static void Create(int someInput)
         {
              if(someInput is not valid)
              {
                    return null;

              }
         
              return Something(someInput);

         }

    }

    Saturday, December 02, 2006 5:12 AM
  • I'm glad some of you agree that throwing exceptions from a constructor is not necessarily bad practice, as I tend to do this, e.g., in the input arguments are invalid.

    I think it is one of those rules that has been handed down and got garbled in the process.

    Throwing an exception from a constructor is bad IF the object is left half constructed. In C++ this could be a real problem where you have to manage all the memory yourself. So the rule has warped into "do not throw exceptions from a constructor".

    In C# this less likely to be a problem, and an exception is often the best way to report an error when creating an object, as long as the application state remains consistent before and after the exception.

    Monday, December 04, 2006 1:32 PM
  • You could have the constructor create an empty object and then have an Init method to process any actual data and fill the object. The Init method could return NULL or an error code that would give the caller more information. Hell, you could even add a GetError method to give detailed error information.

    This way you never have an object that's half constructed, it would simply be set to default values. Any calls to the empty object could fail safely.

    I agree that throwing an exception in a constructor is not the way to go. You would be simply setting yourself up for future heartbreak.

    Monday, December 04, 2006 8:37 PM
  • There are MANY classes in the .Net framework that throw exceptions, so it is totally untrue to say that it is not recommended practice!

    Examples include:

    DateTime
    List<T>
    Queue<T>
    String()
    Encoding()

    ...and many, many more. In fact, it's difficult to find any .Net constructor that takes a parameter that DOESN'T throw an exception!

    Tuesday, December 05, 2006 1:13 PM
  • Although I still don't see a problem with throwing an execption from a constructor, it seems that a few people still don't agree. So how's this for a compromise: Instead of throwing an exception or using a separate Init() function, why not declare the constructor like this:

        public Something(string szInput, out bool errorOccurred)

    Then if there's a problem with the input, or if there isn't enough memory for the object, the calling method will know by checking the value of errorOccurred. Eh?

    Tuesday, December 05, 2006 11:59 PM
  • Since parameter-accepting constructors for most .Net classes can throw exceptions, I think people just have to suck it up and accept that constructors will throw exceptions.

    I'm not sure where the idea came from that it's bad for a constructor to throw an exception. Could it be that people are confusing it with the fact that C++ destructors should never throw an exception?

    Anyway, people MUST TAKE NOTE that something as innocent looking as:

    using (FileStream myStream = new FileStream("myFile", FileMode.OpenOrCreate))
        ...

    can throw no less than NINE different kinds of exceptions.

    To be honest, it is somewhat worrying that there can be so much debate about exceptions in constructors. Are people writing code that blithely ignores the exceptions that can be thrown from all the .Net types?
    Wednesday, December 06, 2006 9:46 AM
  • This is the most obvious solution except the Create method should return a Somehting object instead of void.
    Wednesday, December 06, 2006 3:33 PM
  •  Matthew Watson wrote:

    Anyway, people MUST TAKE NOTE that something as innocent looking as:

    using (FileStream myStream = new FileStream("myFile", FileMode.OpenOrCreate))
    ...

    can throw no less than NINE different kinds of exceptions.

    To be honest, it is somewhat worrying that there can be so much debate about exceptions in constructors. Are people writing code that blithely ignores the exceptions that can be thrown from all the .Net types?

    Now you know why so much software is so buggy.  People don't want to handle errors - a) it's hard to do well and b) it disrupts the flow of what might otherwise be clean and easy to read code.

    Unfortunately, it's necessary and I'm with you.. you gotta do what you gotta do.  But the answer is yes.. I think alot of people DO blithely ignore the possible exceptions.

    I have the luck of working with people who love breaking software though, so the stuff I write usually gets a good pounding.  While it's impossible to create bug-free software, I think I at least get the opportunity to create very reliable software..

    Friday, December 08, 2006 5:37 PM
  • A couple of the posts in this discussion have highlighted the reasons to prefer factory methods over constructors. I can't give a constructor a meaningful name, and I can only have the ctor return a single object of a specific type. Using a constructor is hard coding a dependency into an application - which will need to happen occasionally, but can also hurt testability and maintainability.

    It sounds like the original poster has a scenario where some complicated logic is required to construct the right object - and this is a place where I'd favor using a factory method over both a constructor and over any "Init" type / two step initialization technique. Two phase construction introduces more complications than throwing from inside a constructor would ever introduce. What happens if Init is called twice? What sort of checks do I need to place into every method to ensure Init was correctly invoked once and once only? Life is simpler if I know the object is created all at once or not at all.

     

    Friday, December 08, 2006 7:15 PM
  • The best way I know to return null from constructor or to cancel a constructor is this:

     

    public class Person
    {
        public Person(int age, out Person result)
        {
            result = this;
            if (age > 120)
            {
                result = null;
                return;
            }
            // Continue with constructor...
        }
    }


    // Call constructor and return null if person is more than 120 years old.
    Person p;
    new Person(130, out p);

     

    // p is Null

    www.signumsoft.com

    Friday, March 21, 2008 11:23 AM
  •  Dst2 wrote:

    The best way I know to return null from constructor or to cancel a constructor is this:

     

    public class Person
    {
        public Person(int age, out Person result)
        {
            result = this;
            if (age > 120)
            {
                result = null;
                return;
            }
            // Continue with constructor...
        }
    }


    // Call constructor and return null if person is more than 120 years old.
    Person p;
    new Person(130, out p);

     

    // p is Null

    www.signumsoft.com

    I don't think that returning a null from a constructor is a good programming practice.  That appears to be valid code that returns valid objects, not nulls.  It would require intimate knowledge of the code to realilze that a null was being returned.  Works great if you have the source code for Person.  Too bad if you don't

     

    Rudedog

    Friday, March 21, 2008 6:00 PM
    Moderator
  • An easier, and mucht more sensible way to deal with this is (if you really didn't want to throw an exception):


    public class Person
    {
        public bool IsValid {get; private set }
        public Person(int age)
        {
            IsValid = true;
            if (age > 120)
            {
                IsValid = false;
            }
            // Continue with constructor...
        }
    }


    Person p = new Person(130);
    if (p.IsValid)
    { ...... }

     



    Tuesday, March 25, 2008 3:15 PM
  • I agree with Scott, a factory method would be ideal for this situation.  Having to create a Person object to create another Person object isn't right...

     

    Tuesday, March 25, 2008 3:31 PM
    Moderator
  • Everything I've read on the subject from Microsoft indicates that it is perfectly valid to throw exceptions in constructors, and that in fact exceptions should ALWAYS be used to report errors so that errors are always reported and dealt with consistently.  Most of the suggestions posted here to avoid throwing an exception in a constructor (such as returning the object as an out parameter), actually violates the design guidelines established by Microsoft for .NET.

     

    The only time you really want to avoid throwing an exception is when you except it to happen in the normal flow of the program.

     

    That said, using factory methods is a perfectly reasonable approach when one needs to do something that can't be done with a constructor, such as the option of returning null instead of a valid object.

     

    Tuesday, March 25, 2008 5:38 PM
  • Don't like the IsValid idea at all.  You are given the illusion the object was created (because you've had one returned to you).  It's way to easy to forget to call IsValid because, for starters, you have to notice that the class has an IsValid property.

     

    The pattern I've seen used with great success is:  Have a C'Tor and a TryCreate(input, out objectCreated) method.  If you use the C'Tor, be prepared for exceptions.  If you use the trycreate, be prepared to get back false and have objectCreated be null.

     

    Thursday, May 01, 2008 11:47 PM
  • I think this whole discussion here have derailed.

    Exceptions are used for *exceptional* cases. Yes, they're more costly than simply an if-statement with a "return null" statement inside, but the thing is that the "return null" case will only happen as *an exception*, it should not be the general case.

    If you have to validate input from a file, like a CSV file full of data, then throwing exceptions on 50% of the data will slow down the import. On the other hand, if you *know* that the first column will be a valid Int32 valid, doing a Int32.Parse, which will throw an exception on bad input, is *exactly the right idea*.

    Constructors *should* throw exceptions on bad data, unless you can *guarantee* that the constructor is only called from controlled methods, like factory methods that is in the same library. You should *never* assume the caller has done the job required to validate the input. But again, as long as the invalid data are *exceptions* and not the rule, you won't have a problem with performance.

    The alternative is the odd bug where the wrong data slipping through to a class will cause unpredictable results later on. Without the fail-at-once mentality, you're going to use more time to figure out why a class fails at a particular point when in fact you could've known about the problem well in advance, and at the point where the wrong data was given to the class, which will typically give you a stack trace that shows the location that the real bug is: the code that is calling your constructor with wrong data.

    As for handling the problem, if all you do is return "I can't do this", you might compare this to a lightweight version of "throw new Exception();" where you simply don't tell the caller what exactly went wrong. This will make finding and fixing bugs in this code that much harder when all you know is that it "doesn't work". I'm sure most of you have heard that phrase from coworkers, support, customers, etc. and wondered how these people could work when they can't even read a simple error message back to you, but if you follow this "return null" way of doing things, you're ensuring this is all you'll ever know. I'm pretty sure the user of your software would feel much better too if the program told him that "The file you picked has the wrong file format" instead of just "I can't open that file", which, as was shown, could be from nine different exceptions (like ACL, file locked, network no longer there).

    Personally I advocate that all public methods should throw exceptions if the data that is invalid is exceptional, or there is no (known) way to process that particular type of data. If for no other reason you'll get a crash which tells you that "this particular combination of data was invalid according to the rules I know at the moment", and then you can go figure out if you need to extend your method to handle that case.

    Under no circumstances is it bad to throw exceptions from a constructor as *a general rule*. It might be that you want to prevent costly exceptions that will occur a lot because you're doing things that will often fail (like the import case), but in that case you will still use exceptions for the absolutely invalid data, and then pre-validate the data to avoid the throw at all.

    The exception, however, is the last defense for the class. If you drop that, all bets are off.

    This is my 2 cents, but if someone is going to challenge this with "throwing exceptions in constructors is bad practice" then I challenge you to come up with the source for this bad practice, otherwise its just an opinion.
    Sunday, May 04, 2008 11:30 AM
  • I am not good at English and I am programmer beginner. I looked for this information too and everywhere was, that constructor cant return value. What about this solution:

    class something
    {
    public:
      something()
      {
        if ( !{test validity} )
        {
          delete(this);
          (something*)this = NULL;
        }
      }
    }

    But I dont know if it is correct way (all allocated memory from class will be destroyed etc...).
    Next problem is that I am deallocating memory in which program running...
    So write your opinion if I can solute this problem by this way.
    Monday, September 08, 2008 12:57 PM
  • "I am not good at English and I am programmer beginner. I looked for this information too and everywhere was, that constructor cant return value. What about this solution:"


    The this keyword is read only and you cannot assign to it.

    You cannot have a constructor that returns null. Your best bet  is to create some static methods in your class that have the abilities of creating an object of your type based on your requirement :

    1public class Foo 
    2
    3    private Foo() 
    4    { 
    5         //do some init here 
    6    } 
    7 
    8    private Foo(int args1, long args2) 
    9    { 
    10         //do some init here 
    11    } 
    12 
    13    public static Create() 
    14    { 
    15        return new Foo(); 
    16    } 
    17 
    18    public static Create(int args1, long args2) 
    19    { 
    20        return new Foo(args1, args2); 
    21    } 
    22
    23 
    24You can then call the code as follows : 
    25 
    26Foo foo = Foo.Create(); 



    Enjoy

    Agility. http://salakoahmed.blogspot.com
    Monday, September 08, 2008 3:23 PM
  • Lasse V. Karlsen said:

    I think this whole discussion here have derailed.


    Anyone who'd like to add to this thread, could you please scroll up to Lasse's statement on May 4th.  Sums it up very well.  The constructor is no place for user input, or text file input validation.  The constructor's job is to construct things and if it will be handed garbage data regularly, it should throw(up) an exception regularly.  By the way, learn "Design Patterns", the Object Factory pattern is classic and should be used where it fits.  It may apply in this case, but not as a way to get around constructors not returning null.

    IMHO...


    Les Potter, Xalnix Corporation, Yet Another C# Blog
    Monday, September 08, 2008 4:21 PM
  • A long time ago in a galaxy far away...

    There was cpp, where you could explicitly define operator new, which was calling malloc(). It was easy to return NULL calling new operator. It was very interesting feature. It was used to create very complicated programs by almost very complicated programmers. These programs were debugged by very hard bugslayers. Right than very hard bugslayyers had beaten complicated programmers.
    Wednesday, July 29, 2009 1:31 PM
  • You can not return null in the constructor but you can overload the == operator and make the result look like it's null.

    Following code works fine: (You don't need to override GetHashCode and Equals. But compiler throws warning if you don't)

    Person p = new Person(150);
    if (p == null)
    {
        MessageBox.Show("Yes it's null!");
    }



    And this is the Person class:

    public class Person
    {
        public Person(int age)
        {
            if (age > 120)
            {
                isNull = true;
            }
        }
    
        private bool isNull;
    
        public static bool operator ==(Person personA, Person personB)
        {
            if ((object)personA != null && personA.isNull)
            {
                personA = null;
            }
            if ((object)personB != null && personB.isNull)
            {
                personB = null;
            }
            return object.Equals(personA, personB);
        }
    
        public static bool operator !=(Person a, Person b)
        {
            return !(a == b);
        }
    
        public override int GetHashCode()
        {
            if (isNull)
            {
                return 0;
            }
            return base.GetHashCode();
        }
    
        public override bool Equals(object obj)
        {
            if (obj is Person)
            {
                if (((Person)obj).isNull)
                {
                    obj = null;
                }
            }
            return base.Equals(obj);
        }
    }
    
    Wednesday, January 13, 2010 9:17 PM
  • If possible, use the Null-object pattern.  Don't return a null if at all possible, because you start checking for NULLs everywhere.

    As an example, in the "build object from what has been read in file", have your null object return an empty list (or empty StreamReader). 

    If the problem is (contrived example) that your streamreader is supposed to load the contents of a file, and that file doesn't exist, throw an exception (Even if its in the constructor).  Validate your inputs, throw exceptions, and handle those exceptions where necessary.
    Wednesday, January 13, 2010 11:34 PM
  • Forcing Object Construction via a Factory Method or allowing use of a Static validation Method is fine if all you care about is whether it was / can be created or not. However, what if, in cases when it was not / could not be created, you also want to know to know the reason(s) why?

    1. You could have a Parameter on the Factory Method that tells you why but: a) you'd need to declare a separate Variable to hold the results of that Parameter and b) to follow good practices, do so in every place you're trying to create the Object vs. sharing a Global one.

    2. You could Throw a custom Exception but that would require use of the Try Statement, which: a) is cumbersome, b) IMHO, should be reserved for unexpected errors where you just want to display and / or log an error(s) and exit vs. recover and continue processing and c) cannot be enforced to exist (via a Base Class or a more generic Interface) to exist like a Public Variable / Property of the Class.

    3. You could have a Shared validation Method but: a) it would have the same disadvantage as option 1 above, plus b) it would have to duplicate the Parameters needed by the Constructor and the appreciating human cost of that duplication is usually much more significant than the depreciating machine costs of Constructing an Object only to Destruct it shortly after.

    For commonly expected errors (like the User typed in an invalid value(s) needed to create the Object), it's much easier to just check one or more Public Variable(s) / Property(ies) of the Class
    Friday, June 29, 2012 6:30 PM
  • Forcing Object Construction via a Factory Method or allowing use of a Static validation Method is fine if all you care about is whether it was / can be created or not. However, what if, in cases when it was not / could not be created, you also want to know to know the reason(s) why?

    .................................

    For commonly expected errors (like the User typed in an invalid value(s) needed to create the Object), it's much easier to just check one or more Public Variable(s) / Property(ies) of the Class

    For commonly expected errors, why not validate the parameters prior to using them?

    If it is possible to determine the reason "why" after the fact, shouldn't you be able to determine the reason before the fact?

    I have a previous post on this thread.  You cite the fact that try/catch is undesirable, which I agree with.  Throwing an exception would be deceptive and misleading.  A Factory Method seems to be the only best choice.  The are examples of this in the Base Class Library; i.e. Delegate.CreateDelegate.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Saturday, June 30, 2012 10:50 AM
    Moderator
  • For commonly expected errors (like the User typed in an invalid value(s) needed to create the Object), it's much easier to just check one or more Public Variable(s) / Property(ies) of the Class

    It would be even easier to forget to check those public variables, and to start using the object as if it had been constructed correctly.

    Personally, I think your suggestion that the class should validate the user input is suboptimal. It should be the responsibility of a business logic class to do that kind of verification, and then the verified data should be passed to the constructor of the object that requires the input data to be correct. Any user of the "verified" class can be sure that it is in a usable state.

    If you allow a class to have a property that tells you if it was properly constructed or not, then *every* method that is passed such an object will need to check that property. Not only that, such methods will need to decide what to do if the object is NOT properly constructed. That would not be a great design...


    Monday, July 02, 2012 7:52 AM
  • @Rudedog2 and Matthew Watson: First of all, I'm sincerely honored to have replies by an MVP and a 22 k Pts member.  Thanks for your replies.

    If an App was designed to validate "expected" errors in data needed for an Object's Construction prior to that Object's Construction (via "Business Logic" or whatever), then if those errors somehow still managed to occur during that Object's Construction, then: a) at that point, those would be "unexpected" errors and therefore not the "expected" errors my recommendation is for, and b) something went terribly wrong and in this case, I would actually recommend Throwing an Exception vs. even Returning Null (to prevent possible continuation of processing based on and / or generating invalid / corrupted data).

    When dealing with existing code, the best compromise may be to add Optional Constructor Parameter(s) (i.e. to: a) specify whether to Return vs. Throw Error(s) and b) to Return the Error(s)), so you can activate them as needed on a per - Construction basis.

    Thursday, July 05, 2012 5:08 PM
  • @Rudedog2 and Matthew Watson: First of all, I'm sincerely honored to have replies by an MVP and a 22 k Pts member.  Thanks for your replies.

    If an App was designed to validate "expected" errors in data needed for an Object's Construction prior to that Object's Construction (via "Business Logic" or whatever), then if those errors somehow still managed to occur during that Object's Construction, then: a) at that point, those would be "unexpected" errors and therefore not the "expected" errors my recommendation is for, and b) something went terribly wrong and in this case, I would actually recommend Throwing an Exception vs. even Returning Null (to prevent possible continuation of processing based on and / or generating invalid / corrupted data).

    When dealing with existing code, the best compromise may be to add Optional Constructor Parameter(s) (i.e. to: a) specify whether to Return vs. Throw Error(s) and b) to Return the Error(s)), so you can activate them as needed on a per - Construction basis.

    Thanks for the compliment.  

    Under the scenario you describe above, I would not call those circumstances "unexpected errors".   I would call them "bugs".  A Factory Method should return null or a valid object.  In fact, you do not even need to throw an exception.  I say let the OS do it for you because that is most likely what will happen anyway.

    If your Factory Method has the potential to throw exceptions, then it should catch them and return a null object.  If the code is for your own internal use, then proceed by whatever means seems most logical and appropriate.  I'm just saying that I would be livid if a constructor threw an exception on me.  To me, that's a bug.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/


    Thursday, July 05, 2012 5:24 PM
    Moderator
  • @Rudedog2: You're welcome.

    Re. "I would call them "bugs".": I agree.  That's precisely why I think they should generate Exceptions vs. just returning a Null and hoping that all instances of Calling Code will properly suspend / abort processing when Null is returned.

    Re. "In fact, you do not even need to throw an exception.": When I said "Throw an Exception", I meant indirectly (by allowing a Runtime Error to occur un-Catch'ed) or indirectly (via an explicit Throw Statement) both from inside the Constructor.

    Re. "I would be livid if a constructor threw an exception on me.": Welll, Class Constructors in the .NET Framework do that all the time (albeit for what I would call "unexpected" errors / "bugs" in the Calling Code).  Ex. "String(Char, Int32)", "List(Of T)(Int32)", "List(Of T)(IEnumerable(Of T))".



    Sent from my iMind

    Thursday, July 05, 2012 6:56 PM
  • I didn't look up all of the constructors that you listed, but the String constructor throws an IndexOutOfRange Exception, which is documented.  Remember, the original question is how to return null from a set of invalid parameters.  The  recommendation is to use a Factory Method, not a constructor, per se.

    Also, using a negative integer to index an array should throw an exception, and it is something that the consumer should catch.  The original question was how to throw the exception and return something, preferably a null.  I would bet that the other types you cited throw exceptions for invalid parameters, not unexpected or unforeseen issues.

    [EDIT]  List<T> throws an exception if the parameter is null.  Again, another developer error that has been foreseen.  Not the scenario posed by the original question.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Thursday, July 05, 2012 9:41 PM
    Moderator
  • Re. "the String constructor throws an IndexOutOfRange Exception": Huh?  The String Constructor example I listed was "String(Char, Int32)" which, according to the MSDN docs, Throws an "ArgumentOutOfRangeException" (not "IndexOutOfRange") Exception (btw, when "count is less than zero" which the Parameter's Type of "Integer" does not prevent).

    Re. "which is documented": Huh?  I never claimed it wasn't.  If you're just trying to imply that being "documented" means it's not an "unexpected" error, then see my 3rd "Re." after this one.

    Re. "Remember, the original question is how to return null from a set of invalid parameters.  The  recommendation is to use a Factory Method, not a constructor, per se." and "The original question was how to throw the exception and return something, preferably a null.": Huh?  The O.P. asks at the end of his post "how do i return null from a cosntructor if params are not adecuate?".  The answer to the O.P.'s literal Q. is "No, you can't do it".  Now the *closest* *workaround* to what he's asking for is to force use of a Factory Method (which returns Null on errors) vs. a "cosntructor".  Regardless of whether one uses a *theoretical* Constructor that *could* return Null or a Factory Method that *can* to Construct an Object, what I (and others including yourself) have been trying to also point out is that it's bad practice to rely on it doing so *if* it's doing so due to errors that the App was supposedly designed to catch (i.e. via "Business Logic") before Object Construction.  In addition to that, I (and I think no one else in this Thread) am also trying to point out that *if* the errors were designed to be caught before Object Construction, then the Class should not *quietly* announce the errors by simply returning Null, but *instead / also* *loudly* announce them by (directly / indirectly) Throwing Exceptions from inside the Constructing Method (New or Factory) so that it's much less likely the Consumer will continue processing (by simply avoiding References to the Null Object because I think the code to do so is much less likely to be well designed / tested code which therefore is much more likely to result in invalid processing / corrupted data without generating other error messages and / or doing so later in the process when it's harder to trace the source and / or recover from the damages) vs. aborting.  BTW, in the O.P.'s specific example where the Class' Constructor is checking for "wrong format or end of file (?aka empty file?)" prior to returning an Object that represents the File's contents, I don't think his App was designed to check for those errors prior to Object Construction, nor do I think it should've been.  I think that in that specific example: a) the validation logic should be encapsulated inside his Class which would make the errors they catch "expected" errors at the time of Object Construction and b) *if* his Consumer code wants to know why the Construction failed, then I recommend the Object return the error(s) via Public Variable(s) / Property(ies) or Optional Parameter(s) on the Constructing Method (New or Factory).

    Re. "Also, using a negative integer to index an array should throw an exception, and it is something that the consumer should catch.": Did you mean "should catch" with a Try - Catch Statement around the Constructor Call or (as several of us including yourself have recommended above) before even calling the Constructor?

    Re. "I would bet that the other types you cited throw exceptions for invalid parameters, not unexpected or unforeseen issues.": As I was trying to point out in my 2nd reply above, whether an error is considered "unexpected" / "unforeseen" / "bug" (in the Consumer) at the point of Object Construction depends on whether the Consumer was designed to catch those errors prior to Object Construction.  If the latter was, then the former is.  As for the .NET Classes, since they're Throwing Exceptions vs. returning errors from their Constructors and we can't change them, then I think the best practice would be to validate the Parameters prior to calling a .NET Class Constructor which would make the errors "unexpected" inside the .NET Constructors such that if somehow my validation logic failed, I'd want errors due to it to be *loudly* announced by the Constructor via Thrown Exceptions and either: a) just generate a Runtime Error and abort the App or b) be Catch'ed via a Try Statement but only for display / logging purposes before ultimately aborting the App.


    Sent from my iMind

    Friday, July 06, 2012 12:27 AM
  • I'm just saying that I would be livid if a constructor threw an exception on me.  To me, that's a bug.

    Sure it's a bug - in your own code, not in the constructor throwing the exception. :)

    How do you deal with the myriad of .Net types that throw exceptions from their constructors?

    * DateTime - if you pass in an illegal year/month/day combination

    * FileStream - if you try to open a non-existent file.

    * Hundreds of other classes - if you pass in null for parameters that are not allowed to be null.

    There are so very many - how do you deal with it?

    To me it is pretty clear that if you commit a programming error by passing bad data to a constructor, you should get an exception.

    I would like to point you at Microsoft's documentation for Constructor Design. In particular, note the comment: Do throw exceptions from instance constructors if appropriate.

    Friday, July 06, 2012 8:16 AM