هل هناك علامة عامة "مجهولة" في C#، مثل "؟" في جافا؟

StackOverflow https://stackoverflow.com/questions/116830

  •  02-07-2019
  •  | 
  •  

سؤال

في Java، يمكن للمرء أن يعلن عن متغير له معلمات من نوع عام "غير معروف"، والذي يبدو كما يلي:

Foo<?> x;

هل هناك بنية مكافئة لعلامة الاستفهام هذه في لغة C#؟

هل كانت مفيدة؟

المحلول

الجواب القصير هو لا.لا توجد ميزة مماثلة في C#.

الحل البديل، من C# من وجهة نظر مطور Java بواسطة داري أوباسانجو:

في بعض الحالات، قد يحتاج المرء إلى إنشاء طريقة يمكنها العمل على هياكل البيانات التي تحتوي على أي نوع بدلاً من تلك التي تحتوي على نوع معين (على سبيل المثال.طريقة لطباعة جميع الكائنات الموجودة في بنية البيانات) مع الاستمرار في الاستفادة من فوائد الكتابة القوية في الأدوية العامة.آلية تحديد ذلك في C# تتم عبر ميزة تسمى استنتاج النوع العام بينما يتم ذلك في Java باستخدام أنواع أحرف البدل.توضح نماذج التعليمات البرمجية التالية كيف يؤدي كلا الأسلوبين إلى نفس النتيجة.

كود سي#

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

نصائح أخرى

AFAIK لا يمكنك فعل ذلك في C#.ما يفعله BCL وهناك الكثير من الأمثلة هو إنشاء فئة ليست عامة ثم إنشاء فئة عامة ترث السلوك الأساسي من الفئة السابقة.انظر المثال أدناه.

class Foo
{
}

class Foo<T> : Foo
{
}

يمكنك كتابة شيء مثل هذا:

Foo t = new Foo<int>();

في حين أنه ليس النهج النظيف، باستخدام Foo<object> x قد تكون مناسبة أيضًا.

لا يوجد بناء جملة مكافئ في C#.

ليس صحيحًا (تمامًا) أنه لا يوجد ما يعادله في لغة C#.لا يوجد مكافئ ثابت يمكنك استخدامه كنوع أو طرق استدعاء، وهذا صحيح بما فيه الكفاية.من أجل ذلك استخدم إجابة جورجي.

من ناحية أخرى، في بعض الأحيان تحتاج إلى فكرة مكافئة للتفكير، وهناك ما يعادلها هناك.اذا كنت تمتلك:

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

يمكنك الحصول على Type الذي يمثل IFoo<int> استخدام typeof(IFoo<int>).الأقل شهرة، والإجابة الجزئية لسؤالك، هي أنه يمكنك أيضًا الحصول على Type الذي يمثل IFoo<T> استخدام typeof(IFoo<>).

وهذا مفيد عندما تريد استخدامه IFoo<T> بالنسبة للبعض 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.

لا، ليس هناك حقًا نفس المفهوم في لغة C#.ستحتاج إلى الإشارة إلى فئة أساسية من Foo (ربما Foo غير عامة)، أو جعل الطريقة التي تعمل بها عامة في حد ذاتها (بحيث يمكنك الرجوع إلى Foo، والسماح للمتصل بالطريقة الخاصة بك بتحديد ما هو T يكون).

امل ان يساعد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top