none
class name as parameter? RRS feed

  • Question

  • I have 3 singleton classes with same set of methods.

    in my calling function, I am writing:

    decimal result = 0;

    switch (myParam)

    {

    case value1:

    result = MyClass1.Instance.GetData(); break;

    case valu2:

    result = MyClass2.Instance.GetData(); break;

    default:

    result = MyClass3.Instance.GetData(); break;

    }

    return result;

    I want to replace the above switch with a single statement and pass className as parameter to my above calling function. Will the below code work for a singleton? If not, how would I do it?

    object myObject = Activator.CreateInstance(className);

    decimal result = myObject.GetData();

    Thanks.

    Monday, January 29, 2018 11:09 AM

All replies

  • C# is not a scripting language. 

    What you want is typical for scripting. If you search on Internet you can find it asked thousand times. 

    However, a class is not an object so you will never find a real satisfying answer. 

    Keep in mind C# classes needs always to be instanced to be used (it are just templates). Either static at compile time or with the "new" keyword at runtime. 


    Success Cor


    Monday, January 29, 2018 12:17 PM
  • Why do they need to be singletons? This looks like just a simple case of passing an object to a method.

    //If it is as simple as this then you don't even need 
    //this method
    void GetData ( SomeCommonType instance )
    {
       var result = instance.GetData();
    }
    
    

    As for your activator code, it isn't going to work for singletons anyway. Activator is going to create an instance but singletons (when properly implemented) do not allow creation. Thus activator and singletons don't go together which goes back to why you're using a singleton to begin with.

    If you weren't using a singleton and MyClass1, MyClass2 and MyClass3 had a common base type or interface then activator becomes easy.

    var instance = Activator.CreateInstance(someTypeName) as SomeCommonType;
    
    var result = instance.GetData();
    
    

    An example of what SomeCommonType might look like (if it were an interface).

    public interface ISomeCommonType
    {
       decimal GetData();
    }
    
    public class Class1 : ISomeCommonType
    {
       public decimal GetData() { ... };
    }
    
    public class Class2 : ISomeCommonType
    {
       public decimal GetData() { ... };
    }
    
    public class Class3 : ISomeCommonType
    {
       public decimal GetData() { ... };
    }
    


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, January 29, 2018 4:03 PM
    Moderator
  • Hello JayShah20,

    >>Will the below code work for a singleton? If not, how would I do it?

    The singleton pattern is that set the ctor method as private and get the instance by method of adding limitation. And the Activator.CreateInstance method will create a instance based on the constructor and it doesn't meet your requirement.

    You need to use reflect to invoke the method that could create a singleton object. A simple example like below.

    For given two singleton class.

     public class MyClass1
        {
           private static MyClass1 myClass1;
           private MyClass1()
            {
                Console.WriteLine("MyClass1 was created");
            }
            public static MyClass1 CreateInstance() {        
                if (myClass1 == null) {
                    myClass1 = new MyClass1();
                }
                return myClass1;
            }
    
            public int GetData() {
                return 0;
            }
          }
      
        public class MyClass2
        {
            private static MyClass2 myClass2;
            private MyClass2()
            {        
                Console.WriteLine("MyClass2 was created");
            }
            public static MyClass2 CreateInstance()
            {
                if (myClass2 == null)
                {
                    myClass2 = new MyClass2();
                }
                return myClass2;
            }
    
            public int GetData()
            {
                return 1;
            }
        }

    Use reflect to create instance.

      class Program
        {
            public static Object Test(string typeName,string SingletonMethod) {
               
                MethodInfo methodInfo = Type.GetType(typeName)?.GetMethod(SingletonMethod);
    
                return methodInfo.Invoke(null, null);
            }
    
            static void Main(string[] args)
            {
                var obj = Test("Program.MyClass1", "CreateInstance");
                ((MyClass1)obj).GetData();
    
                var obj1 = Test("Program.MyClass2", "CreateInstance");
                ((MyClass2)obj1).GetData();
    
    
            }
       }

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, January 30, 2018 5:27 AM
    Moderator
  • If Instance represents static fields in all of your classes, for example:

       class MyClass3

       {

          public static MyClass3 Instance = new MyClass3();

     

          public decimal GetData() { return 3; }

       }

     

    then this should work:

       decimal result = GetMyData<MyClass3>();

     

    where GetMyData is:

       static decimal GetMyData<T>()

       {

           dynamic d = typeof( T ).GetField( "Instance" ).GetValue( null );

     

           return d.GetData();

       }



    • Edited by Viorel_MVP Tuesday, January 30, 2018 6:02 AM
    • Proposed as answer by Fei HuModerator Wednesday, January 31, 2018 9:33 AM
    Tuesday, January 30, 2018 6:01 AM