Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent an instantiation of an object in c#

Tags:

c#

What I need is to check the parameters passed to the constructor and prevent the instantiation of the specific object in case they are treated as invalid.

What I have found is that an exception can be thrown so the object reference will end up with "null" as expected.

For example, this class will be instantiated only if the integer passed to the constructor is non negative.

class MyClass
{
    public MyClass(int a)
    {
        if (a < 0)
        {
            throw new Exception();
        }
    }
}

Although the above works fine, I bet that c# can provide a cleaner way to do this, avoiding the extra cost of the try/catch need, each time a new object is about to be constructed.

static void Main(string[] args)
{
    MyClass e1;
    MyClass e2;

    try
    {
        e1 = new MyClass(1);
    } 
    catch(Exception)   { }

    try
    {
        e2 = new MyClass(-1);
    } 
    catch(Exception) { }
}
like image 612
thanos.a Avatar asked Jan 23 '14 00:01

thanos.a


People also ask

What are the ways to prevent instantiation of class?

Private constructors are used to prevent creating instances of a class when there are no instance fields or methods, such as the Math class, or when a method is called to obtain an instance of a class. If all the methods in the class are static, consider making the complete class static.

Which of the following techniques can be used to prevent the instantiation?

If you don't want to instantiate a class, use "abstract" modifier.

Do abstract function prevent instantiation?

An abstract class cannot be instantiated.


3 Answers

In cases like this, you should consider using the Factory Pattern. You made the constructor private, and instead use a static method to return an instance.

public class Foo {
    private Foo(int a) { ... }

    public static Foo GetFoo(int a) {
        if (a < 0) {
            throw new Exception("No Foo for you!");

            // or

            return null;
        }

        return new Foo(a);
    }
}

public class Program {
    public static void Main() {
        Foo f;

        f = new Foo();        // Not allowed, ctor is private.

        f = Foo.GetFoo(42);   // Do this instead.
    }
}

With this, you can do some pretty interesting stuff.

Here, we have a Foo class, with different sub-classes. By using the Factory Pattern, we can construct an instance of a particular Foo sub-class, without the outside world even knowing that any subclasses exist!

public abstract class Foo { 

    // Private implementations of Foo
    // No one outside can ever construct one directly.
    private class RedFoo : Foo { }
    private class GreenFoo : Foo { }
    private class BlueFoo : Foo { }

    public static Foo GetColoredFoo(string color) {

        switch (color.ToLower()) {
        case "red":    return new RedFoo();
        case "green":  return new GreenFoo();
        case "blue":   return new BlueFoo();
        }

        throw new Exception("No Foo for that color!");
    }
}

public class Program {
    public static void Main() {
        Foo f;

        f = new Foo();     // Not allowed; Foo is abstract

        f = new RedFoo();  // Not allowed, RedFoo is private, inside of Foo

        f = Foo.GetColoredFoo("red");  // Returns an instance of RedFoo

    }
}

This moves the knowledge of "how to best construct the object you really need" into the definition of the class itself, and of course eliminates the try/catch. You could apply any logic you need inside of the static factory method.

like image 74
Jonathon Reinhart Avatar answered Sep 27 '22 18:09

Jonathon Reinhart


You can go with the factory pattern, as suggested by MarcinJruaszek, by making the constructor private and add a static method:

public class myClass
{
    private myClass(int a)
    {
        // constructor
    }

   public static myClass Create(int a){
       if (a < 0)
        {
            return null;
        }
        return new myClass(a);
   }
}

And do myClass.Create(1).

like image 24
TheDude Avatar answered Sep 27 '22 18:09

TheDude


What I suggest you do is create a static method of your class that accepts the parameters you need to verify and have that return the object. I do not know of a way to abandon object creation during a constructor without throwing an Exception.

like image 31
Nabren Avatar answered Sep 27 '22 18:09

Nabren