C # नया T बनाएँ ()


159

आप देख सकते हैं कि मैं क्या कर रहा हूँ (लेकिन असफल) निम्नलिखित कोड के साथ करने के लिए:

protected T GetObject()
{
    return new T();
}

किसी भी तरह की सहायता का स्वागत किया जाएगा।

संपादित करें:

प्रसंग इस प्रकार था। मैं सभी नियंत्रकों के लिए एक कस्टम कंट्रोलर क्लास के साथ मानकीकृत विधियों के साथ खेल रहा था। इसलिए संदर्भ में, मुझे नियंत्रक प्रकार की वस्तु का एक नया उदाहरण बनाने की आवश्यकता थी। इसलिए लेखन के समय, यह कुछ इस तरह था:

public class GenericController<T> : Controller
{
    ...

    protected T GetObject()
    {
        return (T)Activator.CreateInstance(ObjectType);
    }        

    public ActionResult Create()
    {
        var obj = GetObject()

        return View(obj);
    }

और इसलिए मैंने तय किया कि प्रतिबिंब यहाँ सबसे आसान था। मैं मानता हूं कि निश्चित रूप से प्रश्न का प्रारंभिक विवरण दिया गया है, सही के रूप में चिह्नित करने के लिए सबसे उपयुक्त उत्तर नए () बाधा का उपयोग कर रहा था। मैंने तय कर लिया है कि


27
नहीं, मैं यह नहीं देखता कि आप क्या करने की कोशिश कर रहे हैं और असफल हो रहे हैं। मुझे एक ऐसा कोड दिखाई देता है, जो बिना किसी संदर्भ, कोई त्रुटि संदेश और कोई स्पष्टीकरण के साथ एक कार्यशील कार्यक्रम का हिस्सा हो सकता है।
बेन वोइगट

17
अजी, गलत उत्तर चुने जाने पर मुझे इससे नफरत है!
डेविड हेफर्नन

जवाबों:


409

नए अवरोध पर एक नज़र

public class MyClass<T> where T : new()
{
    protected T GetObject()
    {
        return new T();
    }
}

Tएक ऐसा वर्ग हो सकता है जिसमें एक डिफ़ॉल्ट निर्माता नहीं है: इस मामले में new T()एक अमान्य बयान होगा। new()बाधा का कहना है कि Tएक डिफ़ॉल्ट निर्माता, बनाता है जो होना आवश्यक हैnew T() कानूनी।

आप एक सामान्य विधि के लिए एक ही बाधा लागू कर सकते हैं:

public static T GetObject<T>() where T : new()
{
    return new T();
}

यदि आपको पैरामीटर पारित करने की आवश्यकता है:

protected T GetObject(params object[] args)
{
    return (T)Activator.CreateInstance(typeof(T), args);
}

2
धन्यवाद, दोस्त - मुझे आज यह जानकर खुशी हुई। मेरी पद्धति के संदर्भ को देखते हुए, मैं प्रतिबिंब समाधान के लिए चला गया हूं। चीयर्स!
हंसन

8
@nulliusinverba - हम्म ... अच्छा होगा यदि आप प्रश्न में अपनी पद्धति का संदर्भ दिखाए।
एलेक्स आजा

1
@nulliusinverba - आपको उस प्रश्न में नहीं दिखा, जिसमें आपको मापदंडों की आवश्यकता थी।
एलेक्स आजा

1
@ एलेक्स - जब मैंने उनका प्रश्न पढ़ा तो मैंने मान लिया कि वे पैरामीटर नहीं चाहते हैं: एस अप-वोट फॉर
फिल

क्या नए (पैरामीटर) बाधा जैसे कुछ का उपयोग करना संभव है?
लुई राइस


29

दूसरा तरीका प्रतिबिंब का उपयोग करना है:

protected T GetObject<T>(Type[] signature, object[] args)
{
    return (T)typeof(T).GetConstructor(signature).Invoke(args);
}

धन्यवाद, दोस्त - मैं विधि के संदर्भ को देखते हुए इस समाधान के साथ गया था।
हंसन

22
FYI के रूप में, इसे वैकल्पिक रूप से Activator.CreateInstance (टाइपोफ़ (T), सिग्नेचर, आर्ग्स) के रूप में लिखा जा सकता है; अधिक विवरण के लिए msdn.microsoft.com/en-us/library/4b0ww1we.aspx देखें ।
क्रिस बैक्सटर

@ कालगर्ल कोडर: एक प्रकार [] हस्ताक्षर के लिए क्या उपयोग है, आप स्पष्ट रूप से हस्ताक्षर निर्दिष्ट किए बिना, सीधे Params के साथ CreateInstance को कॉल कर सकते हैं। दोनों मामलों में आपको मिसिंगमेथोडएक्ससेप्शन मिलेगा यदि एक मेलिंग कंस्ट्रक्टर मौजूद नहीं है।
बोरिस बी।

4
यहां तक ​​कि अगर यह जवाब है जो आपके लिए सबसे अच्छा काम करता है, तो जाहिर है कि यह समुदाय के लिए सबसे अच्छा नहीं है। इस सवाल की तलाश में लोग नीचे से जवाब की तलाश कर रहे हैं, वास्तव में।
ट्रैप

और वास्तव में वह संदर्भ क्या है? कृपया इसे मूल प्रश्न में जोड़ें।
जेम्स

18

बस पूरा करने के लिए, यहां सबसे अच्छा समाधान अक्सर एक कारखाना फ़ंक्शन तर्क की आवश्यकता होती है:

T GetObject<T>(Func<T> factory)
{  return factory(); }

और इसे कुछ इस तरह से कहें:

string s = GetObject(() => "result");

आप जरूरत पड़ने पर उपलब्ध मापदंडों का उपयोग करने या बनाने के लिए इसका उपयोग कर सकते हैं।


16

नई बाधा ठीक है, लेकिन अगर आप टी एक मान प्रकार भी किया जा रहा है की जरूरत है, इस का उपयोग करें:

protected T GetObject() {
    if (typeof(T).IsValueType || typeof(T) == typeof(string)) {
        return default(T);
    } else {
       return (T)Activator.CreateInstance(typeof(T));
    }
}

7

चूँकि यह C # 4. टैग किया गया है, इसलिए ओपन सोक्रस फ्रेमवर्क ImpromptuIntereface के साथ, यह dlr का उपयोग करेगा कंस्ट्रक्टर को कॉल करने के लिए यह एक्टिवेटर की तुलना में काफी तेज़ है जब आपके कंस्ट्रक्टर के पास तर्क होते हैं, और लापरवाही से जब यह नहीं होता है। हालांकि मुख्य लाभ यह है कि यह सी # 4.0 वैकल्पिक मापदंडों के साथ कंस्ट्रक्टर्स को सही ढंग से संभाल लेगा, कुछ ऐसा जो एक्टिवेटर नहीं करेगा।

protected T GetObject(params object[] args)
{
    return (T)Impromptu.InvokeConstructor(typeof(T), args);
}

4

इसे पाने के लिए मैंने निम्नलिखित कोड की कोशिश की:

  protected T GetObject<T>()
    {
        T obj = default(T);
        obj =Activator.CreateInstance<T>();
        return obj ;
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.