0

I have a basic c# app to process some sql files. I have a class for each type of object like proc, function, view, etc.

What I want to do in the main is determine what kind of script file im processing and them create an instance of that class.

Then using that object, call it objSqlType, I want to call a method in the underlying class. each class will have the same method names implemented like getHeader(), getPermissions(), etc

Is this possible. I looked at interfaces which forces me to create methods but can't seem to use a single object,

for example:

object objSqlType;

switch (type)
{
    case ObjectType.PROC:
        objSqlType = new SqlProc();
        break;
    case ObjectType.FUNCTION:
        objSqlType = new SqlFunction();
        break;
    case ObjectType.VIEW:
        objSqlType = new SqlView();
        break;
    default:
        break;
}

string header = objSqlType.getHeader();  // call getHeader for whichever object I created
Hamid Pourjam
  • 20,441
  • 9
  • 58
  • 74
user3781891
  • 135
  • 10
  • 1
    Possible duplicate of [How to use reflection to call method by name](http://stackoverflow.com/questions/3110280/how-to-use-reflection-to-call-method-by-name), that should do it if you know method name and all types have it (you can check if method exists otherwise). From design point of view you should use interfaces however (or even base class if objects are similar). – Sinatr May 12 '16 at 13:30
  • 3
    instead of `object objSqlType;` use `yourInterface objSqlType;`. Maybe consider using base class instead of interface – Ondra May 12 '16 at 13:37
  • I would create a generic object MainObject where T can be any of the classes you desire func, proc, view. Those classes would all implement the same interface IMyInterface. `class MainObject where T: IMyInterface {public T myObject {get;set;} ...}`. – CFreitas May 12 '16 at 13:38

4 Answers4

4
  1. Create an interface
  2. Create classes that implement that interface
  3. Declare your object as that interface
  4. Instantiate your object as one of the classes that implement the interface

Like this:

public interface ISqlType
{
    string getHeader();
}

public class SqlProc : ISqlType
{
    public string getHeader()
    {
        return "I'm a SqlProc!"
    }
}

public class SqlFunction : ISqlType
{
    public string getHeader()
    {
        return "I'm a SqlFunction!"
    }
}

public class SqlView : ISqlType
{
    public string getHeader()
    {
        return "I'm a SqlView!"
    }
}

ISqlType objSqlType;

switch (type)
{
    case ObjectType.PROC:
        objSqlType = new SqlProc();
        break;
    case ObjectType.FUNCTION:
        objSqlType = new SqlFunction();
        break;
    case ObjectType.VIEW:
        objSqlType = new SqlView();
        break;
    default:
        break;
}

string header = objSqlType.getHeader();
Kristof Claes
  • 10,797
  • 3
  • 30
  • 42
0

use dynamic

dynamic objSqlType;

// rest of code

string header = objSqlType.getHeader();

Also it seems that you are using an uninitialized variable here because if you fall in default case then objSqlType is uninitialized and you can not use an uninitialized local variable.

Hamid Pourjam
  • 20,441
  • 9
  • 58
  • 74
  • And I quote: _Therefore, no compiler error is reported. However, the error does not escape notice indefinitely. It is caught at run time and causes a run-time exception._ From: https://msdn.microsoft.com/en-us/library/dd264736.aspx Why would you want that in your code? – Max Sorin May 12 '16 at 13:39
0

Create an interface and make every object implement it. Or alternatively, create an abstract class and make every object inherit from it.

Oscar
  • 13,594
  • 8
  • 47
  • 75
0

May be below code help you. I am not sure whether you want to remove create new object from client and make it centralised.

You can think of making your requirement in decoupled way Like..

interface IDBObject
{
     string GetDBType()
}

then have your required classes and implement respect interface

public class SQLStoreProc:IDBObject
{
     public string GetDBType()
     {}
}

public class SQLFunction:IDBObject
{
public string GetDBType()
     {}
}

public class SQLMisc:IDBObject
{
public string GetDBType()
     {}
}

Now create your wrapper or factory class which will be

class clsFactory
{
     public static IDBObject CreateObject(string type)
     {
      IDBObject ObjSelector = null;

        switch (type)
        {
            case "SP":
                ObjSelector = new SQLStoreProc();
                break;
            case "FUNC":
                ObjSelector = new SQLFucntion();
                break;
            default:
                ObjSelector = new SQLMisc();
                break;
        }
        return ObjSelector;
     }
}

Now in main method you can have something like below

public static void main (args a)
{
    IDBObject ObjIntrface = null;
    ObjIntrface = clsFactory.CreateObject(your object type);
    string res = ObjIntrface.GetDBType("First", "Second");

}
LifeOfPi
  • 625
  • 5
  • 19