2012-06-21 12 views
7

सब, मेरे पास एक तरीका है जो एक सूची देता है। इस विधि का उपयोग नाम के आधार पर SQL संग्रहीत प्रसंस्करण, दृश्य और कार्य के पैरामीटर को वापस करने के लिए किया जाता है। मैं क्या करना चाहता हूं वस्तुओं की एक सूची बनाएं और इस सूची को कॉलर पर वापस कर दें। विधिसी # जेनिक्स इंस्टेंटेशन

नीचे
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; 
} 

मैं स्पष्ट रूप सेnew के माध्यम से T का दृष्टांत नहीं कर सकते और निर्माता के पास, लेकिन यह स्पष्ट मैं क्या करने की कोशिश कर रहा हूँ क्या होना चाहिए। क्या मैं तीन अतिरिक्त तरीकों से जो करना चाहता हूं उसे करने का कोई तरीका है?

नोट। मुख्य मुद्दा यह है कि टी को पारित करने वाले पैरामीटर की संख्या या तो दो या तीन हो सकती है।

आपके समय के लिए धन्यवाद।

संपादित करें: struct रों मैं उपयोग के रूप में T बना सकते हैं और मानकों को पारित करने के लिए

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; 
    } 
} 
+0

'टी 'का प्रकार यहां होने की संभावना क्या है? –

+0

@ जोन स्कीट, यह वास्तव में एक 'संरचना' है। मैं डाटाबेस, टेबल इत्यादि दिखाने के लिए एक पुन: प्रयोज्य पेड़ संरचना बनाने का प्रयास कर रहा हूं लेकिन मैं इस प्रक्रिया से प्राप्त जानकारी का उपयोग फिर से करने में सक्षम होना चाहता हूं - इसलिए मैं 'स्ट्रक्चर स्टोर्डप्रोसेसर', 'स्ट्रक्चर फंक्शन' आदि के साथ सिंगलटन पैटर्न का उपयोग करता हूं। । धन्यवाद। – MoonKnight

+0

मुझे लगता है कि "इनपुटपर्मर्स" 'एक टाइपो है? – comecme

उत्तर

6

उपयोग Activator वर्ग इस प्रकार हैं।

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

अपने कोड स्निपेट में उपयोग किया:

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

कमाल, इस बारे में बिल्कुल नहीं पता था, आपके समय के लिए बहुत बहुत धन्यवाद ... – MoonKnight

+0

@ किल्करम कोई समस्या नहीं है। हालांकि, जैसा कि अन्य ने लिखा है, इससे बचने के लिए सबसे अच्छा है और एक अलग डिज़ाइन किए गए एपप्रूच का उपयोग करें। – Aphelion

+0

इस स्तर पर मुझे यकीन नहीं है क्यों? क्या तुम मुझे हास्य कर सकते हो? मेरे पास तीन प्रकार, एसपी, कार्य और विचार हैं। इनमें से टॉव केवल इनपुट पैरामीटर (एसपी और विचार) है, कार्यों में दोनों हैं ... – MoonKnight

3

मैं न तो पुष्टि और न ही इस तकनीक को विकर्षित हूँ, लेकिन आप का उपयोग कर सकते हैं:

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

मुझे लगता है कि मैं नहीं बल्कि अलग होगा कारखाने के तरीके।

1

तुम सिर्फ सूची < DbParameter>

में थोड़ा और अधिक स्पष्ट है कि इस्तेमाल कर सकते हैं।

1

आप इस कोशिश कर सकते:

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

आप अन्य उल्लेख किया है Activator.CreateInstance() का उपयोग करें या एक प्रतिनिधि Func<string, string, int, T> प्रतिबिंब भूमि के ऊपर से परहेज पारित कर सकते हैं।

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;  
} 
1

आप ADO.NET DbProviderFactories साथ सामान्य डेटाबेस मानकों (और कनेक्शन और आदेश, आदि) बना सकते हैं।

System.Data.Common नाम स्थान विशिष्ट डेटा स्रोतों के साथ काम करने के लिए DbProviderFactory उदाहरणों बनाने के लिए कक्षाएं प्रदान करता है। जब आप एक DbProviderFactory उदाहरण बनाते हैं और डेटा प्रदाता के बारे में जानकारी पास करते हैं, तो DbProviderFactory सही दृढ़ता से टाइप की गई कनेक्शन ऑब्जेक्ट को जानकारी के आधार पर लौटने के लिए निर्धारित कर सकता है।

अपने कोड में, आप DbProviderFactory बना सकते हैं और फिर CreateParameter() पर कॉल कर सकते हैं।

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

मैं स्पष्ट रूप से नई के माध्यम से टी instansiate और निर्माता

लिखा, कोई रूप को पारित नहीं कर सकते हैं; हालांकि, आप यदि आप करने के लिए अपने प्रकार पैरामीटर विवश केवल प्रकार कंस्ट्रक्टर्स के साथ स्वीकार कर सकते हैं:

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

उदाहरण में ऊपर आप कहते हैं कि करने में सक्षम होगा:

T myItem = new T(); 

अपने विशिष्ट मामले में, यह ऐसा लगता है कि आप प्रत्येक जेनेरिक प्रकारों को सामान्य में साझा करने की अपेक्षा करते हैं। यह भी एक इंटरफेस के साथ प्रकार बाधित पर विचार करें:

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

है कि आप के लिए, आप का दृष्टांत के बाद आप आपत्ति, मूल्यों किसी भी गुणों के इंटरफेस पर लागू की अनुमति होगी:

T myItem = new T(); 

myItem.SomeProperty = somevalue; 
myItem.AnotherProperty = anothervalue; 

अधिक जानकारी के लिए, बाहर की जाँच सामान्य प्रकार की बाधाओं पर अधिक जानकारी के लिए एमएसडीएन पर Constraints on Type Parameters (C# Programming Guide)

+0

मुझे यह बहुत पसंद है! लेकिन यह तथ्य नहीं है कि मेरे तीन structs के अंदर वस्तुओं का मतलब अलग है कि मैं एक इंटरफ़ेस का उपयोग नहीं कर सकता क्योंकि यह सब कुछ या कुछ भी नहीं है? – MoonKnight

+0

आदर्श रूप से, इस मामले में, प्रत्येक structs (या कक्षाएं) एक ही इंटरफ़ेस या बेस क्लास को लागू करने (या उत्तराधिकारी) को सक्षम करने में सक्षम होंगे, अगर कुछ और नहीं, तो कारखाने विधि के साथ कुछ। क्या आप वास्तविक structs को शामिल करने के लिए अपने प्रश्न को अपडेट करने में सक्षम होंगे? –

+0

यह किया गया है ... – MoonKnight

संबंधित मुद्दे