2008-09-22 4 views
18

जावा में, कोई एक "अज्ञात" जेनेरिक प्रकार द्वारा पैरामीटर किए गए चर को घोषित कर सकता है, जो इस तरह दिखता है:क्या सी # में एक "अज्ञात" जेनेरिक टैग है, जैसे '?' जावा में?

Foo<?> x; 

क्या इस प्रश्न-चिह्न के बराबर निर्माण है, सी # में?

+0

आखिरकार टेम्पलेट प्रकार का समाधान क्या है? –

उत्तर

26

कम जवाब नहीं है। सी # में समकक्ष सुविधा नहीं है।

का संभावित हल, C# from a Java developer's perspective से हिम्मत Obasanjo द्वारा:

कुछ मामलों में, एक (एक विधि है कि डेटा किसी भी प्रकार के रूप में उन है कि एक विशिष्ट प्रकार के होते हैं करने के लिए विरोध युक्त ढांचे पर काम कर सकते हैं बनाने की आवश्यकता हो सकती जैसे के लिए एक विधि जेनरिक्स में मजबूत टाइपिंग के लाभों का लाभ उठाते हुए भी डेटा ऑब्जेक्ट में सभी ऑब्जेक्ट्स प्रिंट करें)। सी # में इसे निर्दिष्ट करने के लिए तंत्र जेनेरिक टाइप इनफ्रेंसिंग नामक एक फीचर के माध्यम से होता है जबकि जावा में यह वाइल्डकार्ड प्रकारों का उपयोग करके किया जाता है। निम्नलिखित कोड नमूने दिखाते हैं कि दोनों दृष्टिकोण एक ही परिणाम के लिए कैसे नेतृत्व करते हैं।

सी # कोड

using System; 
using System.Collections; 
using System.Collections.Generic; 

class Test{ 

    //Prints the contents of any generic Stack by 
    //using generic type inference 
    public static void PrintStackContents<T>(Stack<T> s){ 
     while(s.Count != 0){ 
      Console.WriteLine(s.Pop()); 
     } 
    } 

    public static void Main(String[] args){ 

    Stack<int> s2 = new Stack<int>(); 
    s2.Push(4); 
    s2.Push(5); 
    s2.Push(6); 

    PrintStackContents(s2);  

    Stack<string> s1 = new Stack<string>(); 
    s1.Push("One"); 
    s1.Push("Two"); 
    s1.Push("Three"); 

    PrintStackContents(s1); 
    } 
} 

जावा कोड

import java.util.*; 

class Test{ 

    //Prints the contents of any generic Stack by 
    //specifying wildcard type 
    public static void PrintStackContents(Stack<?> s){ 
     while(!s.empty()){ 
      System.out.println(s.pop()); 
     } 
    } 

    public static void main(String[] args){ 

    Stack <Integer> s2 = new Stack <Integer>(); 
    s2.push(4); 
    s2.push(5); 
    s2.push(6); 

    PrintStackContents(s2);  

    Stack<String> s1 = new Stack<String>(); 
    s1.push("One"); 
    s1.push("Two"); 
    s1.push("Three"); 

    PrintStackContents(s1); 
    } 
} 
+1

सी # -like अनुमान जावा 6 में भी काम करता है। क्या जावा में अभी भी का उपयोग किया गया है? –

+21

यह वास्तव में सवाल का जवाब नहीं दे रहा है। जवाब न है"। ऊपर दिखाया गया चाल सी # में जावा के कैप्चर रूपांतरण के लिए एक वर्कअराउंड दिखाता है जो विधि आमंत्रण रूपांतरण के साथ काम करता है, लेकिन असाइनमेंट रूपांतरण या कलाकार अभिव्यक्ति में उपयोगी नहीं होगा। – Mishax

+4

असल में, यह जवाब "नहीं" कहने का सबसे लंबा तरीका है जिसे मैंने कभी देखा है :) – David

1

नहीं, वास्तव में सी # में एक ही अवधारणा नहीं है। आपको फू (शायद एक गैर-जेनेरिक फू) की बेस क्लास को संदर्भित करना होगा, या जिस विधि को आप सामान्य रूप से काम कर रहे हैं उसे बनाएं (ताकि आप फू को देख सकें, और अपनी विधि के कॉलर को यह निर्धारित करने दें कि टी है)।

उम्मीद है कि मदद करता है।

4

सी # में समकक्ष वाक्यविन्यास नहीं है।

12

AFAIK आप इसे सी # में नहीं कर सकते हैं। बीसीएल क्या करता है और वहां उदाहरणों की दिक्कतें होती हैं जो ऐसी कक्षा बनाने के लिए होती हैं जो सामान्य नहीं होती है और फिर एक सामान्य वर्ग बनाती है जो पिछले एक से मूल व्यवहार को प्राप्त करती है। नीचे उदाहरण देखें।

class Foo 
{ 
} 

class Foo<T> : Foo 
{ 
} 

, जिसे आप कुछ इस तरह लिख सकते हैं:

Foo t = new Foo<int>(); 
3

सी # में कोई समकक्ष नहीं है यह है (काफी) सच नहीं है कि। कोई स्थैतिक समतुल्य नहीं है जिसे आप एक प्रकार, या कॉल विधियों के रूप में उपयोग कर सकते हैं, पर्याप्त सत्य। इसके लिए, Jorge's answer का उपयोग करें।

दूसरी ओर, कभी-कभी आपको प्रतिबिंब के लिए समकक्ष विचार की आवश्यकता होती है, और वहां समकक्ष होता है। यदि आपके पास:

interface IFoo<T> 
{ 
    T Bar(T t, int n); 
} 

आप एक Type कि IFoo<int> का प्रतिनिधित्व करता है typeof(IFoo<int>) का उपयोग कर प्राप्त कर सकते हैं। कम ज्ञात, और आपके प्रश्न का आंशिक उत्तर यह है कि आप Type भी प्राप्त कर सकते हैं जो का प्रतिनिधित्व typeof(IFoo<>) का उपयोग करता है।

यह उपयोगी है जब आप प्रतिबिंब के माध्यम से T के लिए IFoo<T> का उपयोग करना चाहते हैं और रनटाइम तक T नहीं जान पाएंगे।

Type theInterface = typeof(IFoo<>); 
Type theSpecificInterface = theInterface.MakeGenericType(typeof(string)); 

// theSpecificInterface now holds IFoo<string> even though we may not have known we wanted to use string until runtime 

// proceed with reflection as normal, make late bound calls/constructions, emit DynamicMethod code, etc. 
11

स्वीकार्य रूप से स्वच्छ दृष्टिकोण नहीं होने पर, Foo<object> x का उपयोग करके भी उपयुक्त हो सकता है।

+2

-1: 'ऑब्जेक्ट' का उपयोग करके सामान्य प्रकार को उन सभी प्रकारों तक सीमित करें जिनमें सामान्य सुपर क्लास 'ऑब्जेक्ट' है। –

+3

सबकुछ के साथ काम करता है: प्राइमेटिव्स, क्लास ऑब्जेक्ट्स, structs, enums ... 'सूची सूची = नई सूची (); list.Add (1); सूची जोड़ें। जोड़ें (नया डेटटाइम()); सूची जोड़ें। जोड़ें (नया MyStruct()); सूची। जोड़ें (MyEnum.Enum1); ' – Dani

+0

मैं मानता हूं कि आप सही हैं। –

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