কোনও বস্তু আক্ষরিক হয় কিনা তা কীভাবে পরীক্ষা করবেন?


202

নীচের পদ্ধতিটি কীভাবে প্রয়োগ করা যায় তা অন্য শব্দগুলিতে কোনও প্রদত্ত বস্তুটি অবিয়োগযোগ্য কিনা তা আমি কীভাবে চেক করব ...

bool IsNullableValueType(object o)
{
    ...
}

সম্পাদনা: আমি মূল্যহীন মান ধরণের খুঁজছি আমার মনে রেফ টাইপ ছিল না।

//Note: This is just a sample. The code has been simplified 
//to fit in a post.

public class BoolContainer
{
    bool? myBool = true;
}

var bc = new BoolContainer();

const BindingFlags bindingFlags = BindingFlags.Public
                        | BindingFlags.NonPublic
                        | BindingFlags.Instance
                        ;


object obj;
object o = (object)bc;

foreach (var fieldInfo in o.GetType().GetFields(bindingFlags))
{
    obj = (object)fieldInfo.GetValue(o);
}

আপত্তি এখন সমান মান সহ টাইপের bool( System.Boolean) প্রবন্ধকে বোঝায়true । আমি যা চেয়েছিলাম তা হ'ল টাইপের একটি অবজেক্টNullable<bool>

সুতরাং এখন চারপাশের কাজ হিসাবে আমি সিদ্ধান্ত নিয়েছি যে ও হ'ল আবেগযোগ্য কিনা তা পরীক্ষা করে নিন এবং উদ্দেশ্যটির চারপাশে একটি নমনীয় মোড়ক তৈরি করুন।


কোডটিতে স্ট্রিংগুলি যুক্তযোগ্য হিসাবে অন্তর্ভুক্ত করা উচিত? এগুলি একটি নন-জেনেরিক মান টাইপ যা এটিকে অযোগ্য বলে মনে হচ্ছে। না এগুলি কি ভ্যালু টাইপ নয়?
টামুসজেয়েস 21

স্ট্রিং কোনও ভ্যালু টাইপ নয়। এটি একটি রেফারেন্স টাইপ।
সানকাট 2000

এই সত্যিই একটি ভাল প্রশ্ন! 'Type.IsNullableType ()' ধরণের প্রতারণাপূর্ণ কারণ এটি কেবলমাত্র 'নুলাবল <T>' প্রকারের জন্য যাচাই করে, যা আপনি যদি এমন কোনও প্রকারের জন্য যাচাই করতে চান তবে প্রত্যাশিত ফলাফল প্রত্যাবর্তন করে না যা কোনও নাল গ্রহণ করতে পারে মান (উদাহরণস্বরূপ, আমি a.IsNullableType () দিয়ে ব্যবহারের চেষ্টা করেছি, যেখানে 'a' একটি 'টাইপফ (স্ট্রিং)' ছিল রানটাইমের সময় নির্ধারিত)
এররকোড

উত্তর ফিল্ডইনফো.ফিল্ড টাইপ: ফিল্ডটাইপ জেনেরিক এবং জেনেরিক টাইপ নুলাবাল <> টাইপের কিনা তা পরীক্ষা করে দেখুন। (উদাহরণ: যদি (FieldType.IsGenericType && FieldType.GetGenericTypeDefinition () == typof (nullable <>)))। আপত্তি পাওয়ার চেষ্টা করবেন না। গেটটাইপ () এতে নুলাবল <T> ভেরিয়েবল টি (আপনার বুলিয়ান প্রকারের ক্ষেত্রে নুলযোগ্য <বুলেটিয়ান> এর পরিবর্তে) এর আনডিলিংস সিস্টেমটাইপ থাকবে, এটি বক্সিংয়ের সমস্যা।
SoLaR

উত্তর:


271

দুটি ধরণের নালাই - Nullable<T>এবং রেফারেন্স-প্রকার।

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

static bool IsNullable<T>(T obj)
{
    if (obj == null) return true; // obvious
    Type type = typeof(T);
    if (!type.IsValueType) return true; // ref-type
    if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T>
    return false; // value-type
}

আপনি যদি ইতিমধ্যে কোনও বস্তুর ভেরিয়েবলের মান বাক্স করে রেখেছেন তবে এটি এত ভাল কাজ করবে না।

মাইক্রোসফ্ট ডকুমেন্টেশন: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/nullable-tyype/how-to-uthorfy-a-nlalable-type


7
শেষ লাইনটি কেবলমাত্র বৈধ যদি আপনি কোনওভাবে সরাসরি টি-তে বক্সিং করার পরিবর্তে কোনও বক্সযুক্ত নল <<< টাকে পরিচালনা করতে পারেন manage এটি সম্ভব তবে আমার মনে আছে যা থেকে অর্জন করা কঠিন।
জন স্কিটি

এই কোডটি আমার পক্ষে সহায়ক ছিল, কারণ আমি একটি বক্সযুক্ত নুলাবল <T> পেয়েছিলাম না কারণ আমি জেনেরিক ডাব্লুএফএফ রূপান্তরকারী বেস শ্রেণি লিখছিলাম এবং কিছু বৈশিষ্ট্য নলযোগ্য তাই আমি কেসটি এবং অ্যাক্টিভেটরটি সনাক্ত করতে নলবল।গেটউন্ডারিলিং টাইপটি ব্যবহার করেছি re একটি বাক্সযুক্ত নলযোগ্য, (রূপান্তর করুন han চেঞ্জটাইপটি বিটিডাব্লু nullables পরিচালনা করে না)।
কিওয়ারটি

1
@ আবেল যদি আপনি তার সম্পাদনাটি বোঝাতে চান তবে তিনি স্পষ্ট করে জানান যে তিনি রেফারেন্সের ধরণগুলি বিবেচনা করেন নি, আমার ধারণা আমার উত্তরটি সম্পাদনার পূর্বাভাস করেছিল; পাঠক তাদের নিজস্ব প্রয়োজনের ভিত্তিতে সেখানে তাদের নিজস্ব সিদ্ধান্ত নিতে পারেন, আমি সন্দেহ করি (নিশ্চিত: তার মন্তব্য পুনরায় টাইপ করা হয়েছে 14:42-এ যুক্ত হিসাবে; আমার উত্তরটি সব ছিল <= 14:34)
মার্ক গ্র্যাভেল

1
আপত্তি = 1 হলে (আপত্তি == নাল) একটি ব্যতিক্রম ছুঁড়ে দেবে?
কিউ ফ্যান

3
@ জাস্টিনমর্গান যদি Tজেনেরিক প্যারামিটার দ্বারা আবদ্ধ থাকে T : structতবে Tতা হতে দেওয়া হয় না Nullable<>, সুতরাং আপনার সেই ক্ষেত্রে কোনও চেক দরকার নেই! আমি জানি টাইপটি Nullable<>একটি স্ট্রাক্ট, তবে সি # তে সীমাবদ্ধভাবে where T : structবিশেষভাবে মূল্যহীন মান-প্রকারগুলি বাদ দেয়। অনুমানটি
জেপ্প স্টিগ নীলসন

46

পদ্ধতি ওভারলোডগুলি ব্যবহার করে খুব সহজ সমাধান রয়েছে

http://deanchalk.com/is-it-nullable/

উদ্ধৃতাংশ:

public static class ValueTypeHelper
{
    public static bool IsNullable<T>(T t) { return false; }
    public static bool IsNullable<T>(T? t) where T : struct { return true; }
}

তারপর

static void Main(string[] args)
{
    int a = 123;
    int? b = null;
    object c = new object();
    object d = null;
    int? e = 456;
    var f = (int?)789;
    bool result1 = ValueTypeHelper.IsNullable(a); // false
    bool result2 = ValueTypeHelper.IsNullable(b); // true
    bool result3 = ValueTypeHelper.IsNullable(c); // false
    bool result4 = ValueTypeHelper.IsNullable(d); // false
    bool result5 = ValueTypeHelper.IsNullable(e); // true
    bool result6 = ValueTypeHelper.IsNullable(f); // true

7
পরীক্ষার কেস যুক্ত করার জন্য আপনার জন্য স্যার আরও একটি। অন্যান্য পরীক্ষাগুলি উত্তর যাচাই করার জন্য আমি সেই পরীক্ষার কেসগুলি ব্যবহার করেছি। আরও বেশি লোকের এই অতিরিক্ত কিছুটা যাওয়া উচিত।
মার্টি নিল

4
এর মূল্য কী, এটি VB.NET এ কাজ করে না। এটি " ওভারলোড রেজোলিউশন ব্যর্থ হয়েছে কারণ কোনও পরিস্থিতিতে অ্যাক্সেসযোগ্য 'ইসনুল্যাবল' এই যুক্তিগুলির পক্ষে সুনির্দিষ্ট নয়" যেখানে সমস্ত পরিস্থিতিতে Trueফিরে আসবে তার সংকলক ত্রুটির ফলস্বরূপ
ckittel

1
আমি এই সমাধানটি সত্যিই পছন্দ করি - এবং এটি লজ্জার বিষয় যে ভিবি এটি পরিচালনা করতে পারে না। আমি ভ্যালু টাইপ নিয়ে কাজ করার চেষ্টা করেছি কিন্তু ভিবি সংকলকটি কোনটি ওভারলোডকে কোনও শেয়ারড পদ্ধতি বা একটি এক্সটেনশন হিসাবে ডাকা হয়েছিল তার ভিত্তিতে ব্যবহার করতে হবে সে সম্পর্কে বেমানান না হয়ে সমস্যায় পড়েছি, এমনকি এটিকে অদ্ভুত বলে মনে হওয়ায় আমি এ সম্পর্কে একটি প্রশ্নও উত্থাপন করেছি: stackoverflow.com/ প্রশ্নগুলি / 12319591 /…
জেমস বন্ধ করুন

22
আপনি সংকলন-সময় প্রকারটি যাচাই করছেন , তবে সংকলন-সময় প্রকারটি ( System.Nullable<>) অদৃশ্য হলে এটি ইতিমধ্যে স্পষ্ট (ইন্টেলিজেন্স থেকে )। আপনি যদি বলেন object g = e;এবং তারপরে ValueTypeHelper.IsNullable(g), আপনি কী পাওয়ার আশা করছেন?
জেপ্প স্টিগ নীলসন

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

30

"কোনও প্রকারটি উত্তরযোগ্য কিনা তা কীভাবে পরীক্ষা করবেন?" আসলে "টাইপটি কীভাবে তা পরীক্ষা করতে হয় Nullable<>?", যা "টাইপটি কিছু জেনেরিক ধরণের তৈরির ধরণ কিনা তা কীভাবে পরীক্ষা করতে হয় ?" তে সাধারণীকরণ করা যেতে পারে, যাতে এটি কেবল "এটি Nullable<int>একটি Nullable<>?" প্রশ্নের উত্তর দেয় না , তবে "কি List<int>একটি List<>?"।

প্রদত্ত সমাধানগুলির বেশিরভাগটি Nullable.GetUnderlyingType()পদ্ধতিটি ব্যবহার করে যা স্পষ্টতই কেবলমাত্র এর ক্ষেত্রে কাজ করবে Nullable<>। আমি সাধারণ প্রতিফলনমূলক সমাধানটি দেখতে পাই নি যা কোনও জেনেরিক প্রকারের সাথে কাজ করবে, তাই আমি উত্তরসূরির জন্য এটি এখানে যুক্ত করার সিদ্ধান্ত নিয়েছি, যদিও এই প্রশ্নের উত্তর অনেক আগেই দেওয়া হয়ে গেছে।

কোনও ধরণের Nullable<>প্রতিবিম্ব ব্যবহারের কিছু রূপ কিনা তা পরীক্ষা করতে আপনাকে প্রথমে আপনার নির্মিত জেনেরিক প্রকারকে রূপান্তর করতে হবে, উদাহরণস্বরূপ Nullable<int>, জেনেরিক টাইপ সংজ্ঞায় Nullable<>,। আপনি ক্লাসের GetGenericTypeDefinition()পদ্ধতিটি ব্যবহার করে এটি করতে পারেন Type। তারপরে আপনি ফলাফলের সাথে তুলনা করতে পারেন Nullable<>:

Type typeToTest = typeof(Nullable<int>);
bool isNullable = typeToTest.GetGenericTypeDefinition() == typeof(Nullable<>);
// isNullable == true

একই যে কোনও জেনেরিক প্রকারে প্রয়োগ করা যেতে পারে:

Type typeToTest = typeof(List<int>);
bool isList = typeToTest.GetGenericTypeDefinition() == typeof(List<>);
// isList == true

বেশ কয়েকটি প্রকার একই রকম মনে হতে পারে তবে বিভিন্ন ধরণের আর্গুমেন্টের অর্থ এটি সম্পূর্ণ ভিন্ন ধরণের।

Type typeToTest = typeof(Action<DateTime, float>);
bool isAction1 = typeToTest.GetGenericTypeDefinition() == typeof(Action<>);
bool isAction2 = typeToTest.GetGenericTypeDefinition() == typeof(Action<,>);
bool isAction3 = typeToTest.GetGenericTypeDefinition() == typeof(Action<,,>);
// isAction1 == false
// isAction2 == true
// isAction3 == false

যেহেতু Typeবস্তু প্রতি টাইপ একবারে ইনস্ট্যান্ট করা হয়, আপনি তাদের মধ্যে রেফারেন্স সমতার জন্য পরীক্ষা করতে পারেন। সুতরাং আপনি যদি দুটি বস্তু একই জেনেরিক ধরণের সংজ্ঞার কিনা তা পরীক্ষা করতে চান তবে আপনি লিখতে পারেন:

var listOfInts = new List<int>();
var listOfStrings = new List<string>();

bool areSameGenericType =
    listOfInts.GetType().GetGenericTypeDefinition() ==
    listOfStrings.GetType().GetGenericTypeDefinition();
// areSameGenericType == true

যদি আপনি যাচাই করতে চান যে কোনও বস্তুর পরিবর্তে অণুগঠনযোগ্য কিনা Type, তবে আপনি মারক গ্র্যাভেলের সমাধানের সাথে উপরের কৌশলটি একসাথে একটি সহজ পদ্ধতি তৈরি করতে ব্যবহার করতে পারেন:

static bool IsNullable<T>(T obj)
{
    if (!typeof(T).IsGenericType)
        return false;

    return typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>);
}

@ অ্যালনগুরালেনেক আমার উত্তরে সরলিকৃত সংস্করণটি এখানে আছে। আমি এটিকে সম্পাদনা হিসাবে তৈরি করতে চেয়েছিলাম এবং যেহেতু আমার খ্যাতিটি আপনার স্তর নয়, এটি আপনার উত্তর ছাড়া আমার নাম ছাড়া এটি সম্পাদনা করা হবে, তবুও, মনে হয় পর্যালোচনাটি সর্বদা আমার পায়ে গুলি করছে, এটি লেখককে আদর করে দিচ্ছে এমনকি যদি না. আজব বিশ্ব, কিছু লোক সংজ্ঞা পায় না :) :)
আইপাবলু

@ আইপাবলু: আপনার সংস্করণটি সরলীকৃত নয়, বাস্তবে এটি আরও জটিল। আমি মনে করি আপনি যে ফলাফলটি ক্যাশে করেছেন সেহেতু আপনার অর্থ এটি অনুকূলিত। এটি বুঝতে আরও কঠিন করে তোলে।
অ্যালন গুরালেনেক

@ অ্যালনগুরালেনেক স্ট্যাটিক জেনেরিক ক্লাস এবং স্ট্যাটিক ওয়ান টাইম ইনিশিয়াল্ড ফিল্ডস, জটিল? প্রিয় ,শ্বর, আমি ভয়ানক অপরাধ করেছি :)।
ipavlu

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

1
@ নওফাল: যদি আমি আপনাকে সঠিকভাবে বুঝতে পারি Nullable.GetUnderlyingType()তবে ইতিমধ্যে কাঠামোর দ্বারা সরবরাহিত অস্তিত্বের মুখোমুখি আপনি আমার বাস্তবায়নের সন্ধান করছেন । শুধু কাঠামোয় পদ্ধতিটি ব্যবহার করবেন না কেন? ঠিক আছে, আপনার উচিত। এটি পরিষ্কার, আরও সংক্ষিপ্ত এবং আরও ভাল পরীক্ষিত। তবে আমার পোস্টে আমি কীভাবে আপনার পছন্দসই তথ্য পেতে প্রতিবিম্বটি ব্যবহার করতে হয় তা শেখানোর চেষ্টা করছি, যাতে কেউ এটিকে যে কোনও প্রকারে প্রয়োগ করতে পারেন ( typeof(Nullable<>)অন্য কোনও ধরণের পরিবর্তে )। যদি আপনি GetUnderlyingType()(মূল বা সংক্রামিত) উত্সগুলি দেখুন তবে আপনি দেখতে পাবেন এটি আমার কোডের সাথে খুব মিল similar
অ্যালন গুরালেনেক

30

এটি আমার পক্ষে কাজ করে এবং সহজ বলে মনে হচ্ছে:

static bool IsNullable<T>(T obj)
{
    return default(T) == null;
}

মান ধরণের জন্য:

static bool IsNullableValueType<T>(T obj)
{
    return default(T) == null && typeof(T).BaseType != null && "ValueType".Equals(typeof(T).BaseType.Name);
}


1
ভাল ... এটি শীর্ষ উত্তর কারণ পরে এসেছিল না? আমি উপরের উত্তরটি এত বিভ্রান্ত মনে করি।
ভিনসেন্ট বাসকারেলো

1
এটি শীর্ষ উত্তর হওয়া উচিত। বিভিন্ন পদ্ধতির চেষ্টা করার কয়েক দিন পরে আমি এলোমেলোভাবে এই সমাধানটি নিয়ে ভাবলাম, চেষ্টা করেছি এবং এটি পুরোপুরি কাজ করছে বলে মনে হচ্ছে (শীর্ষ-উত্তরের উত্তরের তুলনায়)
ইউজার 3163495

2
কোনও উদাহরণ নালায় সেট করা যায় কিনা তা অনুসন্ধান করার জন্য এটি একটি দুর্দান্ত সমাধান, তবে সাধারণ বস্তুগুলি সহ নালায় সেট করা যায় এমন সমস্ত কিছুর জন্য এটি সত্য হয়ে উঠবে । এটি উপলব্ধি করা গুরুত্বপূর্ণ যে মূল প্রশ্নটি বিশেষত নুলযোগ্য মান টিপস সনাক্ত করতে চেয়েছিল।
জেমসহক্স

20

ভাল, আপনি ব্যবহার করতে পারেন:

return !(o is ValueType);

... তবে কোনও বস্তু নিজেই আড়ালযোগ্য নয় অন্যথায় - একটি প্রকার । আপনি কীভাবে এটি ব্যবহারের পরিকল্পনা করছেন?


2
এটি আমাকে কিছুটা ফেলে দিয়েছে। যেমন int? i = 5; টাইপফ (i) সিস্টেমকে ফিরে দেয় N
গিশু

2
typof (i) একটি সংকলক ত্রুটি দেবে- আপনি একটি ভেরিয়েবলের সাথে টাইপফ ব্যবহার করতে পারবেন না। আসলে আপনি কি করলেন?
জন স্কিটি

15
i.GETType () প্রথমে অবজেক্টে বক্স করবে এবং একটি বক্সযুক্ত নাল টাইপের মতো কোনও জিনিস নেই - নুলাবাল <int> একটি নাল রেফারেন্স বা একটি বক্সযুক্ত ইন্টার-তে বক্সযুক্ত হয়ে যায়।
জন স্কিটি

নুলবলের চেয়ে সেই পথটি ভাল et
কিকিনেট

@Kiquenet: আমরা না আছে টাইপ এখানে - শুধু মান।
জন স্কিটি

11

আমি যে সহজ উপায়টি বের করতে পারি তা হ'ল:

public bool IsNullable(object obj)
{
    Type t = obj.GetType();
    return t.IsGenericType 
        && t.GetGenericTypeDefinition() == typeof(Nullable<>);
}

+1 টি। বক্সযুক্ত নাল-সক্ষম প্রকারের জন্য দুর্দান্ত সমাধান। আমি এখনও এটি বিশেষভাবে পরীক্ষা করিনি। সুতরাং অন্য কেউ যদি যাচাই করতে পারেন তবে তা প্রশংসিত হবে।
তমুসজেরোয়েস 21

আমি ইতিমধ্যে এটি পরীক্ষা করেছি। আমাকে এক ধরণের Nullableটাইপ তৈরি করতে হয়েছিল , তবে বিভিন্ন শব্দার্থতত্ত্ব দিয়ে। আমার পরিস্থিতিতে আমার উচিত nullএকটি বৈধ মান হিসাবে সমর্থন করা এবং কোনও মূল্যকে মোটেই সমর্থন করা উচিত । সুতরাং একটি Optionalটাইপ তৈরি । যেমন nullমানগুলির সমর্থন করা প্রয়োজন ছিল , তাই Nullableআমার প্রয়োগের অংশ হিসাবে আমাকে মানগুলি পরিচালনা করার কোডও প্রয়োগ করতে হয়েছিল। এই কোডটি এখান থেকে এসেছে।
কার্লস অনেক

9
আমি মনে করি এই সমাধানটি ভুল। টাইপ অবজেক্টের প্যারামিটারের প্রত্যাশা করে এমন পদ্ধতির আর্গুমেন্ট হিসাবে নুলযোগ্য মান ধরণটি পাস করার ফলে বক্সিং হওয়া উচিত। নুলযোগ্য একটি মানের ধরণ এবং বক্সিং রূপান্তরটির ফলাফল একটি রেফারেন্স টাইপ। কোনও বাক্সযুক্ত নল নেই। আমি বিশ্বাস করি এই পদ্ধতিটি কি সবসময় মিথ্যা প্রত্যাবর্তন করে?
মিশাক্স

1
এটি সম্পর্কে কোন উত্তর অন্য উত্তর মত?
কিকিনেট

5
বক্সিং মানের কারণে এটি কাজ করে না। এটি সর্বদা মিথ্যা প্রত্যাবর্তন করবে।
এন দোলনা 16

10

এখানে দুটি সমস্যা রয়েছে: 1) কোনও প্রকারটি অযোগ্য কিনা তা পরীক্ষা করা; এবং 2) কোনও বস্তু nallaable প্রকার প্রতিনিধিত্ব করে কিনা তা পরীক্ষা করে দেখুন।

ইস্যু 1 (একটি ধরণের পরীক্ষার জন্য) এর জন্য, আমি নিজের সিস্টেমে ব্যবহার করেছি এমন একটি সমাধান এখানে দেওয়া হয়েছে: TypeIsNullaable-check সমাধান

ইস্যু 2 (কোনও অবজেক্টের পরীক্ষার জন্য), উপরে ডিন চকের সমাধানটি মান ধরণের জন্য কাজ করে, তবে এটি রেফারেন্স ধরণের জন্য কাজ করে না, কারণ <T> ওভারলোড সর্বদা মিথ্যা প্রত্যাবর্তন করে। যেহেতু রেফারেন্সের প্রকারগুলি অন্তর্নিহিতভাবে আবদ্ধ হয়, একটি রেফারেন্স ধরণের পরীক্ষা করা সর্বদা সত্য হওয়া উচিত। এই শব্দার্থবিজ্ঞানের ব্যাখ্যার জন্য দয়া করে নীচের নোটটি ["ন্যূনযোগ্যতা"] দেখুন। সুতরাং, এখানে আমার ডিনের পদ্ধতির পরিবর্তন হয়েছে:

    public static bool IsObjectNullable<T>(T obj)
    {
        // If the parameter-Type is a reference type, or if the parameter is null, then the object is always nullable
        if (!typeof(T).IsValueType || obj == null)
            return true;

        // Since the object passed is a ValueType, and it is not null, it cannot be a nullable object
        return false; 
    }

    public static bool IsObjectNullable<T>(T? obj) where T : struct
    {
        // Always return true, since the object-type passed is guaranteed by the compiler to always be nullable
        return true;
    }

এবং উপরের সমাধানের জন্য ক্লায়েন্ট-পরীক্ষার কোডটিতে আমার পরিবর্তনটি এখানে রয়েছে:

    int a = 123;
    int? b = null;
    object c = new object();
    object d = null;
    int? e = 456;
    var f = (int?)789;
    string g = "something";

    bool isnullable = IsObjectNullable(a); // false 
    isnullable = IsObjectNullable(b); // true 
    isnullable = IsObjectNullable(c); // true 
    isnullable = IsObjectNullable(d); // true 
    isnullable = IsObjectNullable(e); // true 
    isnullable = IsObjectNullable(f); // true 
    isnullable = IsObjectNullable(g); // true

আইসোবজেক্টনুলাল <টি> (টি টি) তে আমি ডিনের পদ্ধতির পরিবর্তন করেছি কারণ তার আসল পদ্ধতির জন্য সবসময়ই কোনও রেফারেন্স টাইপের জন্য মিথ্যা ফিরে আসে। যেহেতু আইসোবজেক্টনুলের মতো কোনও পদ্ধতিতে রেফারেন্স-ধরণের মানগুলি পরিচালনা করতে সক্ষম হওয়া উচিত এবং যেহেতু সমস্ত রেফারেন্স প্রকারগুলি অন্তর্নিহিতভাবে নলযোগ্য হয়, তবে যদি কোনও রেফারেন্স টাইপ বা নাল পাস হয় তবে পদ্ধতিটি সর্বদা সত্য হওয়া উচিত।

উপরের দুটি পদ্ধতি নিম্নলিখিত একক পদ্ধতিতে প্রতিস্থাপন এবং একই আউটপুট অর্জন করতে পারে:

    public static bool IsObjectNullable<T>(T obj)
    {
        Type argType = typeof(T);
        if (!argType.IsValueType || obj == null)
            return true;
        return argType.IsGenericType && argType.GetGenericTypeDefinition() == typeof(Nullable<>);
    }

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

কায়েট: উদাহরণ হিসাবে দেখানো হয়েছে এই পদ্ধতিটি কেবলমাত্র আসল অবজেক্ট রেফারেন্স বা একটি সঠিক অনুলিপি ব্যবহার করে ডাকা হলে নির্ভরযোগ্যভাবে কাজ করে। যাইহোক, যদি কোনও নলযোগ্য বস্তুটি তার মূল নালাম <> ফর্মের পরিবর্তে অন্য প্রকারের (যেমন অবজেক্ট ইত্যাদি) বাক্সযুক্ত হয় তবে এই পদ্ধতিটি নির্ভরযোগ্যভাবে কাজ করবে না। যদি এই পদ্ধতিতে কলিং কোডটি মূল, আনবক্সড অবজেক্ট রেফারেন্স বা একটি সঠিক অনুলিপি ব্যবহার না করে, তবে এই পদ্ধতিটি ব্যবহার করে এটি নির্ভরযোগ্যভাবে অবজেক্টের শূন্যতা নির্ধারণ করতে পারে না।

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

পিএস - "nlalability" সম্পর্কে

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

রান-টাইম (ওয়েব সার্ভিসেস, রিমোট কল, ডাটাবেসগুলি, ফিডস ইত্যাদির) অবধি অজানা ধরণের অবজেক্টগুলি ব্যবহার করে এমন কোনও সিস্টেমে কোনও সাধারণ প্রয়োজনীয়তা নির্ধারণ করা হয় যে কোনও বস্তুকে নাল বরাদ্দ করা যেতে পারে, বা বস্তুটি থাকতে পারে কিনা একটি নাল অ-অ-প্রসারণযোগ্য ধরণের ক্ষেত্রে এই ধরনের ক্রিয়াকলাপ সম্পাদন করা ত্রুটিগুলি তৈরি করতে পারে, সাধারণত ব্যাতিক্রম হয়, যা কার্য সম্পাদন এবং কোডিং প্রয়োজনীয়তার ক্ষেত্রে উভয়ই ব্যয়বহুল। এই জাতীয় সমস্যাগুলি সক্রিয়ভাবে এড়িয়ে চলার সর্বাধিক পছন্দের পন্থা অবলম্বন করার জন্য, এটি নির্ধারণ করা প্রয়োজন যে কোনও স্বেচ্ছাসেবীর ধরণের কোনও বস্তু নাল যুক্ত করতে সক্ষম কিনা; অর্থাত্, এটি সাধারণত 'nullaable' কিনা।

খুব ব্যবহারিক এবং সাধারণ অর্থে। নেট শর্তাবলীর মধ্যে nullability মোটেই বোঝা যায় না যে কোনও বস্তুর প্রকার নলযোগ্য একটি রূপ। বেশিরভাগ ক্ষেত্রে বস্তুগুলির রেফারেন্সের ধরণ থাকে, এতে নাল মান থাকতে পারে এবং এইভাবে সমস্ত অযোগ্য; এগুলির কোনওটিরই নুলযোগ্য টাইপ নেই। অতএব, বেশিরভাগ পরিস্থিতিতে ব্যবহারিক উদ্দেশ্যে, নল্যাবিলিটির সাধারণ ধারণার জন্য বনাম নূরেবলের বাস্তবায়ন-নির্ভর ধারণার জন্য পরীক্ষা করা উচিত। সুতরাং কেবলমাত্র নেট নেট ন্যালেবল টাইপের দিকে মনোনিবেশ করে আমাদের ঝুলিয়ে রাখা উচিত নয় বরং এর প্রয়োজনীয়তা এবং আচরণ সম্পর্কে আমাদের উপলব্ধিটি ন্যূনযোগ্যতার সাধারণ, বাস্তব ধারণার উপর ফোকাস করার প্রক্রিয়ায় অন্তর্ভুক্ত করা উচিত।


8

মাইক্রোসফ্টের সমাধান ( কীভাবে: একটি নলযোগ্য প্রকার (সি # প্রোগ্রামিং গাইড) চিহ্নিত করুন ) একটি এক্সটেনশন পদ্ধতি হিসাবে প্রয়োগ করাই আমি যে সহজ সমাধানটি নিয়ে এসেছি :

public static bool IsNullable(this Type type)
{
    return Nullable.GetUnderlyingType(type) != null;
}

এটি তখন এর মতো বলা যেতে পারে:

bool isNullable = typeof(int).IsNullable();

এটি অ্যাক্সেসের যৌক্তিক উপায় বলে মনে হয় IsNullable()কারণ এটি শ্রেণীর অন্যান্য সমস্ত IsXxxx()পদ্ধতির সাথে খাপ Typeখায়।


1
আপনি কি "! =" এর পরিবর্তে "==" ব্যবহার করতে চান না?
ভেকেলম্যান

ভাল স্পট @ ভেলম্যান এই পরিবর্তনটি করার পরিবর্তে আমি মাইক্রোসফ্টের বর্তমান পরামর্শটি ব্যবহার করার উত্তরটি আপডেট করেছি কারণ আমি এটি লেখার পরে এটি পরিবর্তন হয়েছে।
sclarke81

6

সাবধানতা অবলম্বন করুন, যখন একটি নলাবদ্ধ টাইপের বক্সিং করা ( Nullable<int>বা উদাহরণস্বরূপ?

int? nullValue = null;
object boxedNullValue = (object)nullValue;
Debug.Assert(boxedNullValue == null);

int? value = 10;
object boxedValue = (object)value;
Debug.Assert( boxedValue.GetType() == typeof(int))

এটি সত্যিকারের রেফারেন্স প্রকারে পরিণত হয়, তাই আপনি এটি হারাতে পারেন যে এটি প্রবণ ছিল।


3

কিছুটা সামান্য বিষয় হতে পারে, তবে এখনও কিছু আকর্ষণীয় তথ্য। আমি এমন অনেক লোককে পেয়েছি Nullable.GetUnderlyingType() != nullযারা পরিচয় ব্যবহার করে যদি কোনও প্রকারটি উত্তরযোগ্য হয়। এটি স্পষ্টতই কাজ করে, তবে মাইক্রোসফ্ট নিম্নলিখিতগুলির পরামর্শ দেয় type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)(দেখুন http://msdn.microsoft.com/en-us/library/ms366789.aspx )।

আমি পারফরম্যান্সের দিক থেকে এটি দেখেছি। নীচের পরীক্ষার সমাপ্তি (এক মিলিয়ন প্রচেষ্টা) হ'ল যখন কোনও প্রকারটি হ্রাসযোগ্য হয় তখন মাইক্রোসফ্ট বিকল্পটি সর্বোত্তম কার্য সম্পাদন করে del

নলাবল.গেটউন্ডারিলিং টাইপ (): 1335 মিমি (3 গুণ বেশি ধীর)

GetGenericTypeDifinition () == টাইপফ (অবিচ্ছিন্ন <>): 500 মিমি

আমি জানি যে আমরা অল্প সময়ের সাথে কথা বলছি, তবে প্রত্যেকে মিলিসেকেন্ডগুলি টুইট করতে পছন্দ করে :-)! সুতরাং আপনি যদি বস চান আপনি কিছু মিলিসেকেন্ড কমিয়ে আনতে পারেন তবে এটি আপনার ত্রাণকর্তা ...

/// <summary>Method for testing the performance of several options to determine if a type is     nullable</summary>
[TestMethod]
public void IdentityNullablePerformanceTest()
{
    int attempts = 1000000;

    Type nullableType = typeof(Nullable<int>);

    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    for (int attemptIndex = 0; attemptIndex < attempts; attemptIndex++)
    {
        Assert.IsTrue(Nullable.GetUnderlyingType(nullableType) != null, "Expected to be a nullable"); 
    }

    Console.WriteLine("Nullable.GetUnderlyingType(): {0} ms", stopwatch.ElapsedMilliseconds);

    stopwatch.Restart();

    for (int attemptIndex = 0; attemptIndex < attempts; attemptIndex++)
   {
       Assert.IsTrue(nullableType.IsGenericType && nullableType.GetGenericTypeDefinition() == typeof(Nullable<>), "Expected to be a nullable");
   }

   Console.WriteLine("GetGenericTypeDefinition() == typeof(Nullable<>): {0} ms", stopwatch.ElapsedMilliseconds);
   stopwatch.Stop();
}

1
হাই, সময় পরিমাপের ক্ষেত্রে সম্ভবত একটি সমস্যা আছে, ফলাফলগুলি প্রভাবকে প্রভাবিত করতে পারে আপনি Assert ছাড়া পরীক্ষা করেছেন? কনসোল.ওরাইটলাইনটি মিটার এলাকার বাইরে হওয়া উচিত। পারফরম্যান্স সমস্যাগুলি মাপার চেষ্টা করার জন্য +1
ipavlu

@ আইপাবলু Console.WriteLineপ্রকৃতপক্ষে মিটার এলাকার বাইরে;)
নওফাল

রোল, যেমন ইপাভলু উল্লেখ করেছেন, Assertলুপের বাইরে হওয়া উচিত। দ্বিতীয়ত, আপনাকে মিথ্যা মামলার জন্য পরীক্ষা করার পাশাপাশি অ-অযোগ্যদের বিরুদ্ধেও এটি পরীক্ষা করা উচিত। আমি একটি অনুরূপ পরীক্ষা করেছি (২ টি নুলাবল এবং ৪ টি নন-নল) এবং আমি পেয়েছি ~ 2 সেকেন্ড GetUnderlyingTypeএবং ~ 1 সেকেন্ডের জন্য GetGenericTypeDefinition, অর্থাৎ GetGenericTypeDefinitionদ্বিগুণ দ্রুত (তিনবার নয়)।
নওফাল

2 টি nullable এবং 2 টি নন-নুলাবল সহ আরও একটি বৃত্তাকার করেছিলেন - এই সময়টি GetUnderlyingType2.5 গুণ ধীর ছিল। কেবল অ-নলাবলের সাথে - এবার উভয়ই ঘাড় এবং ঘাড়।
নওফাল

তবে আরও গুরুত্বপূর্ণ বিষয় GetUnderlyingTypeহল , যখন আপনাকে nlalability পরীক্ষা করতে হবে এবং যদি এটি nlalable হয় তবে অন্তর্নিহিত প্রকারটি পরীক্ষা করতে হবে। এটি খুব দরকারী এবং আপনি প্যাটার্নগুলি প্রায়শই পছন্দ করেন Activator.CreateInstance(Nullable.GetUnderlyingType(type) ?? type)। এটি কীওয়ার্ডের মতো as, castালাইগুলির জন্য পরীক্ষা করে পাশাপাশি এটি করে & ফলাফল দেয়। যদি আপনি অন্তর্নিহিত ধরণের নালাগুলি ফিরে পেতে চান তবে একটি GetGenericTypeDefinitionচেক করা এবং তারপরে জেনেরিক টাইপ পাওয়া খারাপ ধারণা হবে। এছাড়াও GetUnderlyingTypeঅনেক বেশি পাঠযোগ্য এবং স্মরণীয়। আমি যদি এটি কেবল ~ 1000 বার করে থাকি তবে আমি তাতে কিছু মনে করব না।
নওফাল

0

এই সংস্করণ:

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

:

public static class IsNullable<T>
{
    private static readonly Type type = typeof(T);
    private static readonly bool is_nullable = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
    public static bool Result { get { return is_nullable; } }
}

bool is_nullable = IsNullable<int?>.Result;

আমি মনে করি আপনি সেই স্থির ঘোষণাপত্র 'is_nullable' দিয়ে নিজের-নিজের উত্তর দিয়েছেন। টিপ: ইনট দিয়ে বস্তু ঘোষনা করবেন? (অবজেক্ট এ = (ইনট?) ৮;) এবং দেখুন কী ঘটে।
SoLaR

0

আমি এখানে যা এলাম, অন্য সমস্ত কিছু ব্যর্থ বলে মনে হয়েছিল - কমপক্ষে পিএলসি - পোর্টেবল ক্লাস লাইব্রেরি /। নেট কোর>> সি # 6 সহ

সমাধান: যে কোনও প্রকারের জন্য স্থিতিশীল পদ্ধতিগুলি প্রসারিত করুন Tএবং Nullable<T>অন্তর্নিহিত প্রকারের সাথে মিলে স্থিতিশীল প্রসারণ পদ্ধতিটি আহ্বান করা হবে এবং জেনেরিক Tএক্সটেনশন-পদ্ধতির চেয়ে অগ্রাধিকার গ্রহণ করে use

এর জন্য T:

public static partial class ObjectExtension
{
    public static bool IsNullable<T>(this T self)
    {
        return false;
    }
}

এবং জন্য Nullable<T>

public static partial class NullableExtension
{
    public static bool IsNullable<T>(this Nullable<T> self) where T : struct
    {
        return true;
    }
}

প্রতিবিম্ব এবং type.IsGenericType... ব্যবহার করে আমার বর্তমান নেট নেট টাইমের সেটগুলিতে কাজ হয়নি। বা এমএসডিএন ডকুমেন্টেশন সহায়তা করেনি ।

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) {…}

অংশ হিসাবে কারণ প্রতিস্থাপনের API .NET কোর মধ্যে বেশ উল্লেখযোগ্যভাবে পরিবর্তন করা হয়েছে।


0

আমি মনে করি যেগুলির বিরুদ্ধে মাইক্রোসফ্টের প্রস্তাবিত পরীক্ষাগুলি ব্যবহার করছে IsGenericTypeতারা ভাল, তবে GetUnderlyingTypeকোডটির ক্ষেত্রে, জেনেরিক ধরণের সংজ্ঞা আপনি পাস করেননি তা নিশ্চিত করার জন্য মাইক্রোসফ্ট একটি অতিরিক্ত পরীক্ষা ব্যবহার করে Nullable<>:

 public static bool IsNullableType(this Type nullableType) =>
    // instantiated generic type only                
    nullableType.IsGenericType &&
    !nullableType.IsGenericTypeDefinition &&
    Object.ReferenceEquals(nullableType.GetGenericTypeDefinition(), typeof(Nullable<>));

-1

এটি করার একটি সহজ উপায়:

    public static bool IsNullable(this Type type)
    {
        if (type.IsValueType) return Activator.CreateInstance(type) == null;

        return true;
    }

এগুলি আমার ইউনিট পরীক্ষা এবং সব পাস হয়েছে

    IsNullable_String_ShouldReturn_True
    IsNullable_Boolean_ShouldReturn_False
    IsNullable_Enum_ShouldReturn_Fasle
    IsNullable_Nullable_ShouldReturn_True
    IsNullable_Class_ShouldReturn_True
    IsNullable_Decimal_ShouldReturn_False
    IsNullable_Byte_ShouldReturn_False
    IsNullable_KeyValuePair_ShouldReturn_False

প্রকৃত ইউনিট পরীক্ষা

    [TestMethod]
    public void IsNullable_String_ShouldReturn_True()
    {
        var typ = typeof(string);
        var result = typ.IsNullable();
        Assert.IsTrue(result);
    }

    [TestMethod]
    public void IsNullable_Boolean_ShouldReturn_False()
    {
        var typ = typeof(bool);
        var result = typ.IsNullable();
        Assert.IsFalse(result);
    }

    [TestMethod]
    public void IsNullable_Enum_ShouldReturn_Fasle()
    {
        var typ = typeof(System.GenericUriParserOptions);
        var result = typ.IsNullable();
        Assert.IsFalse(result);
    }

    [TestMethod]
    public void IsNullable_Nullable_ShouldReturn_True()
    {
        var typ = typeof(Nullable<bool>);
        var result = typ.IsNullable();
        Assert.IsTrue(result);
    }

    [TestMethod]
    public void IsNullable_Class_ShouldReturn_True()
    {
        var typ = typeof(TestPerson);
        var result = typ.IsNullable();
        Assert.IsTrue(result);
    }

    [TestMethod]
    public void IsNullable_Decimal_ShouldReturn_False()
    {
        var typ = typeof(decimal);
        var result = typ.IsNullable();
        Assert.IsFalse(result);
    }

    [TestMethod]
    public void IsNullable_Byte_ShouldReturn_False()
    {
        var typ = typeof(byte);
        var result = typ.IsNullable();
        Assert.IsFalse(result);
    }

    [TestMethod]
    public void IsNullable_KeyValuePair_ShouldReturn_False()
    {
        var typ = typeof(KeyValuePair<string, string>);
        var result = typ.IsNullable();
        Assert.IsFalse(result);
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.