如何防止c#中对象的实例化

tha*_*s.a 5 c#

我需要的是检查传递给构造函数的参数,并防止特定对象被实例化,以防它们被视为无效.

我发现可以抛出异常,因此对象引用将按预期结束"null".

例如,仅当传递给构造函数的整数为非负数时,才会实例化此类.

class MyClass
{
    public MyClass(int a)
    {
        if (a < 0)
        {
            throw new Exception();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然上面的工作正常,但我敢打赌,c#可以提供一种更简洁的方法来做到这一点,避免每次新对象即将构建时需要额外的try/catch需求.

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

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

    try
    {
        e2 = new MyClass(-1);
    } 
    catch(Exception) { }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*art 11

在这种情况下,您应该考虑使用工厂模式.您创建了构造函数private,而是使用静态方法返回实例.

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.
    }
}
Run Code Online (Sandbox Code Playgroud)

有了这个,你可以做一些非常有趣的事情.

在这里,我们有一个Foo类,具有不同的子类.通过使用工厂模式,我们可以构建特定Foo子类的实例,而外界甚至不知道存在任何子类!

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

    }
}
Run Code Online (Sandbox Code Playgroud)

这将"如何最好地构造您真正需要的对象"的知识转移到类本身的定义中,当然也消除了try/catch.您可以在静态工厂方法中应用所需的任何逻辑.

  • 你错过了`静态' (3认同)
  • 这并没有解决"每次要构建一个新对象时,避免所需的try/catch额外成本"的问题.异常仍然被抛出. (2认同)