কোনও প্রকারের উপপ্রকার বা কোনও বস্তুর প্রকার কিনা তা আমি কীভাবে পরীক্ষা করব?


335

কোনও প্রকারটি সি # তে অন্য ধরণের একটি সাবক্লাস কিনা তা পরীক্ষা করতে এটি সহজ:

typeof (SubClass).IsSubclassOf(typeof (BaseClass)); // returns true

তবে এটি ব্যর্থ হবে:

typeof (BaseClass).IsSubclassOf(typeof (BaseClass)); // returns false

কোনও প্রকার ORঅপারেটর ব্যবহার না করে বা একটি এক্সটেনশন পদ্ধতি ব্যবহার না করে, কোনও ধরণের হয় বেস ক্লাসের নিজেই একটি সাবক্লাস OR কিনা তা যাচাই করার কোনও উপায় আছে কি ?

উত্তর:


499

স্পষ্টতই, না।

এখানে বিকল্পগুলি:

Type.IsSubclassOf

আপনি ইতিমধ্যে খুঁজে পেয়েছেন যে, দুটি ধরণের একই রকম হলে এটি কাজ করবে না, এখানে একটি নমুনা লিনকিপ্যাড প্রোগ্রাম রয়েছে যা দেখায়:

void Main()
{
    typeof(Derived).IsSubclassOf(typeof(Base)).Dump();
    typeof(Base).IsSubclassOf(typeof(Base)).Dump();
}

public class Base { }
public class Derived : Base { }

আউটপুট:

True
False

যা ইঙ্গিত করে যে Derivedএটি একটি সাবক্লাস Base, তবে এটি Base(স্পষ্টতই) নিজের একটি সাবক্লাস নয়।

Type.IsAssignableFrom

এখন, এটি আপনার নির্দিষ্ট প্রশ্নের উত্তর দেবে, তবে এটি আপনাকে মিথ্যা ধনাত্মকতাও দেবে। যেমন এরিক লিপার্ট মন্তব্যগুলিতে উল্লেখ করেছেন, যদিও পদ্ধতিটি সত্যই Trueউপরোক্ত দুটি প্রশ্নের Trueজন্য ফিরে আসবে, এটি এগুলির জন্যও ফিরে আসবে , যা আপনি সম্ভবত চান না:

void Main()
{
    typeof(Base).IsAssignableFrom(typeof(Derived)).Dump();
    typeof(Base).IsAssignableFrom(typeof(Base)).Dump();
    typeof(int[]).IsAssignableFrom(typeof(uint[])).Dump();
}

public class Base { }
public class Derived : Base { }

এখানে আপনি নিম্নলিখিত আউটপুট পাবেন:

True
True
True

সেখানে সর্বশেষটি Trueনির্দেশ করে যে, যদি পদ্ধতিটি কেবলমাত্র জিজ্ঞাসিত প্রশ্নের উত্তর দেয়, যা uint[]উত্তরাধিকার সূত্রে প্রাপ্ত হয় int[]বা তারা একই ধরণের হয়, যা স্পষ্টভাবে ঘটনাটি নয়।

সুতরাং IsAssignableFromপুরোপুরি সঠিক নয়।

is এবং as

আপনার প্রশ্নের সাথে isএবং asপ্রসঙ্গে "সমস্যা" হ'ল এগুলি আপনাকে অবজেক্টগুলিতে পরিচালনা করতে এবং কোনও কোডে সরাসরি কোডে লিখতে হবে এবং Typeঅবজেক্টগুলির সাথে কাজ করবে না ।

অন্য কথায়, এটি সংকলন করবে না:

SubClass is BaseClass
^--+---^
   |
   +-- need object reference here

না এটি হবে:

typeof(SubClass) is typeof(BaseClass)
                    ^-------+-------^
                            |
                            +-- need type name here, not Type object

না এটি হবে:

typeof(SubClass) is BaseClass
^------+-------^
       |
       +-- this returns a Type object, And "System.Type" does not
           inherit from BaseClass

উপসংহার

উপরের পদ্ধতিগুলি আপনার প্রয়োজনের সাথে মাপসই হতে পারে তবে আপনার প্রশ্নের একমাত্র সঠিক উত্তর (যেমনটি আমি দেখছি) হ'ল আপনার অতিরিক্ত চেক লাগবে:

typeof(Derived).IsSubclassOf(typeof(Base)) || typeof(Derived) == typeof(Base);

অবশ্যই কোন পদ্ধতিতে আরও বোধগম্য হয়:

public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
    return potentialDescendant.IsSubclassOf(potentialBase)
           || potentialDescendant == potentialBase;
}

2
ধন্যবাদ! আমি এটিকে সঠিক উত্তর হিসাবে চিহ্নিত করব (আরও 8 মিনিট অপেক্ষা করতে হবে) যেহেতু আপনি উল্লেখ করেছেন যে চেকটি বিপরীত করতে হবে এবং এমএসডিএন ডকুমেন্টেশনের লিঙ্ক সরবরাহ করতে হবে।
ড্যানিয়েল টি।

71
মনে রাখবেন যে এটি আসলে প্রশ্নটি যা করতে চেয়েছিল তা করে না; এটি নির্ধারণ করে না যে এক প্রকারটি অন্যের উপশ্রেণী কিনা, বরং এক প্রকারের সাথে অন্যর সাথে সামঞ্জস্যপূর্ণ কিনা। ইউিন্টের একটি অ্যারে কোনও পূর্বশ্রেণীর একটি সাবক্লাস নয়, তবে তারা অ্যাসাইনমেন্টের সাথে সামঞ্জস্যপূর্ণ। আইউনামেবল <জিরাফ> আইনিউবারেবল <অ্যানিমাল> এর একটি সাবক্লাস নয়, তবে সেগুলি ভি 4 এর সাথে সামঞ্জস্যপূর্ণ assign
এরিক লিপার্ট

জাভা এর মতো পদ্ধতির নামে এটি করার কোনও উপায় নেই? oid `` শূন্য <? বেস প্রসারিত করুন> সেভওবজেক্ট (? অবজেক্টটোসভ) `` `
অলিভার ডিকসন

2
কিভাবে এই IsInstanceOfTypeমাপসই করা হবে ?
লেনার্ট

আইসেমআরসব্লাক্লাসকে একটি এক্সটেনশন পদ্ধতিতে রূপান্তরিত করার জন্য এটি লোভনীয় হতে পারে তবে আমি এর বিপরীতে সুপারিশ করছি এটি পড়তে এবং লিখতে কিছুটা বিশ্রী হয়, এবং গণ্ডগোলের পক্ষে সহজ হয় (সম্ভাব্যতা এবং সম্ভাব্য ডিজাইনটির ক্রমটি বিপরীত করা মারাত্মক হতে পারে)।
জুন



1

যদি আপনি এটি একটি Xamarin ফর্ম পিসিএল প্রকল্পে করার চেষ্টা করছেন, উপরোক্ত সমাধানগুলি ব্যবহার IsAssignableFromকরে একটি ত্রুটি দেয়:

ত্রুটি: 'টাইপ' তে 'ইসএসাইনএবলফ্রোম' এর সংজ্ঞা নেই এবং কোনও প্রসারণ পদ্ধতি 'আইএসএইসনেবলফ্রম' টাইপ 'টাইপ' টাইপের প্রথম আর্গুমেন্ট গ্রহণ করা যায়নি (আপনি কি কোনও নির্দেশিকা বা কোনও সমাবেশের উল্লেখ ব্যবহার করে নিখোঁজ রয়েছেন?)

কারণ IsAssignableFromএকটি TypeInfoবিষয় জিজ্ঞাসা । আপনি এই GetTypeInfo()পদ্ধতিটি ব্যবহার করতে পারেন System.Reflection:

typeof(BaseClass).GetTypeInfo().IsAssignableFrom(typeof(unknownType).GetTypeInfo())


0

কারও সাথে আমার ভাগ করে নেওয়ার আশা নিয়ে এই উত্তরটি পোস্ট করছি এবং কেন এটি খারাপ ধারণা হবে। আমার আবেদনে আমার কাছে টাইপের একটি সম্পত্তি রয়েছে যা আমি এটি টাইপফ (এ) বা টাইপফ (বি) কিনা তা পরীক্ষা করে দেখতে চাই, যেখানে বি এ থেকে প্রাপ্ত কোনও শ্রেণি, তাই আমার কোড:

public class A
{
}

public class B : A
{
}

public class MyClass
{
    private Type _helperType;
    public Type HelperType
    {
        get { return _helperType; }
        set 
        {
            var testInstance = (A)Activator.CreateInstance(value);
            if (testInstance==null)
                throw new InvalidCastException("HelperType must be derived from A");
            _helperType = value;
        }
    }
}

আমি মনে করি আমি এখানে কিছুটা নির্বোধ হতে পারি তাই কোনও মতামত স্বাগত হবে।


2
এই ধারণার সাথে বেশ কয়েকটি সমস্যা রয়েছে: 1) এই ধরণের একটি প্যারামিটারলেস কনস্ট্রাক্টর প্রয়োজন বা ক্রিয়েটইনস্ট্যান্স ব্যর্থ হবে; 2) Aালাই (ক) বাতিল করা যায় না যদি castালাই তৈরি করা না যায় তবে তা ছোঁড়ে; 3) আপনার আসলে নতুন উদাহরণের প্রয়োজন নেই, সুতরাং আপনার অকেজো বরাদ্দ রয়েছে। গৃহীত উত্তর ভাল (যদিও নিখুঁত না)।
মার্সেল পোপেস্কু

সাহায্য করার জন্য ধন্যবাদ. খুব উপকারী.
বাস্করেন

@ বাস্ক্রেন, সম্ভবত তখনই তাঁর সহায়ক মন্তব্যটিকে উপস্থাপন করুন। আমি # 1 upvote ছিল।
বিকাশকারী 63
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.