জেনেরিক ক্লাস থেকে কোনও ক্লাস উত্পন্ন হয়েছে কিনা তা পরীক্ষা করুন


309

আমার প্রকল্পে উত্পন্ন ক্লাস সহ আমার জেনেরিক ক্লাস রয়েছে।

public class GenericClass<T> : GenericInterface<T>
{
}

public class Test : GenericClass<SomeType>
{
}

কোনও Typeবস্তু উত্পন্ন হয়েছে কিনা তা খুঁজে বের করার কোনও উপায় আছে GenericClass?

t.IsSubclassOf(typeof(GenericClass<>))

কাজ করে না.

উত্তর:


430

এই কোড ব্যবহার করে দেখুন

static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
    while (toCheck != null && toCheck != typeof(object)) {
        var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
        if (generic == cur) {
            return true;
        }
        toCheck = toCheck.BaseType;
    }
    return false;
}

4
এটি কোডের একটি মিষ্টি অংশ, আমাকে বলতে হবে have যখন লুপ বাস্তবায়ন অপ্রয়োজনীয় পুনরাবৃত্তি কর্মক্ষমতা হিট এড়ানো। এটি মেটা-জেনেরিক প্রশ্নের একটি মার্জিত এবং সুন্দর সমাধান।
এনোকএনআরল - আনন্দগোপাল পারদু

2
আমি এই কাঠামোটি আমার কাঠামোর মধ্যে আমার রিফ্লেকশন ইউটিস স্ট্যাটিক ক্লাসে যুক্ত করেছি এবং আমি এটিকে অবজেক্টের জন্য এক্সটেনশন পদ্ধতি হিসাবে ট্যাপচেক = অবজেক্ট.গেটটাইপ () টাইপ হিসাবে পদ্ধতির মধ্যে টেক চেককে সংজ্ঞায়িত করে এটিকে এক্সটেনশন পদ্ধতি হিসাবেও অভিযোজিত করেছি; প্রদত্ত "এই অবজেক্ট আপত্তি" হ'ল প্রথম প্যারামিটার।
এনোকএনআরল - আনন্দগোপাল পারদু

11
টু চেক প্রকারটি শ্রেণি না (যেমন, ইন্টারফেস) না হলে লুপটি ভেঙে যাবে না। এটি একটি নুলারফেরান এক্সসেপশন ঘটাবে।
জেডি কর্টয়ে

2
আপনি যদি অনুসন্ধান করছেন এমন জেনেরিক টাইপ যদি টেক চেক হয় তবে এটিও সত্য হবে।
ওলিও

14
এটি কেবল কংক্রিট ধরণের উত্তরাধিকারের জন্যই কাজ করে ... পরীক্ষার কেস: বুল প্রত্যাশিত = সত্য; বুল আসল = প্রোগ্রাম.আইএসএসব্লাকসঅফআরজেনারিক (টাইপফ (আইয়ানামিউরেবল <>), টাইপফ (তালিকা <স্ট্রিং>)); Assert.AreEqual (প্রত্যাশিত, আসল); // ব্যর্থ
ববি

90

(একটি বিশাল পুনর্লিখনের কারণে পোস্ট করা হয়েছে)

জারেডপারের কোড উত্তরটি দুর্দান্ত, তবে আমার কাছে একটি টিপ রয়েছে যা আপনার জেনেরিক ধরণের মান ধরণের পরামিতিগুলির উপর ভিত্তি করে না থাকলে এটি অপ্রয়োজনীয় করে তুলবে। "হ'ল" অপারেটর কেন কাজ করবে না সে সম্পর্কে আমাকে ঝুলিয়ে রাখা হয়েছিল, তাই আমি ভবিষ্যতের রেফারেন্সের জন্য আমার পরীক্ষার ফলাফলগুলিও নথিভুক্ত করেছি। আরও স্পষ্ট করতে এই উত্তরটি বাড়িয়ে দিন enhance

পরামর্শ:

আপনি যদি নিশ্চিত হন যে আপনার জেনেরিক ক্লাস বাস্তবায়ন জেনেরিক্লাসবেসের মতো একটি বিমূর্ত নন-জেনেরিক বেস শ্রেণীর উত্তরাধিকার সূত্রে আসে, আপনি বিনা ঝামেলা ছাড়াই একই প্রশ্ন জিজ্ঞাসা করতে পারেন:

typeof(Test).IsSubclassOf(typeof(GenericClassBase))

IsSubclassOf ()

আমার পরীক্ষাটি ইঙ্গিত করে যে ইসসব্লক্লসফ () প্যারামিটারলেস জেনেরিক ধরণের যেমন কাজ করে না

typeof(GenericClass<>)

যদিও এটি কাজ করবে

typeof(GenericClass<SomeType>)

সুতরাং নীচের কোডটি জেনেরিক ক্লাস <> এর যে কোনও অনুপাতের জন্য কাজ করবে, ধরে নিবেন যে আপনি সোমটাইপের ভিত্তিতে পরীক্ষা করতে ইচ্ছুক রয়েছেন:

typeof(Test).IsSubclassOf(typeof(GenericClass<SomeType>))

আমি একবারই কল্পনা করতে পারি যে আপনি জেনেরিক্লাস <> দ্বারা পরীক্ষা করতে চাইবেন <> একটি প্লাগ-ইন ফ্রেমওয়ার্ক দৃশ্যে।


"এটি" অপারেটর সম্পর্কিত চিন্তাভাবনা

ডিজাইনের সময় সি # প্যারামিটারলেস জেনেরিকগুলি ব্যবহারের অনুমতি দেয় না কারণ তারা মূলত সেই সময়ে সম্পূর্ণ সিএলআর টাইপ নয়। অতএব, আপনাকে অবশ্যই প্যারামিটারগুলির সাথে জেনেরিক ভেরিয়েবলগুলি ঘোষণা করতে হবে এবং এজন্য অবজেক্টের সাথে কাজ করার জন্য "হ'ল" অপারেটর এত শক্তিশালী। ঘটনাচক্রে, "হয়" অপারেটরও প্যারামিটারলেস জেনেরিক ধরণের মূল্যায়ন করতে পারে না।

"হয়" অপারেটর ইন্টারফেস সহ পুরো উত্তরাধিকার শৃঙ্খলা পরীক্ষা করবে।

সুতরাং, যে কোনও বস্তুর উদাহরণ দেওয়া হলে, নিম্নলিখিত পদ্ধতিটি কৌশলটি সম্পাদন করবে:

bool IsTypeof<T>(object t)
{
    return (t is T);
}

এটি এক ধরণের অপ্রয়োজনীয়, তবে আমি বুঝতে পেরেছিলাম যে আমি এগিয়ে গিয়ে প্রত্যেকের জন্য এটি কল্পনা করব।

প্রদত্ত

var t = new Test();

নিম্নলিখিত কোডের লাইনগুলি সত্য ফিরে আসবে:

bool test1 = IsTypeof<GenericInterface<SomeType>>(t);

bool test2 = IsTypeof<GenericClass<SomeType>>(t);

bool test3 = IsTypeof<Test>(t);

অন্যদিকে, আপনি যদি জেনেরিক ক্লাসের জন্য নির্দিষ্ট কিছু চান তবে আপনি এটি আরও নির্দিষ্ট করে তুলতে পারেন, আমি মনে করি, এটির মতো:

bool IsTypeofGenericClass<SomeType>(object t)
{
    return (t is GenericClass<SomeType>);
}

তারপরে আপনি এটির মতো পরীক্ষা করে দেখবেন:

bool test1 = IsTypeofGenericClass<SomeType>(t);

2
বিশ্লেষণ এবং পরীক্ষার জন্য +1। এছাড়াও, আপনার উত্তরটি আমার ক্ষেত্রে খুব কার্যকর ছিল।
গিলারমো গুটিরিজ

3
এটি লক্ষ করা উচিত যে সংকলকটি পুরোপুরি খুশি I
ব্যবহারকারী 2880616

2
তবে কি যদি সংকলন সময়ে সুমটাইপটি জানা না যায়?
রায়ান দ্য লিচ

পুরো আলোচনার মূল বিষয়টি ছিল যখন আপনার কেবল কোনও Typeবিষয় থাকে।
জোনাথন উড

@ জোনাথনউড এজন্য আমার উপরের উত্তরটি typeofঅপারেটরের সাথে আচরণ করছে । দস্তাবেজগুলির মতে: "টাইপ অফ অপারেটর একটি প্রকারের জন্য System.Type অবজেক্ট প্রাপ্ত করতে ব্যবহৃত হয়।"
এনোকএনআরল - আনন্দগোপাল পারদু

33

আমি এই কয়েকটি নমুনার মধ্য দিয়ে কাজ করেছি এবং দেখেছি সেগুলির কিছু ক্ষেত্রে অভাব রয়েছে। এই সংস্করণটি সমস্ত ধরণের জেনেরিকের সাথে কাজ করে: প্রকার, ইন্টারফেস এবং ধরণের সংজ্ঞা।

public static bool InheritsOrImplements(this Type child, Type parent)
{
    parent = ResolveGenericTypeDefinition(parent);

    var currentChild = child.IsGenericType
                           ? child.GetGenericTypeDefinition()
                           : child;

    while (currentChild != typeof (object))
    {
        if (parent == currentChild || HasAnyInterfaces(parent, currentChild))
            return true;

        currentChild = currentChild.BaseType != null
                       && currentChild.BaseType.IsGenericType
                           ? currentChild.BaseType.GetGenericTypeDefinition()
                           : currentChild.BaseType;

        if (currentChild == null)
            return false;
    }
    return false;
}

private static bool HasAnyInterfaces(Type parent, Type child)
{
    return child.GetInterfaces()
        .Any(childInterface =>
        {
            var currentInterface = childInterface.IsGenericType
                ? childInterface.GetGenericTypeDefinition()
                : childInterface;

            return currentInterface == parent;
        });
}

private static Type ResolveGenericTypeDefinition(Type parent)
{
    var shouldUseGenericType = true;
    if (parent.IsGenericType && parent.GetGenericTypeDefinition() != parent)
        shouldUseGenericType = false;

    if (parent.IsGenericType && shouldUseGenericType)
        parent = parent.GetGenericTypeDefinition();
    return parent;
}

এখানে ইউনিট পরীক্ষাগুলিও রয়েছে:

protected interface IFooInterface
{
}

protected interface IGenericFooInterface<T>
{
}

protected class FooBase
{
}

protected class FooImplementor
    : FooBase, IFooInterface
{
}

protected class GenericFooBase
    : FooImplementor, IGenericFooInterface<object>
{

}

protected class GenericFooImplementor<T>
    : FooImplementor, IGenericFooInterface<T>
{
}


[Test]
public void Should_inherit_or_implement_non_generic_interface()
{
    Assert.That(typeof(FooImplementor)
        .InheritsOrImplements(typeof(IFooInterface)), Is.True);
}

[Test]
public void Should_inherit_or_implement_generic_interface()
{
    Assert.That(typeof(GenericFooBase)
        .InheritsOrImplements(typeof(IGenericFooInterface<>)), Is.True);
}

[Test]
public void Should_inherit_or_implement_generic_interface_by_generic_subclass()
{
    Assert.That(typeof(GenericFooImplementor<>)
        .InheritsOrImplements(typeof(IGenericFooInterface<>)), Is.True);
}

[Test]
public void Should_inherit_or_implement_generic_interface_by_generic_subclass_not_caring_about_generic_type_parameter()
{
    Assert.That(new GenericFooImplementor<string>().GetType()
        .InheritsOrImplements(typeof(IGenericFooInterface<>)), Is.True);
}

[Test]
public void Should_not_inherit_or_implement_generic_interface_by_generic_subclass_not_caring_about_generic_type_parameter()
{
    Assert.That(new GenericFooImplementor<string>().GetType()
        .InheritsOrImplements(typeof(IGenericFooInterface<int>)), Is.False);
}

[Test]
public void Should_inherit_or_implement_non_generic_class()
{
    Assert.That(typeof(FooImplementor)
        .InheritsOrImplements(typeof(FooBase)), Is.True);
}

[Test]
public void Should_inherit_or_implement_any_base_type()
{
    Assert.That(typeof(GenericFooImplementor<>)
        .InheritsOrImplements(typeof(FooBase)), Is.True);
}

2
আমি রেজলজজেনেরিক টাইপডিফাইনিশন পদ্ধতিটি নিয়ে বিস্মিত। "ShouldUseGenericType" ভেরিয়েবলটি সত্যিই মান নির্ধারিত হয়: !parent.IsGenericType || parent.GetGenericTypeDefinition() == parent; সুতরাং আপনি যদি সেই পরিবর্তনকে প্রতিস্থাপনের বিস্তারের সাথে প্রতিস্থাপন করেন: if (parent.IsGenericType && shouldUseGenericType) এবং আপনি if (parent.IsGenericType && (!parent.IsGenericType || parent.GetGenericTypeDefinition() == parent)) যা পরে হ্রাস পাবেন if (parent.IsGenericType && parent.GetGenericTypeDefinition() == parent)) parent = parent.GetGenericTypeDefinition();
মাইকেল ব্ল্যাকবার্ন

2
যা কিছুই করবে বলে মনে হবে। এগুলি যদি মান ধরণের হয় তবে int j = 0; if (j is an int && j == 0) { j=0; } আমার রেফারেন্স সমান এবং মান সমান হয়ে যায়? আমি ভেবেছিলাম মেমোরিতে প্রতিটি টাইপের কেবলমাত্র একটি উদাহরণ রয়েছে, সুতরাং দুটি ভেরিয়েবলগুলি একই ধরণের দিকে নির্দেশ করে আসলে মেমরিতে একই অবস্থানের দিকে নির্দেশ করে।
মাইকেল ব্ল্যাকবার্ন

1
@ মিশেলব্ল্যাকবার্ন স্পট এ :) :) আমি এটিকে কেবল: রিটার্নেন্ট প্যারেন্ট.আইএসজেনেরিক টাইপ রিফেক্টর করেছি? প্যারেন্ট.গেটজেনারিক টাইপডিফাইনিশন (): পিতা বা মাতা;
অ্যারোন এইচএস

3
এটি যদি ইতিমধ্যে পিতামাতার মতো হয় তবে কেবল এটি ফিরিয়ে দিন! এবং তিনি গেজেইনারিক টাইপডেফকে অনেকবার কল করছেন। এটি কেবল একবার কল করা দরকার
অ্যারোন এইচএস

1
দুঃখিত, আমি নীচে একটি নতুন মন্তব্য যুক্ত করব।
মেন্নো দেইজ - ভ্যান রিজস্বিক

26

আমার কাছে মনে হচ্ছে এই বাস্তবায়নটি আরও অনেক ক্ষেত্রে কাজ করে (শিশু এবং পরামিতিগুলির নির্বিশেষে জেনেরিক ক্লাস এবং সূচনা পরামিতিগুলি ছাড়া বা ইন্টারফেস):

public static class ReflexionExtension
{
    public static bool IsSubClassOfGeneric(this Type child, Type parent)
    {
        if (child == parent)
            return false;

        if (child.IsSubclassOf(parent))
            return true;

        var parameters = parent.GetGenericArguments();
        var isParameterLessGeneric = !(parameters != null && parameters.Length > 0 &&
            ((parameters[0].Attributes & TypeAttributes.BeforeFieldInit) == TypeAttributes.BeforeFieldInit));

        while (child != null && child != typeof(object))
        {
            var cur = GetFullTypeDefinition(child);
            if (parent == cur || (isParameterLessGeneric && cur.GetInterfaces().Select(i => GetFullTypeDefinition(i)).Contains(GetFullTypeDefinition(parent))))
                return true;
            else if (!isParameterLessGeneric)
                if (GetFullTypeDefinition(parent) == cur && !cur.IsInterface)
                {
                    if (VerifyGenericArguments(GetFullTypeDefinition(parent), cur))
                        if (VerifyGenericArguments(parent, child))
                            return true;
                }
                else
                    foreach (var item in child.GetInterfaces().Where(i => GetFullTypeDefinition(parent) == GetFullTypeDefinition(i)))
                        if (VerifyGenericArguments(parent, item))
                            return true;

            child = child.BaseType;
        }

        return false;
    }

    private static Type GetFullTypeDefinition(Type type)
    {
        return type.IsGenericType ? type.GetGenericTypeDefinition() : type;
    }

    private static bool VerifyGenericArguments(Type parent, Type child)
    {
        Type[] childArguments = child.GetGenericArguments();
        Type[] parentArguments = parent.GetGenericArguments();
        if (childArguments.Length == parentArguments.Length)
            for (int i = 0; i < childArguments.Length; i++)
                if (childArguments[i].Assembly != parentArguments[i].Assembly || childArguments[i].Name != parentArguments[i].Name || childArguments[i].Namespace != parentArguments[i].Namespace)
                    if (!childArguments[i].IsSubclassOf(parentArguments[i]))
                        return false;

        return true;
    }
}

এখানে আমার 70 76 টি পরীক্ষার মামলা রয়েছে:

[TestMethod]
public void IsSubClassOfGenericTest()
{
    Assert.IsTrue(typeof(ChildGeneric).IsSubClassOfGeneric(typeof(BaseGeneric<>)), " 1");
    Assert.IsFalse(typeof(ChildGeneric).IsSubClassOfGeneric(typeof(WrongBaseGeneric<>)), " 2");
    Assert.IsTrue(typeof(ChildGeneric).IsSubClassOfGeneric(typeof(IBaseGeneric<>)), " 3");
    Assert.IsFalse(typeof(ChildGeneric).IsSubClassOfGeneric(typeof(IWrongBaseGeneric<>)), " 4");
    Assert.IsTrue(typeof(IChildGeneric).IsSubClassOfGeneric(typeof(IBaseGeneric<>)), " 5");
    Assert.IsFalse(typeof(IWrongBaseGeneric<>).IsSubClassOfGeneric(typeof(ChildGeneric2<>)), " 6");
    Assert.IsTrue(typeof(ChildGeneric2<>).IsSubClassOfGeneric(typeof(BaseGeneric<>)), " 7");
    Assert.IsTrue(typeof(ChildGeneric2<Class1>).IsSubClassOfGeneric(typeof(BaseGeneric<>)), " 8");
    Assert.IsTrue(typeof(ChildGeneric).IsSubClassOfGeneric(typeof(BaseGeneric<Class1>)), " 9");
    Assert.IsFalse(typeof(ChildGeneric).IsSubClassOfGeneric(typeof(WrongBaseGeneric<Class1>)), "10");
    Assert.IsTrue(typeof(ChildGeneric).IsSubClassOfGeneric(typeof(IBaseGeneric<Class1>)), "11");
    Assert.IsFalse(typeof(ChildGeneric).IsSubClassOfGeneric(typeof(IWrongBaseGeneric<Class1>)), "12");
    Assert.IsTrue(typeof(IChildGeneric).IsSubClassOfGeneric(typeof(IBaseGeneric<Class1>)), "13");
    Assert.IsFalse(typeof(BaseGeneric<Class1>).IsSubClassOfGeneric(typeof(ChildGeneric2<Class1>)), "14");
    Assert.IsTrue(typeof(ChildGeneric2<Class1>).IsSubClassOfGeneric(typeof(BaseGeneric<Class1>)), "15");
    Assert.IsFalse(typeof(ChildGeneric).IsSubClassOfGeneric(typeof(ChildGeneric)), "16");
    Assert.IsFalse(typeof(IChildGeneric).IsSubClassOfGeneric(typeof(IChildGeneric)), "17");
    Assert.IsFalse(typeof(IBaseGeneric<>).IsSubClassOfGeneric(typeof(IChildGeneric2<>)), "18");
    Assert.IsTrue(typeof(IChildGeneric2<>).IsSubClassOfGeneric(typeof(IBaseGeneric<>)), "19");
    Assert.IsTrue(typeof(IChildGeneric2<Class1>).IsSubClassOfGeneric(typeof(IBaseGeneric<>)), "20");
    Assert.IsFalse(typeof(IBaseGeneric<Class1>).IsSubClassOfGeneric(typeof(IChildGeneric2<Class1>)), "21");
    Assert.IsTrue(typeof(IChildGeneric2<Class1>).IsSubClassOfGeneric(typeof(IBaseGeneric<Class1>)), "22");
    Assert.IsFalse(typeof(IBaseGeneric<Class1>).IsSubClassOfGeneric(typeof(BaseGeneric<Class1>)), "23");
    Assert.IsTrue(typeof(BaseGeneric<Class1>).IsSubClassOfGeneric(typeof(IBaseGeneric<Class1>)), "24");
    Assert.IsFalse(typeof(IBaseGeneric<>).IsSubClassOfGeneric(typeof(BaseGeneric<>)), "25");
    Assert.IsTrue(typeof(BaseGeneric<>).IsSubClassOfGeneric(typeof(IBaseGeneric<>)), "26");
    Assert.IsTrue(typeof(BaseGeneric<Class1>).IsSubClassOfGeneric(typeof(IBaseGeneric<>)), "27");
    Assert.IsFalse(typeof(IBaseGeneric<Class1>).IsSubClassOfGeneric(typeof(IBaseGeneric<Class1>)), "28");
    Assert.IsTrue(typeof(BaseGeneric2<Class1>).IsSubClassOfGeneric(typeof(IBaseGeneric<Class1>)), "29");
    Assert.IsFalse(typeof(IBaseGeneric<>).IsSubClassOfGeneric(typeof(BaseGeneric2<>)), "30");
    Assert.IsTrue(typeof(BaseGeneric2<>).IsSubClassOfGeneric(typeof(IBaseGeneric<>)), "31");
    Assert.IsTrue(typeof(BaseGeneric2<Class1>).IsSubClassOfGeneric(typeof(IBaseGeneric<>)), "32");
    Assert.IsTrue(typeof(ChildGenericA).IsSubClassOfGeneric(typeof(BaseGenericA<,>)), "33");
    Assert.IsFalse(typeof(ChildGenericA).IsSubClassOfGeneric(typeof(WrongBaseGenericA<,>)), "34");
    Assert.IsTrue(typeof(ChildGenericA).IsSubClassOfGeneric(typeof(IBaseGenericA<,>)), "35");
    Assert.IsFalse(typeof(ChildGenericA).IsSubClassOfGeneric(typeof(IWrongBaseGenericA<,>)), "36");
    Assert.IsTrue(typeof(IChildGenericA).IsSubClassOfGeneric(typeof(IBaseGenericA<,>)), "37");
    Assert.IsFalse(typeof(IWrongBaseGenericA<,>).IsSubClassOfGeneric(typeof(ChildGenericA2<,>)), "38");
    Assert.IsTrue(typeof(ChildGenericA2<,>).IsSubClassOfGeneric(typeof(BaseGenericA<,>)), "39");
    Assert.IsTrue(typeof(ChildGenericA2<ClassA, ClassB>).IsSubClassOfGeneric(typeof(BaseGenericA<,>)), "40");
    Assert.IsTrue(typeof(ChildGenericA).IsSubClassOfGeneric(typeof(BaseGenericA<ClassA, ClassB>)), "41");
    Assert.IsFalse(typeof(ChildGenericA).IsSubClassOfGeneric(typeof(WrongBaseGenericA<ClassA, ClassB>)), "42");
    Assert.IsTrue(typeof(ChildGenericA).IsSubClassOfGeneric(typeof(IBaseGenericA<ClassA, ClassB>)), "43");
    Assert.IsFalse(typeof(ChildGenericA).IsSubClassOfGeneric(typeof(IWrongBaseGenericA<ClassA, ClassB>)), "44");
    Assert.IsTrue(typeof(IChildGenericA).IsSubClassOfGeneric(typeof(IBaseGenericA<ClassA, ClassB>)), "45");
    Assert.IsFalse(typeof(BaseGenericA<ClassA, ClassB>).IsSubClassOfGeneric(typeof(ChildGenericA2<ClassA, ClassB>)), "46");
    Assert.IsTrue(typeof(ChildGenericA2<ClassA, ClassB>).IsSubClassOfGeneric(typeof(BaseGenericA<ClassA, ClassB>)), "47");
    Assert.IsFalse(typeof(ChildGenericA).IsSubClassOfGeneric(typeof(ChildGenericA)), "48");
    Assert.IsFalse(typeof(IChildGenericA).IsSubClassOfGeneric(typeof(IChildGenericA)), "49");
    Assert.IsFalse(typeof(IBaseGenericA<,>).IsSubClassOfGeneric(typeof(IChildGenericA2<,>)), "50");
    Assert.IsTrue(typeof(IChildGenericA2<,>).IsSubClassOfGeneric(typeof(IBaseGenericA<,>)), "51");
    Assert.IsTrue(typeof(IChildGenericA2<ClassA, ClassB>).IsSubClassOfGeneric(typeof(IBaseGenericA<,>)), "52");
    Assert.IsFalse(typeof(IBaseGenericA<ClassA, ClassB>).IsSubClassOfGeneric(typeof(IChildGenericA2<ClassA, ClassB>)), "53");
    Assert.IsTrue(typeof(IChildGenericA2<ClassA, ClassB>).IsSubClassOfGeneric(typeof(IBaseGenericA<ClassA, ClassB>)), "54");
    Assert.IsFalse(typeof(IBaseGenericA<ClassA, ClassB>).IsSubClassOfGeneric(typeof(BaseGenericA<ClassA, ClassB>)), "55");
    Assert.IsTrue(typeof(BaseGenericA<ClassA, ClassB>).IsSubClassOfGeneric(typeof(IBaseGenericA<ClassA, ClassB>)), "56");
    Assert.IsFalse(typeof(IBaseGenericA<,>).IsSubClassOfGeneric(typeof(BaseGenericA<,>)), "57");
    Assert.IsTrue(typeof(BaseGenericA<,>).IsSubClassOfGeneric(typeof(IBaseGenericA<,>)), "58");
    Assert.IsTrue(typeof(BaseGenericA<ClassA, ClassB>).IsSubClassOfGeneric(typeof(IBaseGenericA<,>)), "59");
    Assert.IsFalse(typeof(IBaseGenericA<ClassA, ClassB>).IsSubClassOfGeneric(typeof(IBaseGenericA<ClassA, ClassB>)), "60");
    Assert.IsTrue(typeof(BaseGenericA2<ClassA, ClassB>).IsSubClassOfGeneric(typeof(IBaseGenericA<ClassA, ClassB>)), "61");
    Assert.IsFalse(typeof(IBaseGenericA<,>).IsSubClassOfGeneric(typeof(BaseGenericA2<,>)), "62");
    Assert.IsTrue(typeof(BaseGenericA2<,>).IsSubClassOfGeneric(typeof(IBaseGenericA<,>)), "63");
    Assert.IsTrue(typeof(BaseGenericA2<ClassA, ClassB>).IsSubClassOfGeneric(typeof(IBaseGenericA<,>)), "64");
    Assert.IsFalse(typeof(BaseGenericA2<ClassB, ClassA>).IsSubClassOfGeneric(typeof(IBaseGenericA<ClassA, ClassB>)), "65");
    Assert.IsFalse(typeof(BaseGenericA<ClassB, ClassA>).IsSubClassOfGeneric(typeof(ChildGenericA2<ClassA, ClassB>)), "66");
    Assert.IsFalse(typeof(BaseGenericA2<ClassB, ClassA>).IsSubClassOfGeneric(typeof(BaseGenericA<ClassA, ClassB>)), "67");
    Assert.IsTrue(typeof(ChildGenericA3<ClassA, ClassB>).IsSubClassOfGeneric(typeof(BaseGenericB<ClassA, ClassB, ClassC>)), "68");
    Assert.IsTrue(typeof(ChildGenericA4<ClassA, ClassB>).IsSubClassOfGeneric(typeof(IBaseGenericB<ClassA, ClassB, ClassC>)), "69");
    Assert.IsFalse(typeof(ChildGenericA3<ClassB, ClassA>).IsSubClassOfGeneric(typeof(BaseGenericB<ClassA, ClassB, ClassC>)), "68-2");
    Assert.IsTrue(typeof(ChildGenericA3<ClassA, ClassB2>).IsSubClassOfGeneric(typeof(BaseGenericB<ClassA, ClassB, ClassC>)), "68-3");
    Assert.IsFalse(typeof(ChildGenericA3<ClassB2, ClassA>).IsSubClassOfGeneric(typeof(BaseGenericB<ClassA, ClassB, ClassC>)), "68-4");
    Assert.IsFalse(typeof(ChildGenericA4<ClassB, ClassA>).IsSubClassOfGeneric(typeof(IBaseGenericB<ClassA, ClassB, ClassC>)), "69-2");
    Assert.IsTrue(typeof(ChildGenericA4<ClassA, ClassB2>).IsSubClassOfGeneric(typeof(IBaseGenericB<ClassA, ClassB, ClassC>)), "69-3");
    Assert.IsFalse(typeof(ChildGenericA4<ClassB2, ClassA>).IsSubClassOfGeneric(typeof(IBaseGenericB<ClassA, ClassB, ClassC>)), "69-4");
    Assert.IsFalse(typeof(bool).IsSubClassOfGeneric(typeof(IBaseGenericB<ClassA, ClassB, ClassC>)), "70");
}

পরীক্ষার জন্য ক্লাস এবং ইন্টারফেস:

public class Class1 { }
public class BaseGeneric<T> : IBaseGeneric<T> { }
public class BaseGeneric2<T> : IBaseGeneric<T>, IInterfaceBidon { }
public interface IBaseGeneric<T> { }
public class ChildGeneric : BaseGeneric<Class1> { }
public interface IChildGeneric : IBaseGeneric<Class1> { }
public class ChildGeneric2<Class1> : BaseGeneric<Class1> { }
public interface IChildGeneric2<Class1> : IBaseGeneric<Class1> { }

public class WrongBaseGeneric<T> { }
public interface IWrongBaseGeneric<T> { }

public interface IInterfaceBidon { }

public class ClassA { }
public class ClassB { }
public class ClassC { }
public class ClassB2 : ClassB { }
public class BaseGenericA<T, U> : IBaseGenericA<T, U> { }
public class BaseGenericB<T, U, V> { }
public interface IBaseGenericB<ClassA, ClassB, ClassC> { }
public class BaseGenericA2<T, U> : IBaseGenericA<T, U>, IInterfaceBidonA { }
public interface IBaseGenericA<T, U> { }
public class ChildGenericA : BaseGenericA<ClassA, ClassB> { }
public interface IChildGenericA : IBaseGenericA<ClassA, ClassB> { }
public class ChildGenericA2<ClassA, ClassB> : BaseGenericA<ClassA, ClassB> { }
public class ChildGenericA3<ClassA, ClassB> : BaseGenericB<ClassA, ClassB, ClassC> { }
public class ChildGenericA4<ClassA, ClassB> : IBaseGenericB<ClassA, ClassB, ClassC> { }
public interface IChildGenericA2<ClassA, ClassB> : IBaseGenericA<ClassA, ClassB> { }

public class WrongBaseGenericA<T, U> { }
public interface IWrongBaseGenericA<T, U> { }

public interface IInterfaceBidonA { }

4
এটি আমার জন্য কাজ করা একমাত্র সমাধান। একাধিক ধরণের পরামিতিগুলির ক্লাসগুলির সাথে কাজ করে এমন কোনও সমাধান আমি পাইনি। ধন্যবাদ.
কনার ক্লার্ক

1
আমি এই পরীক্ষার সমস্ত ক্ষেত্রে আপনাকে পোস্ট করার জন্য সত্যই প্রশংসা করেছি। আমি মনে করি যে 68 এবং 69 টি ক্ষেত্রে সত্যের পরিবর্তে মিথ্যা হওয়া উচিত, কারণ আপনার বামে ক্লাসবি, বামদিকে ক্লাসএ এবং ডানদিকে ক্লাসএ, ক্লাসবি রয়েছে।
Grax32

ঠিক বলেছেন, @ গ্রাक्स। আমার এখনই সংশোধন করার সময় নেই, তবে আমার পোস্টটি তা শেষ হওয়ার সাথে সাথেই আপডেট করব। আমি মনে করি সংশোধনটি অবশ্যই "VerifyGenericArguments" পদ্ধতিতে থাকতে হবে
Xav987

1
@ গ্র্যাক্স: সংশোধন করার জন্য আমি কিছু সময় পেয়েছি। আমি ক্লাসবি 2 ক্লাস যুক্ত করেছি, আমি ভেরিফিজারিকআরগমেন্টস পরিবর্তন করেছি এবং আমি ভেরিফিজারিকআরগমেন্টস এর ডাকে একটি নিয়ন্ত্রণ যুক্ত করেছি। আমি 68 এবং 69 কেসগুলিও সংশোধন করেছি এবং 68-2, 68-3, 68-4, 69-2, 69-3 এবং 69-4 এ যুক্ত করেছি।
Xav987

1
ধন্যবাদ জনাব. কাজের সমাধানের জন্য +1 এবং পরীক্ষার মামলার প্রচুর পরিমাণ (আমার পক্ষে কমপক্ষে, অবাক করা)।
Eldoïr

10

জারেডপার কোডটি কেবলমাত্র এক স্তরের উত্তরাধিকারের জন্য কাজ করে। উত্তরাধিকারের সীমাহীন স্তরের জন্য, নিম্নলিখিত কোডটি ব্যবহার করুন

public bool IsTypeDerivedFromGenericType(Type typeToCheck, Type genericType)
{
    if (typeToCheck == typeof(object))
    {
        return false;
    }
    else if (typeToCheck == null)
    {
        return false;
    }
    else if (typeToCheck.IsGenericType && typeToCheck.GetGenericTypeDefinition() == genericType)
    {
        return true;
    }
    else
    {
        return IsTypeDerivedFromGenericType(typeToCheck.BaseType, genericType);
    }
}

4
whileJaredPar এর কোড মধ্যে সীমাহীন মাত্রা জুড়ে।
জয়

@ জয় ... এবং পুনরাবৃত্তি এড়ানো।
মার্চ এল।

1
@MarcL। এটি লেজ পুনরাবৃত্তি ব্যবহার করে, তাই সংকলনটির পুনরাবৃত্তিটি অপ্টিমাইজ করার জন্য এটি তুচ্ছ হওয়া উচিত।
দারহুক

10

একটি নির্দিষ্ট ধরণের থেকে কোনও বস্তু উত্পন্ন হয়েছে তা যাচাই করার জন্য আমি এখানে একটি ছোট পদ্ধতি তৈরি করেছি। আমার জন্য দুর্দান্ত কাজ!

internal static bool IsDerivativeOf(this Type t, Type typeToCompare)
{
    if (t == null) throw new NullReferenceException();
    if (t.BaseType == null) return false;

    if (t.BaseType == typeToCompare) return true;
    else return t.BaseType.IsDerivativeOf(typeToCompare);
}

7

এটি ওভারকিল হতে পারে তবে আমি নিম্নলিখিতগুলির মতো এক্সটেনশন পদ্ধতি ব্যবহার করি। তারা ইন্টারফেস পাশাপাশি সাবক্লাস চেক করে check এটি নির্দিষ্ট জেনেরিক সংজ্ঞা রয়েছে এমন ধরণটিও ফিরিয়ে দিতে পারে।

যেমন প্রশ্নের উদাহরণ হিসাবে এটি জেনেরিক ইন্টারফেসের পাশাপাশি জেনেরিক শ্রেণির বিরুদ্ধেও পরীক্ষা করতে পারে। GetGenericArgumentsজেনেরিক আর্গুমেন্ট টাইপটি "সামারটাইপ" কিনা তা নির্ধারণ করতে প্রত্যাবর্তিত প্রকারটি ব্যবহার করা যেতে পারে ।

/// <summary>
/// Checks whether this type has the specified definition in its ancestry.
/// </summary>   
public static bool HasGenericDefinition(this Type type, Type definition)
{
    return GetTypeWithGenericDefinition(type, definition) != null;
}

/// <summary>
/// Returns the actual type implementing the specified definition from the
/// ancestry of the type, if available. Else, null.
/// </summary>
public static Type GetTypeWithGenericDefinition(this Type type, Type definition)
{
    if (type == null)
        throw new ArgumentNullException("type");
    if (definition == null)
        throw new ArgumentNullException("definition");
    if (!definition.IsGenericTypeDefinition)
        throw new ArgumentException(
            "The definition needs to be a GenericTypeDefinition", "definition");

    if (definition.IsInterface)
        foreach (var interfaceType in type.GetInterfaces())
            if (interfaceType.IsGenericType
                && interfaceType.GetGenericTypeDefinition() == definition)
                return interfaceType;

    for (Type t = type; t != null; t = t.BaseType)
        if (t.IsGenericType && t.GetGenericTypeDefinition() == definition)
            return t;

    return null;
}

ভাল পোস্ট! উদ্বেগগুলি দুটি পদ্ধতিতে ভাগ করে নেওয়ার জন্য দুর্দান্ত।
ওয়েবে টিজসমা

4

উপরে33rpho3nixx এবং ডেভিড শ্মিটের উত্তরের উত্তরের উপর ভিত্তি করে, আমি তাদের কোডটি সংশোধন করেছি এবং হোল্ডআইনেহেরিটঅরপ্লিমেন্টটাইপডজেনেরিকআইন্টারফেস পরীক্ষা (শেষ একটি) যুক্ত করেছি।

    /// <summary>
    /// Find out if a child type implements or inherits from the parent type.
    /// The parent type can be an interface or a concrete class, generic or non-generic.
    /// </summary>
    /// <param name="child"></param>
    /// <param name="parent"></param>
    /// <returns></returns>
    public static bool InheritsOrImplements(this Type child, Type parent)
    {
        var currentChild = parent.IsGenericTypeDefinition && child.IsGenericType ? child.GetGenericTypeDefinition() : child;

        while (currentChild != typeof(object))
        {
            if (parent == currentChild || HasAnyInterfaces(parent, currentChild))
                return true;

            currentChild = currentChild.BaseType != null && parent.IsGenericTypeDefinition && currentChild.BaseType.IsGenericType
                                ? currentChild.BaseType.GetGenericTypeDefinition()
                                : currentChild.BaseType;

            if (currentChild == null)
                return false;
        }
        return false;
    }

    private static bool HasAnyInterfaces(Type parent, Type child)
    {
        return child.GetInterfaces().Any(childInterface =>
            {
                var currentInterface = parent.IsGenericTypeDefinition && childInterface.IsGenericType
                    ? childInterface.GetGenericTypeDefinition()
                    : childInterface;

                return currentInterface == parent;
            });

    }

    [Test]
    public void ShouldInheritOrImplementNonGenericInterface()
    {
        Assert.That(typeof(FooImplementor)
            .InheritsOrImplements(typeof(IFooInterface)), Is.True);
    }

    [Test]
    public void ShouldInheritOrImplementGenericInterface()
    {
        Assert.That(typeof(GenericFooBase)
            .InheritsOrImplements(typeof(IGenericFooInterface<>)), Is.True);
    }

    [Test]
    public void ShouldInheritOrImplementGenericInterfaceByGenericSubclass()
    {
        Assert.That(typeof(GenericFooImplementor<>)
            .InheritsOrImplements(typeof(IGenericFooInterface<>)), Is.True);
    }

    [Test]
    public void ShouldInheritOrImplementGenericInterfaceByGenericSubclassNotCaringAboutGenericTypeParameter()
    {
        Assert.That(new GenericFooImplementor<string>().GetType()
            .InheritsOrImplements(typeof(IGenericFooInterface<>)), Is.True);
    }

    [Test]
    public void ShouldNotInheritOrImplementGenericInterfaceByGenericSubclassNotCaringAboutGenericTypeParameter()
    {
        Assert.That(new GenericFooImplementor<string>().GetType()
            .InheritsOrImplements(typeof(IGenericFooInterface<int>)), Is.False);
    }

    [Test]
    public void ShouldInheritOrImplementNonGenericClass()
    {
        Assert.That(typeof(FooImplementor)
            .InheritsOrImplements(typeof(FooBase)), Is.True);
    }

    [Test]
    public void ShouldInheritOrImplementAnyBaseType()
    {
        Assert.That(typeof(GenericFooImplementor<>)
            .InheritsOrImplements(typeof(FooBase)), Is.True);
    }

    [Test]
    public void ShouldInheritOrImplementTypedGenericInterface()
    {
        GenericFooImplementor<int> obj = new GenericFooImplementor<int>();
        Type t = obj.GetType();

        Assert.IsTrue(t.InheritsOrImplements(typeof(IGenericFooInterface<int>)));
        Assert.IsFalse(t.InheritsOrImplements(typeof(IGenericFooInterface<String>)));
    } 

4

লিনক দিয়ে এটি সহজেই করা যায়। এটি এমন কোনও ধরণের সন্ধান করবে যা জেনেরিক বেস শ্রেণীর জেনেরিকবেসটাইপের একটি সাবক্লাস।

    IEnumerable<Type> allTypes = Assembly.GetExecutingAssembly().GetTypes();

    IEnumerable<Type> mySubclasses = allTypes.Where(t => t.BaseType != null 
                                                            && t.BaseType.IsGenericType
                                                            && t.BaseType.GetGenericTypeDefinition() == typeof(GenericBaseType<,>));

এটি আমার জন্য কাজ করা একমাত্র সমাধান ছিল। সহজ এবং মার্জিত। ধন্যবাদ.
সিল্কফায়ার

4

সহজ সমাধান: জেনেরিক শ্রেণিতে কেবল একটি দ্বিতীয়, অ-জেনেরিক ইন্টারফেস তৈরি এবং যুক্ত করুন:

public interface IGenericClass
{
}

public class GenericClass<T> : GenericInterface<T>, IGenericClass
{
}

তারপর শুধু যে কোন ভাবেই আপনি ব্যবহার করতে পছন্দ জন্য চেক is, as, IsAssignableFrom, ইত্যাদি

if (thing is IGenericClass)
{
    // Do work
{

স্পষ্টতই কেবল সম্ভব যদি আপনার জেনেরিক ক্লাসটি সম্পাদন করার ক্ষমতা থাকে (যা ওপি বলে মনে হয়) তবে এটি কোনও ক্রিপ্টিক এক্সটেনশন পদ্ধতি ব্যবহার করার চেয়ে কিছুটা মার্জিত এবং পঠনযোগ্য।


1
যাইহোক, কেবল কিছু টাইপ করা হয়েছে কিনা তা যাচাই করা IGenericClassআপনাকে গ্যারান্টি দেয় না GenericClassবা GenericInterfaceআসলে প্রসারিত বা বাস্তবায়িত করা হয়েছে। এর অর্থ, আপনার সংকলকটি আপনাকে জেনেরিক শ্রেণির কোনও সদস্য অ্যাক্সেস করার অনুমতি দেয় না।
বি 12 টিউস্টার

4

@ জারেদারের উত্তরে যুক্ত হয়েছে, ইন্টারফেসগুলি পরীক্ষা করতে আমি যা ব্যবহার করি তা এখানে:

public static bool IsImplementerOfRawGeneric(this Type type, Type toCheck)
{
    if (toCheck.GetTypeInfo().IsClass)
    {
        return false;
    }

    return type.GetInterfaces().Any(interfaceType =>
    {
        var current = interfaceType.GetTypeInfo().IsGenericType ?
                    interfaceType.GetGenericTypeDefinition() : interfaceType;
        return current == toCheck;
    });
}

public static bool IsSubTypeOfRawGeneric(this Type type, Type toCheck)
{
    return type.IsInterface ?
          IsImplementerOfRawGeneric(type, toCheck)
        : IsSubclassOfRawGeneric(type, toCheck);
}

উদা:

Console.WriteLine(typeof(IList<>).IsSubTypeOfRawGeneric(typeof(IList<int>))); // true

ভাল সংযোজন। আপনি এবং জারেডপার উভয়কে একটি উঁচু পর্ব দিয়েছেন। আমার একমাত্র মন্তব্য হ'ল আপনি এক্সটেনশন পদ্ধতির কারণে প্রকারের অবস্থানটি (জারেডারের উত্তর থেকে) বিপরীত করেছেন। আমি এটিকে একটি এক্সটেনশন পদ্ধতি হিসাবে সরিয়ে দিয়েছি এবং এটি আমাকে কিছুটা ছাড়িয়ে দিয়েছে। আপনার সমস্যা না আমার। কেবলমাত্র পরবর্তী ব্যক্তির মাথা তুলে দিতে চেয়েছিল। আবার ধন্যবাদ.
টনি

@ টনি, টিপটির জন্য ধন্যবাদ তবে পরবর্তী সময় উত্তরটি আপডেট করুন।
জননি 5

@ ওয়েক্সে, পরীক্ষা করা গুরুত্বপূর্ণ যে আপনার আসল উত্তরটি নষ্ট হয়েছে, এটি কেবলমাত্র কাজ করে কারণ আপনি এটি একটি ইন্টারফেসে পরীক্ষা করেছেন। দ্বিতীয়ত, আপনি প্রকার নির্বিশেষে এই ফাংশনটি চালিয়ে প্রক্রিয়াজাতকরণ শক্তি নষ্ট করছেন।
জননি 5

2

JaredPar,

যদি আমি টাইপ (টাইপ <> টাইপ) কে চেক হিসাবে পাস করি তবে এটি আমার পক্ষে কার্যকর হয়নি। আমি যা বদলেছি তা এখানে।

static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
    while (toCheck != typeof(object)) {
        var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
          if (cur.IsGenericType && generic.GetGenericTypeDefinition() == cur.GetGenericTypeDefinition()) {
            return true;
        }
        toCheck = toCheck.BaseType;
    }
    return false;
}

JaredPar এর সমাধান প্রকৃতপক্ষে জন্য কাজ করে typeof(type<>)যেমন toCheck। জেয়ার্ডপাড়ের দ্রবণের মত আপনারও নাল চেকের দরকার আছে। তদুপরি, আমি জানি না যে আপনি কেবল জেনেরিক ধরণের জন্য নিজের পদ্ধতিতে কাজ করতে সীমাবদ্ধ cur == genericনা করে আপনি তার সমাধানটিতে প্রতিস্থাপন করে আর কী অর্জন করছেন cur.IsGenericType && generic.GetGenericTypeDefinition() == cur.GetGenericTypeDefinition()। অন্য কথায়, এর মতো কিছু ব্যতিক্রম ব্যর্থ হয়:IsSubclassOfRawGeneric(typeof(MyClass), typeof(MyClass<>))
নওফাল

2

@ এনোকনআরল - আনন্দ গোপালের উত্তর আকর্ষণীয়, তবে যদি কোনও উদাহরণ আগেই ইনস্ট্যান্ট করা না হয় বা আপনি জেনেরিক ধরণের সংজ্ঞা দিয়ে পরীক্ষা করতে চান তবে আমি এই পদ্ধতির পরামর্শ দেব:

public static bool TypeIs(this Type x, Type d) {
    if(null==d) {
        return false;
    }

    for(var c = x; null!=c; c=c.BaseType) {
        var a = c.GetInterfaces();

        for(var i = a.Length; i-->=0;) {
            var t = i<0 ? c : a[i];

            if(t==d||t.IsGenericType&&t.GetGenericTypeDefinition()==d) {
                return true;
            }
        }
    }

    return false;
}

এবং এটি ব্যবহার করুন:

var b = typeof(char[]).TypeIs(typeof(IList<>)); // true

দুটি শর্তসাপেক্ষ ক্ষেত্রে রয়েছে যখন উভয়ই t(পরীক্ষা করার জন্য) এবং dজেনেরিক ধরণের এবং দুটি ক্ষেত্রে আচ্ছাদিত থাকে t==dযার দ্বারা (1) হয় না tএবং dজেনেরিক সংজ্ঞা হয় না বা (2) উভয়ই জেনেরিক সংজ্ঞা হয় । বাকি মামলা আছে তাদের মধ্যে একজন একটি জেনেরিক সংজ্ঞা নেই, শুধুমাত্র যখন dইতিমধ্যে একটি জেনেরিক সংজ্ঞা আমরা বলতে সুযোগ আছে একটি tএকটি হলd কিন্তু তদ্বিপরীত।

এটি পরীক্ষা করতে চান স্বেচ্ছাসেবী ক্লাস বা ইন্টারফেসের সাথে কাজ করা উচিত, এবং isঅপারেটরের সাথে যেমন টাইপের কোনও উদাহরণ পরীক্ষা করে এমনটি প্রদান করে ।


0
Type _type = myclass.GetType();
PropertyInfo[] _propertyInfos = _type.GetProperties();
Boolean _test = _propertyInfos[0].PropertyType.GetGenericTypeDefinition() 
== typeof(List<>);

0

আপনি এই এক্সটেনশনটি চেষ্টা করতে পারেন

    public static bool IsSubClassOfGenericClass(this Type type, Type genericClass,Type t)
    {
        return type.IsSubclassOf(genericClass.MakeGenericType(new[] { t }));
    }

0

এই সম্পর্কে খেলা দেরি করে ... আমার কাছে জারোডপাড়ের উত্তরের আর একটি অনুমতি আছে।

এখানে Type.IsSubClassOf (প্রকার) প্রতিফলকের সৌজন্যে:

    public virtual bool IsSubclassOf(Type c)
    {
        Type baseType = this;
        if (!(baseType == c))
        {
            while (baseType != null)
            {
                if (baseType == c)
                {
                    return true;
                }
                baseType = baseType.BaseType;
            }
            return false;
        }
        return false;
    }

সেখান থেকে আমরা দেখতে পাচ্ছি যে এটি খুব ক্রে ক্রে কিছুই করছে না এবং জারেডপারের পুনরুক্তি পদ্ধতির অনুরূপ। এ পর্যন্ত সব ঠিকই. এখানে আমার সংস্করণটি (অস্বীকৃতি: পুরোপুরি পরীক্ষা করা হয়নি, তাই সমস্যাগুলি খুঁজে পেলে লেমে জানুন)

    public static bool IsExtension(this Type thisType, Type potentialSuperType)
    {
        //
        // protect ya neck
        //
        if (thisType == null || potentialSuperType == null || thisType == potentialSuperType) return false;

        //
        // don't need to traverse inheritance for interface extension, so check/do these first
        //
        if (potentialSuperType.IsInterface)
        {
            foreach (var interfaceType in thisType.GetInterfaces())
            {
                var tempType = interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType;

                if (tempType == potentialSuperType)
                {
                    return true;
                }
            }
        }

        //
        // do the concrete type checks, iterating up the inheritance chain, as in orignal
        //
        while (thisType != null && thisType != typeof(object))
        {
            var cur = thisType.IsGenericType ? thisType.GetGenericTypeDefinition() : thisType;

            if (potentialSuperType == cur)
            {
                return true;
            }

            thisType = thisType.BaseType;
        }
        return false;
    }

মূলত এটি সিস্টেমে কেবলমাত্র একটি এক্সটেনশন পদ্ধতি ype টাইপ - আমি ইচ্ছাকৃতভাবে "এই টাইপ" টাইপটি কংক্রিট প্রকারের মধ্যে সীমাবদ্ধ করতেই করেছি, কারণ আমার তাত্ক্ষণিক ব্যবহারটি লিনকিউ ক্যোয়ারিতে "যেখানে" টাইপ অবজেক্টগুলির বিরুদ্ধে ভবিষ্যদ্বাণী করে। আমি নিশ্চিত যে আপনার সমস্ত স্মার্ট লোকেরা যদি এটির প্রয়োজন হয় তবে এটি একটি দক্ষ, সর্ব-উদ্দেশ্যমূলক স্থিতিশীল পদ্ধতিতে ঠেলাঠেলি করতে পারে :) কোডটি কয়েকটি কাজ করে যা উত্তরটির কোড না করে

  1. এটি সাধারণ "এক্সটেনশান" পর্যন্ত খোলা আছে - আমি উত্তরাধিকার (থিং ক্লাস) পাশাপাশি বাস্তবায়ন (ইন্টারফেস) বিবেচনা করছি; এটি আরও ভালভাবে প্রতিফলিত করার জন্য পদ্ধতি এবং পরামিতিগুলির নামগুলি পরিবর্তন করা হয়েছে
  2. ইনপুট নাল-বৈধকরণ (মেঃ)
  3. একই ধরণের ইনপুট (কোনও শ্রেণি নিজেকে প্রসারিত করতে পারে না)
  4. শর্ট সার্কিট এক্সিকিউশন যদি প্রশ্নে টাইপ হয় একটি ইন্টারফেস; কারণ getInterfaces () সমস্ত প্রয়োগকৃত ইন্টারফেস (এমনকি উচ্চ-শ্রেণিতে প্রয়োগ করা হয়) প্রদান করে, আপনি উত্তরাধিকার গাছটিতে আরোহণ না করে কেবল সেই সংগ্রহের মধ্য দিয়ে লুপ করতে পারেন you

বাকিটি মূলত জারেডপার কোডের মতো

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.