2009-11-24 12 views
8

साथ सामान्य विधि तो, मुझे यकीन है कि यह कहीं वहाँ से पहले उत्तर दिया गया है, लेकिन मैं इसे कहीं भी नहीं मिल सका। उम्मीद कुछ जेनरिक गुरु कर सकते हैं।कार्रवाई <T> पैरामीटर

public interface IAnimal{} 
public class Orangutan:IAnimal{} 

public void ValidateUsing<T>(Action<T> action) where T : IAnimal 
{ 
    Orangutan orangutan = new Orangutan(); 
    action(orangutan); //Compile error 1 

    //This doesn't work either: 
    IAnimal animal = new Orangutan(); 
    action(animal); //Compile error 2 
} 
  1. तर्क प्रकार 'आरंगुटान' नहीं आबंटित पैरामीटर के लिए प्रकार 'टी'
  2. तर्क प्रकार 'IAnimal' है नहीं आबंटित प्रकार पैरामीटर के लिए 'टी'

संपादित है: आधार यूरी और के अन्य सुझावों पर, मैं कर सकता कुछ कास्टिंग जैसे:

public void ValidateUsing<T>(Action<T> action) where T : IAnimal 
{ 
    Orangutan orangutan = new Orangutan(); 
    action((T)(IAnimal)orangutan); 

    //This doesn't work either: 
    IAnimal animal = new Orangutan(); 
    action((T)animal); 
} 

बात मैं करना चाहता था इस तरह ValidateUsing विधि कॉल किया गया था:

ValidateUsing(Foo); 

दुर्भाग्य से, foo इस तरह दिखता है:

private void Foo(Orangutan obj) 
{ 
    //Do something 
} 

मैं स्पष्ट रूप से प्रकार निर्दिष्ट करने के लिए है जब मैं ValidateUsing कॉल

ValidateUsing<Orangutan>(Foo); 

उत्तर

6

क्यों आप एक Orangutan instantiating कर रहे हैं अगर आप किसी भी IAnimal को स्वीकार किए जाने की अपेक्षा की जाती है:

Orangutan orangutan = new Orangutan(); 
Action<IAnimal> castedAction = action as Action<IAnimal>; 
castedAction(orangutan); 
+0

धन्यवाद bdukes, मैंने सिर्फ उदाहरण के रूप में ओरंगुटन का उपयोग किया। शायद एक बुरा है। मैं किसी भी IAnimal के साथ कार्रवाई को कॉल करने में सक्षम होना चाहता हूँ। "असली" कोड में, IAnimal कक्षा में एक निजी क्षेत्र के रूप में संग्रहीत किया जाता है। तो, मैं वास्तव में कुछ भी तत्काल नहीं कर रहा हूँ। –

2

इस प्रयास करें।

Orangutan orangutan = new Orangutan(); 
action((T)(IAnimal)orangutan); 


IAnimal animal = new Orangutan(); 
action((T)animal); 
+0

धन्यवाद स्टेन! अगर मेरे पास पर्याप्त प्रतिष्ठा थी तो मैं आपके जवाब को उखाड़ फेंक दूंगा। –

2

निम्न परिवर्तन करें?

public void ValidateUsing<T>(Action<T> action) where T : IAnimal, new() 
{ 
    T animal = new T(); 
    action(animal); //Compile error 2 

आप अपने सामान्य पैरामीटर का पुन: उपयोग, तो आप किसी भी प्रकार के मुद्दों के लिए नहीं होगा ...

अब, जिनकी वजह से आपके कोड काम नहीं करता है के संबंध में, जो कुछ तुम कह रहे हो कि है प्रकार TIAnimal से निकाले जाते हैं जाएगा। हालांकि, यह बस के रूप में आसानी से एक Orangutan के रूप में एक Giraffe हो सकता है, तो आप सिर्फ प्रकार T की एक पैरामीटर के लिए एक Orangutan या IAnimal नहीं सौंप सकते।

+0

हाय यूरी, यह बहुत अच्छी तरह से काम करता है। यह मुझे रास्ते का हिस्सा बनता है (संपादन देखें)। धन्यवाद! –

0
public interface IAnimal { } 
public class Orangutan : IAnimal { } 

public void ValidateUsing<T>(Action<T> action) where T : IAnimal 
{ 
    Orangutan orangutan = new Orangutan(); 
    action((T)(orangutan as IAnimal)); // needs to be cast as IAnimal 

    //This doesn't work either: 
    IAnimal animal = new Orangutan(); 
    action((T)animal); // needs to be cast as T 
} 

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

public abstract class Animal { } 
public class Orangutan : Animal { } 

public void ValidateUsing<T>(Action<T> action) where T : Animal 
{ 
    Orangutan orangutan = new Orangutan(); 
    action(orangutan as T); 

    //This doesn't work either: 
    Animal animal = new Orangutan(); 
    action(animal as T); 
} 
+0

हाय क्लाइंबेज, विस्तृत उत्तर के लिए धन्यवाद। मैं अमूर्त वर्गों (पक्ष बनाम विरासत विरासत और यह सब) की तुलना में अक्सर इंटरफ़ेस का उपयोग करता हूं, लेकिन यह जानना दिलचस्प है कि यह एक अमूर्त वर्ग के साथ काम करता है। –

4

बात है, कि टी कुछ प्रकार है जो जिस तरह से IAnimal लागू करता है प्रतिनिधित्व करता है।

इसलिए, जब आप action(new Organatum()) क्योंकि आप घोषणा की है कि कार्रवाई प्रकार T की एक पैरामीटर जो अपनी बारी में प्रकार का हो सकता है ले जाना चाहिए यदि आपको त्रुटि प्राप्त संकलित करने के लिए प्रयास करते हैं, मान लीजिए कि, Fish करते हैं - आप Organatum डाली नहीं कर सकता एक Fish करने के लिए, आप कर सकते हैं?

यदि आप किसी भी क्रिया को ट्रिगर करना चाहते हैं जो IAnimal इंटरफ़ेस लागू करता है, तो बस जेनरिक के बारे में भूल जाएं और Action<IAnimal> का उपयोग करें।

एचटीएच।

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