简体   繁体   中英

Prevent a Class from being instantiated

Hi i want to have a class that cannot be instantiated but can be added as a static field to another class but i could not achieve it;

Here is what i've done;

    public class ValueListManager
    {
        public static Operations myOps { get { return new Ops(); } }         
    }

    public interface Operations
    {
        void Call();
    }

    public class Ops : Operations
    { 

        public void Call()
        {

        }
    }

I dont' want the Ops class to be instantiated anywhere else. Basically I want to be able to;

    ValueListManager.Operations.Call();

But i dont want to be able to use the ops class like;

    var ops = new Ops();

Is there a way to achieve this?

You can achieve that by declaring the Ops class as a private class within the ValueListManager class where you want to use it:

public class ValueListManager
{
    private class Ops : Operations
    {
        public Ops()
        {
        }

        public void Call()
        {
        }
    }

    public static Operations myOps { get { return new Ops(); } }
}

Note, that in this example based on your code, a new instance of the Ops class is created every time you access the myOps property. If you don't want that, you need to store the Ops instance in a static field once it is created and use that in the Getter of the property.

As I understand you want to instantiate this class only once and later use it .

You can use Singletone pattern , you can also use inheritance with this pattern.

public class Ops: Operations
{
   private static Ops instance;

   private Ops() {}

   public static Ops Instance
   {
      get 
      {
         if (instance == null)
         {
            instance = new Ops();
         }
         return instance;
      }
   }

 public void Call()
 {
   // do something
 }
}

and where you want to use it you can call its method:

Ops.Instance.Call()

If you don't want to nest your classes for some reason, and don't want to basically change anything except the Ops class itself, you could put your code into a different assembly (add a class library to your solution), and make the constructor internal :

public class ValueListManager
{
  public static Operations myOps { get { return new Ops(); } }         
}

public class Ops : Operations
{ 
  internal Ops() {}
  public void Call()
  {
  }
}

Then you'd only need to add a reference to that assembly from the one you want to use that, you'd not need to change any other code.

The constructor (thus new Ops() ) can only be accessed from that assembly, code in other assemblies won't be able to new .

This is very similar to the design pattern singleton, but it is unclear from your code if you want only one instance or if you don't want to instantiate it from elsewhere?

If it is a single instance you're after the most recommended way to implement a singleton in c# is using the static constructor:

public class Single
{
    private static Single instance;
    private Single() { }

    static Single()
    {
        instance = new Single();
    }

    public static Single Instance
    {
        get { return instance; }
    }
}

Most other ways have (at least a theoretical) risk of threading issues.

However it should be noted that the singleton pattern (and typically extensive use of static methods) is in some contexts an indication of a bad design.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM