كيف يمكنني تحديد قيمة المعلمة العامة في مثيل صفي

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

  •  02-07-2019
  •  | 
  •  

سؤال

لدي واجهة علامة محددة على أنها

public interface IExtender<T>
{
}

لدي فصل يطبق IExtender

public class UserExtender : IExtender<User>

في وقت التشغيل أتلقى نوع UserExtender كمعلمة لطريقة التقييم الخاصة بي

public Type Evaluate(Type type) // type == typeof(UserExtender)

كيف يمكنني إعادة طريقة التقييم الخاصة بي

typeof(User)

بناء على تقييم وقت التشغيل.أنا متأكد من أن الانعكاس متضمن ولكن لا يبدو أنني أستطيع حله.

(لم أكن متأكداً من كيفية صياغة هذا السؤال.آمل أن يكون الأمر واضحًا بما فيه الكفاية.)

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

المحلول 3

لقد ذهبت بهذه الطريقة بناءً على بعض الحكايات المقدمة.يمكن جعله أكثر قوة للتعامل مع الوسائط العامة المتعددة على الواجهة....لكنني لم أكن في حاجة إليها ;)

private static Type SafeGetSingleGenericParameter(Type type, Type interfaceType)
{
    if (!interfaceType.IsGenericType || interfaceType.GetGenericArguments().Count() != 1)
        return type;

    foreach (Type baseInterface in type.GetInterfaces())
    {
        if (baseInterface.IsGenericType &&
                baseInterface.GetGenericTypeDefinition() == interfaceType.GetGenericTypeDefinition())
        {
            return baseInterface.GetGenericArguments().Single();
        }
    }

    return type;
}

نصائح أخرى

يوجد مثال لفعل ما تصفه في وثائق MSDN لـ طريقة GetGenericTypeDefinition.يستخدم طريقة GetGenericArguments.

Type[] typeArguments = t.GetGenericArguments();
Console.WriteLine("\tList type arguments ({0}):", typeArguments.Length);
foreach (Type tParam in typeArguments)
{
    Console.WriteLine("\t\t{0}", tParam);
}

في المثال الخاص بك أعتقد أنك تريد استبداله t مع this.إذا لم ينجح ذلك بشكل مباشر، فقد تحتاج إلى القيام بشيء ما باستخدام ملف طريقة GetInterfaces لتعداد الواجهات الحالية على النوع الخاص بك ومن ثم GetGenericArguments() من نوع الواجهة

قرأت سؤالك بشكل مختلف تمامًا عن الإجابات الأخرى.

إذا كان من الممكن تغيير توقيع التقييم إلى:

public Type Evaluate<T>(IExtender<T> it)
{
    return typeof(T);
}

لا يتطلب هذا تغيير رمز الاتصال، ولكنه يتطلب أن تكون المعلمة من النوع IExtender<T>, ، ومع ذلك يمكنك الوصول بسهولة إلى النوع T :

// ** compiled and tested    
UserExtender ue = new UserExtender();
Type t = Evaluate(ue);

من المؤكد أنها ليست عامة مثل شيء مجرد أخذ Type المعلمة، ولكن هذا هو تناول مختلف للمشكلة.لاحظ أيضًا أن هناك الاعتبارات الأمنية للتفكير [msdn]

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