Resolved Prohibit the creation of an object

rammfire

Member
Joined
Sep 1, 2020
Messages
14
Programming Experience
Beginner
Hello everyone. Let's imagine a situation that I have a class inside which there is a property. The property does not equate the value of a variable if the length of the incoming value is greater than the specified condition.
C#:
    public class Book
    {
        string bookDescription = null;
        public string TitleOfBook { get; set; }
        public string BookDescription
        {
            get
            {
                return bookDescription;
            }
            set
            {
                if (value.Length > 20)
                {
                    Console.WriteLine("Description is too long");
                }
                else
                {
                    bookDescription= value;
                }
            }
        }
    }
Filling the array

C#:
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            Book[] books = new Book[5];

            for (int i = 0; i < books.Length; i++)
            {
                Console.WriteLine($"Create book number {i}");
                Book tempBook = new Book
                {
                    TitleOfBook = Console.ReadLine(),
                    BookDescription = Console.ReadLine()
                };
                books[i] = tempBook;
            }

            for (int i = 0; i < books.Length; i++)
            {
                Console.WriteLine($"Title of book {books[i].TitleOfBook} \nDescription\n{books[i].TitleOfBook}");
            }

        }
    }

If you run this example and make the description of the book very large, the object will fall into an array, there will be no description in it. How can I forbid creating such an object?
 
That's exactly the sort of thing exceptions are for. Your property should document the fact that the maximum length of a valid value is 20 characters and then, in the setter, you should validate the value provided and throw an ArgumentException if it's not valid. It's then up to the calling code to know what's valid and then either validate data before setting the property or else handle the exception that will be thrown. If the calling code doesn't catch the exception and uses invalid data, the app will crash.

If that value is required for a valid object then you should be making it an argument to the constructor. Otherwise, the calling code might just not set it at all. If the constructor requires a value then no instance can be created without providing one. You'd still throw the same exception for an invalid value though.
 
That's exactly the sort of thing exceptions are for.
By calling an exception, then I will have to enclose this code in a try-catch block. I would like to avoid using exception capture. I thought it was possible to solve this problem somehow through the property.
 
By calling an exception, then I will have to enclose this code in a try-catch block. I would like to avoid using exception capture.
C#, unlike Java, doesn't require that you capture exceptions. Exceptions are there for a reason.
 
By calling an exception, then I will have to enclose this code in a try-catch block. I would like to avoid using exception capture. I thought it was possible to solve this problem somehow through the property.
Why do you think that checking the value of a property is better than catching an exception?
 
I wouldn't bother limiting the description length in this way; it's not the responsibility of this class to do it, it's the responsibility of the input process

Consider writing a wrapper for your console write/read process:

C#:
string Ask(string question, int maxAnswerLen){
  while(true){
    Console.Write(question);
    var ans = Console.ReadLine();
    if(ans.Length <= maxAnswerLen) return ans;
    else Console.WriteLine($"Please enter {maxAnswerLen} or fewer characters");
  }
}

Then use it:

C#:
books[i].Description = Ask("Enter description: ", 20);

Not only does it make your code better to just have Ask() calls everywhere, it handles validating the input. This will be a common theme among the apps you write; generally it's the UI that is the first point of call towards making sure garbage doesn't get into the system. Console.Xxx is your UI, and it has no business being part of a property on an object from the data layer of your app
 
Last edited:
Why do you think that checking the value of a property is better than catching an exception?
How do I imagine the properties work based on the description: as for properties, it is a way to encapsulate how data is assigned and retrieved from a finite field. I have a situation where I would like to hide how a value is assigned to a field. That is, the description is no more than 20 characters. Then I need to create a separate method for checking, or do such a check inside the current method, when I could assign this responsibility to the property. And why would I call an exception for this in that case? How I imagine exceptions work - they need to be used for those methods that really can get the wrong data. In my case, the behavior is described very clearly. With the exception that I thought it was possible to prohibit the creation of an object if one of the conditions is not met.
 
In short, why should I bother with the description of the property setter, if I can stupidly conclude everything without it and process it through exceptions or in a special separate method
 
If you want to prevent the creation of the invalid object. Use a factory method and hide the public constructor. Furthermore, make the properties read-only. Let the factory method throw an exception or return null if the object cannot be created.
 
If you want to prevent the creation of the invalid object. Use a factory method and hide the public constructor. Furthermore, make the properties read-only. Let the factory method throw an exception or return null if the object cannot be created.
most likely, this is done in the current form. I thought I didn't know of some more elegant way to assign this responsibility to properties.
 
How do I imagine the properties work based on the description: as for properties, it is a way to encapsulate how data is assigned and retrieved from a finite field. I have a situation where I would like to hide how a value is assigned to a field. That is, the description is no more than 20 characters.
Yes, you could throw an exception from a property if a string of length greater than X is passed..

..and then you would need to have a try catch around the part of the code that sets that property, and you'd feed a message back to the user, and they could try again

This would, however, be fairly abortive and tedious. Let us suppose that the user must enter 3 bits of info: Firstname, LastName, address. Are are limit 20

The user enters them all longer than 20, you try to construct your object, the attempt to set the Firstname throws an error. Once you've thrown your exception your can't go back to where you left off constructing and supply again the other data; the simplest thing to do is have the user type it all again, but that's bad UX. having 3 goes at getting the object constructed is wearisome

So how about instead we store the user input in three temp variables, and try to construct an object and when setting the first name fails, ask them again for another first name, and try again, and when setting the last name it fails and you have a loop, and..
..we're constantly having this process of trying to construct an object

It's not to say you can't do it, it's just that it's easier to make sure the data is valid closer to the UI; by the time you're at "ready to construct" stage, it's easier to have the correct data
 
most likely, this is done in the current form. I thought I didn't know of some more elegant way to assign this responsibility to properties.
Usually we add an attribute to a property, rather than have it throw an exception, and then the UI uses reflection(ultimately, but it's probably abstracted away in a validation library) to inspect the object, retrieve the properties and do something like setting the max length of the text box based on what it discovered about the property

It still goes back to getting the "validate the data is correct" up into the part of the program that is very near the user rather than making it a "start constructing the object and abort it" process which is inherently lower level
 
I thought I didn't know of some more elegant way to assign this responsibility to properties.
I think that there are "aspect oriented programming" C# frameworks. You can put attributes on the properties to indicate validation rules like the WCF data contracts.

My understanding is that the more simplistic frameworks will insert extra code into the setter to enforce the validation. But alas, my understanding is that that inserted code will throw an exception if invalid data is passed in. So you are back to square one with your resistance to having to deal with exceptions.

More sophisticated frameworks will also inject that validation code to throw exceptions as a safety net. They also perform more sophisticated code analysis to inspect all code paths that would call those setters. If any of the code has the potential of passing in invalid data, an error is declared and you get something that looks like security static code analysis that reports the problem and explains how some rule is being broken. The frameworks won't add in the code to magically prevent the violation, so you will have to add in that code yourself. So you are back again to @cjard 's suggestions above about adding code at the UI level to prevent the invalid input.
 
Back
Top Bottom