Create C # Instance

That's all, I have a method that returns a list. This method is used to return SQL StoredProcedures parameters, views and functions based on the name. I want to create a list of objects and return this list to the caller. Method below

private List<T> GetInputParameters<T>(string spFunViewName) { string strSql = String.Format( "SELECT PARAMETER_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.PARAMETERS " + "WHERE SPECIFIC_NAME = '{0}' AND PARAMETER_MODE = 'IN';", spFunViewName); List<string[]> paramInfoList = new List<string[]>(); DataTable paramDt = Utilities.DTFromDB(conn, "InputParmaters", strSql); if (paramDt != null) { Converter<DataRow, string[]> rowConverter = new Converter<DataRow, string[]>(Utilities.RowColConvert); paramInfoList = Utilities.ConvertRowsToList<string[]>(paramDt, rowConverter); } else return null; // Build the input parameter list. List<T> paramList = new List<T>(); foreach (string[] paramInfo in paramInfoList) { T t = new T(paramInfo[NAME], paramInfo[TYPE], Convert.ToInt32(paramInfo[CHARMAXLEN])); columnList.Add(column); } return columnList; } 

I obviously cannot create an instance of T via new and go to the constructor, but it should be clear what I'm trying to do. Is there a way to do what I want using three additional methods?

Note. The main problem is that the number of parameters that I pass to T can be either two OR three.

Thank you for your time.

Edit: struct I use the following

 public struct Database { public string name { get; set; } public string filename { get; set; } public List<Table> tables { get; set; } public List<StoredProcedure> sps { get; set; } public List<Function> funcs { get; set; } public List<View> views { get; set; } public Database(string name, string filename) { this.name = name; this.filename = filename; } } protected internal struct StoredProcedure { public string name { get; set; } public List<string[]> parameters { get; set; } public StoredProcedure(string name, List<string[]> parameters) { this.name = name; this.parameters = parameters; } } protected internal struct Function { public string name { get; set; } public string output { get; set; } public List<string[]> parameters { get; set; } public Function(string name, string output, List<string[]> parameters) { this.name = name; this.output = output; this.parameters = parameters; } } protected internal struct View { public string name {get; set;} public List<string[]> parameters { get; set; } public View(string name, List<string[]> parameters) { this.name = name; this.parameters = parameters; } } 
+7
source share
7 answers

Use the Activator class to create T and pass parameters.

 Type type = typeof(T); var result = (T)Activator.CreateInstance(type, new object[] { yourParameters }); 

Used in code snippet:

 T t = Activator.CreateInstance(type, colInfo[NAME], colInfo[TYPE], Convert.ToInt32(colInfo[CHARMAXLEN])); 
+6
source

I do not approve or belittle this technique, but you can use:

 (T) Activator.CreateInstance( typeof(T), colInfo[TYPE], Convert.ToInt32(colInfo[CHARMAXLEN]) ); 

I think I would like to have separate factory methods.

+3
source

You can use Activator.CreateInstance() as others mentioned or pass delegate Func<string, string, int, T> , avoiding unnecessary reflection costs.

  List<T> GetInputParameters<T>(string spFunViewName, Func<string, string, int, T> itemCreator) { .... List<T> paramList = new List<T>(); foreach (string[] paramInfo in paramInfoList) { T t = itemCreator(paramInfo[NAME], paramInfo[TYPE], Convert.ToInt32(paramInfo[CHARMAXLEN])); paramList.Add(t); } return columnList; } 
+3
source

I explicitly cannot initialize T via new and go to constructor

As written, no; however, you can, if you are limiting your type parameter, to accept only types with constructors:

 private List<T> GetInputParameters<T>(string spFunViewName) where T : new() { // your code here } 

In the above example, you can say:

 T myItem = new T(); 

In your particular case, it looks like you expect each of the generic types to share something in common. Consider also a type constraint with an interface:

 private List<T> GetInputParameters<T>(string spFunViewName) where T : new(), ISomeInterface { // your code here } 

This will allow you to apply values ​​to any interface properties after creating an instance of the object:

 T myItem = new T(); myItem.SomeProperty = somevalue; myItem.AnotherProperty = anothervalue; 

For more information, see Type Dependencies (C # Programming Guide) on MSDN for more information on type type restrictions.

+2
source

You can just use List < DbParameter >

This is a little more obvious.

+1
source

You can try the following:

 var constructor = typeof(T).GetConstructor(typeof(string), typeof(string), typeof(int)); constructor.Invoke(colInfo[NAME], colInfo[TYPE], Convert.ToInt32(colInfo[CHARMAXLEN])); 
+1
source

You can create general database parameters (both connections and commands, etc.) using ADO.NET DbProviderFactories .

The System.Data.Common namespace provides classes for creating a DbProviderFactory for working with specific data sources. when you create an instance of DbProviderFactory and pass information about the data provider to it, DbProviderFactory can determine the correct, strongly typed connection object to return based on the information that it was provided.

In your code, you can create a DbProviderFactory and then call CreateParameter() .

 string providerName = ConfigurationManager.ConnectionStrings["YourConnectionString"].ProviderName; DbProviderFactory factory = DbProviderFactories.GetFactory(providerName); DbParameter parameter = factory.CreateParameter(); 
+1
source

All Articles