C #: كيفية العثور على مثيلات وإنشاءها التي تلبي قيود متعددة

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

سؤال

قل لدي طريقة عامة مع قيود متعددة من النوع، وهذا هذا:

public static void DoSomethingAwesome<T>(T thing)
    where T : IThing, IAwesome, IComparable<T>
{
    ...
}

الآن .... كيف يمكنني استخدام التفكير، وإنشاء شيء يمكنني إرساله هناك؟

إذا كان ذلك قيد واحد فقط أعرف أنني أستطيع أن أفعل ذلك مثل هذا:

var types = assembly
      .GetTypes()
      .Where(typeof (IThing).IsAssignableFrom)

foreach(var t in types)
    DoSomethingAwesome((IThing) Activator.CreateInstance(t));

ولكن، لا يمكن أن يلقي حقا إلى واجهات متعددة ... كيف يمكن أن يحل هذا الأمر؟ هل يمكن القول أنني فقدت إلى حد كبير هنا الآن: P

حصلت العنوان على نوع طويل ومعقد لأنني لم أكن متأكدا مما يجب الاتصال به، يرجى تحسينه إذا استطعت

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

المحلول

للإضافة إلى إجابات ريد ولورين حول إيجاد أنواع مناسبة، لاحظ أنك لا تزال قادرا على الاتصال بالجرعات doshotomawome عن طريق الصب، لأنه كما وجدت، لا يوفر المترجم طريقة لإلقاء كائن مثيل على واجهات متعددة. لديك خياران:

  1. قم بإنشاء واجهة جديدة IAWESOMECOMPARABLETION التي تستمد من Ithing، IAwesome and exomparableu003CT> ، هل تنفذ الأنواع الخاصة بك، وإلقاء ذلك على ذلك.

  2. استدعاء dosom معا من خلال انعكاس. للقيام بذلك، ستحتاج إلى الحصول على MethodInfo للطريقة العامة Doshothonwesome Generic، ثم اتصل ب PhoticeInfo.makegenericmethod مع نوعك الذي ينفذ جميع الواجهات الثلاثة.

مثال (2):

Type type = sometype; // For example found using reeds method
MethodInfo mgeneric = typeof(Awesomeiser).GetMethod("DoSomethingAwesome");
MethodInfo mspecific = mgeneric.MakeGenericMethod(new [] { type });
mspecific.Invoke(null, new [] { type });

نصائح أخرى

أنا أظن أن هناك بعض الأسباب التي لا يمكنك القيام بها

var types = assembly
.GetTypes()
.Where(typeof (IThing).IsAssignableFrom && typeof (IAwesome).IsAssignableFrom))

تحتاج إلى نوع قابل للتعديل من جميع قيودك. أولهما سهلان، لكن المركز الثالث صعب بعض الشيء:

// Using
static bool IsIComparable(Type thing)
    {
        foreach (Type interfaceType in thing.GetInterfaces())
        {
            if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof (IComparable<>))
            {
                Type[] arguments = interfaceType.GetGenericArguments();
                if (arguments.Length == 1)
                {
                    if (arguments[0] == thing)
                        return true;
                }
            }
        }
        return false;
    }


// This returns an enumerable of compatible types:
var types = assembly.GetTypes().Where( t => 
   typeof(IThing).IsAssignableFrom(t) &&
   typeof(IAwesome).IsAssignableFrom(t) &&
   IsIComparable(t) );
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top