টাইপটি আদিম হলে কীভাবে পরীক্ষা করবেন


162

আমার কাছে কোডের একটি ব্লক রয়েছে যা এইচটিএমএল ট্যাগে কোনও ধরণের সিরিয়ালাইজ করে।

Type t = typeof(T); // I pass <T> in as a paramter, where myObj is of type T
tagBuilder.Attributes.Add("class", t.Name);
foreach (PropertyInfo prop in t.GetProperties())
{
    object propValue = prop.GetValue(myObj, null);
    string stringValue = propValue != null ? propValue.ToString() : String.Empty;
    tagBuilder.Attributes.Add(prop.Name, stringValue);
}

এই মহান কাজ করে, ছাড়া আমি এটা শুধুমাত্র আদিম ধরনের, মত এই কাজ করতে চান int, double, boolইত্যাদি, এবং অন্যান্য ধরনের যে আদিম নয় কিন্তু মত সহজে ধারাবাহিকভাবে যাবে string। আমি এটি তালিকাগুলি এবং অন্যান্য কাস্টম ধরণের মতো অন্য সমস্ত কিছু উপেক্ষা করতে চাই।

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


12
System.Stringকোনও আদিম ধরণের নয়।
স্ল্যাक्स

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

@ এরিক: ধন্যবাদ, আমিও ভাবছি আপনি যদি সংখ্যার সাথে একই মানদণ্ডটি ব্যবহার করতে পারেন? উদাহরণস্বরূপ গাণিতিক ফাংশনগুলি লেখার জন্য যা সমস্ত সংখ্যার প্রকারকে সমর্থন করে, যেমন গড়, সমষ্টি ইত্যাদি etc. সেগুলি জেনেরিক বা ওভারলোড ব্যবহার করে প্রয়োগ করা উচিত? বাস্তবায়ন একই হয় কি না তা বিবেচ্য নয়? কারণ এটি গড় প্রায় একই রকম অপারেশন, কোনও সংখ্যার জন্য সমষ্টি, তাই না?
জোয়ান ওয়েঙ্গেজ

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

উত্তর:


184

আপনি সম্পত্তিটি ব্যবহার করতে পারেন Type.IsPrimitive, তবে যত্নবান হন কারণ এমন কিছু প্রকার রয়েছে যা আমরা ভাবতে পারি যে এটি আদিম, তবে তারা নয়, উদাহরণস্বরূপ Decimalএবং String

সম্পাদনা 1: নমুনা কোড যুক্ত

এখানে একটি নমুনা কোড রয়েছে:

if (t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) || ... )
{
    // Is Primitive, or Decimal, or String
}

সম্পাদনা 2: @ এসএলক্সের মন্তব্য হিসাবে , অন্যান্য প্রকারগুলি রয়েছে যা সম্ভবত আপনিও আদিম হিসাবে বিবেচনা করতে চান। আমি মনে করি যে আপনাকে এই বৈচিত্রগুলি একে একে যুক্ত করতে হবে

3 সম্পাদনা করুন: ইসপ্রিমেটিভ = (বুলিয়ান, বাইট, এসবিট, ইনট 16, ইউআইএনটি 16, ইন্ট 32, ইউআইএনটি 32, ইন্ট 64, ইউআইএনটি 64, ইন্টিপিটি, ইউআইএনটিপিআর, চর, ডাবল এবং একক) ))


12
এবং সম্ভবত DateTime, TimeSpanএবং DateTimeOffset
স্ল্যাक्स

মমমম ... হ্যাঁ, আপনি ঠিক বলেছেন। আমি মনে করি আমাদের আরও কিছু সম্ভাবনা যুক্ত করতে হবে
জাভিয়ের

2
আপনার যুক্তিযুক্ত বা ( ||) ব্যবহার করতে হবে, বিটওয়াইস বা ( |) নয়।
স্ল্যাक्स

42
@ জাভিয়ার এবং মাইকেল পেতিতোর উত্তরগুলিতে বর্ণিত পরীক্ষাগুলি সুবিধামতভাবে চালানোর জন্য এখানে একটি এক্সটেনশন পদ্ধতি লিখেছি: gist.github.com/3330614
জোনাথন

5
আপনি সম্পত্তিটি টাইপ.আইএসভ্যালু টাইপ ব্যবহার করতে পারেন এবং স্ট্রিংয়ের জন্য কেবলমাত্র চেক যোগ করতে পারেন ।
মাত্তেও মিগলিওর

57

অনুরূপ সমাধানের সন্ধানের জন্য আমি এই প্রশ্নটি সবেমাত্র পেয়েছি এবং ভেবেছি আপনি এবং নীচের পদ্ধতির ব্যবহারে আগ্রহী হতে পারেন System.TypeCodeএবং System.Convert

System.TypeCodeঅন্য যে কোনও প্রকারের সাথে ম্যাপ করা কোনও ধরণের সিরিয়ালাইজ করা সহজ System.TypeCode.Object, তাই আপনি এটি করতে পারেন:

object PropertyValue = ...
if(Convert.GetTypeCode(PropertyValue) != TypeCode.Object)
{
    string StringValue = Convert.ToString(PropertyValue);
    ...
}

এই পদ্ধতির সাথে সুবিধাটি হ'ল আপনাকে অন্য প্রত্যেকটি গ্রহণযোগ্য অ-আদিম ধরণের নাম দিতে হবে না। আপনি আইকনভারটিবল প্রয়োগ করে এমন কোনও ধরণের হ্যান্ডেল করতে উপরের কোডটি সামান্যও সংশোধন করতে পারেন।


2
এটি দুর্দান্ত, আমাকে Guidনিজের উদ্দেশ্যে (আমার সংজ্ঞাতে একটি আদিম হিসাবে) নিজেই যুক্ত করতে হয়েছিল ।
এরিক ফিলিপস

56

আমরা আমাদের ওআরএম এ এটি করি:

Type t;
bool isPrimitiveType = t.IsPrimitive || t.IsValueType || (t == typeof(string));

আমি জানি যে ব্যবহার IsValueTypeকরা সর্বোত্তম বিকল্প নয় (আপনার নিজের খুব জটিল স্ট্রাক থাকতে পারে) তবে এটি 99% ক্ষেত্রে কাজ করে (এবং এতে নুলাবল রয়েছে)।


6
আপনি যদি ইসভালিউটাইপ ব্যবহার করছেন তবে আপনার ইস্প্রিমেটিভের প্রয়োজন কেন? সমস্ত আদিম মান মান হয় না?
জোয়েলফ্যান

5
@ জোয়েলফ্যান দশমিক প্রকারের ইজপ্রিমিটিভ মিথ্যা রয়েছে তবে ইসভালিউটাইপ সত্য
xhafan

3
@ শেফান: আপনি ভুল প্রশ্নের উত্তর দিন। সমস্ত স্ট্রাক্ট decimalযে বিষয়ে মত হয়। কিন্তু এমন কি আছে যার জন্য IsPrimitiveরিটার্ন trueছাড়াও IsValueTypeফিরে আসে false? যদি এ জাতীয় কোনও ধরণ না থাকে তবে t.IsPrimitiveপরীক্ষাটি অপ্রয়োজনীয়।
লিই

6
@ লাই আপনি ঠিক বলেছেন, প্রতিটি আদিম টাইপ IsValueTypeসত্য হয়ে গেছে, সুতরাং এটির জন্য পরীক্ষা করার IsPrimitiveদরকার নেই। চিয়ার্স!
xhafan

1
পছন্দ করেছেন আপনার একটি অ-আদিম মান ধরণের থাকতে পারে, সেক্ষেত্রে বৈশিষ্ট্যের বিভিন্ন মান রয়েছে।
মাইকেল পেতিটো

38

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

public static bool IsSimpleType(Type type)
{
    return
        type.IsPrimitive ||
        new Type[] {
            typeof(string),
            typeof(decimal),
            typeof(DateTime),
            typeof(DateTimeOffset),
            typeof(TimeSpan),
            typeof(Guid)
        }.Contains(type) ||
        type.IsEnum ||
        Convert.GetTypeCode(type) != TypeCode.Object ||
        (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>) && IsSimpleType(type.GetGenericArguments()[0]))
        ;
}

নিম্নলিখিত টেস্টকেস সহ:

struct TestStruct
{
    public string Prop1;
    public int Prop2;
}

class TestClass1
{
    public string Prop1;
    public int Prop2;
}

enum TestEnum { TheValue }

[Test]
public void Test1()
{
    Assert.IsTrue(IsSimpleType(typeof(TestEnum)));
    Assert.IsTrue(IsSimpleType(typeof(string)));
    Assert.IsTrue(IsSimpleType(typeof(char)));
    Assert.IsTrue(IsSimpleType(typeof(Guid)));

    Assert.IsTrue(IsSimpleType(typeof(bool)));
    Assert.IsTrue(IsSimpleType(typeof(byte)));
    Assert.IsTrue(IsSimpleType(typeof(short)));
    Assert.IsTrue(IsSimpleType(typeof(int)));
    Assert.IsTrue(IsSimpleType(typeof(long)));
    Assert.IsTrue(IsSimpleType(typeof(float)));
    Assert.IsTrue(IsSimpleType(typeof(double)));
    Assert.IsTrue(IsSimpleType(typeof(decimal)));

    Assert.IsTrue(IsSimpleType(typeof(sbyte)));
    Assert.IsTrue(IsSimpleType(typeof(ushort)));
    Assert.IsTrue(IsSimpleType(typeof(uint)));
    Assert.IsTrue(IsSimpleType(typeof(ulong)));

    Assert.IsTrue(IsSimpleType(typeof(DateTime)));
    Assert.IsTrue(IsSimpleType(typeof(DateTimeOffset)));
    Assert.IsTrue(IsSimpleType(typeof(TimeSpan)));

    Assert.IsFalse(IsSimpleType(typeof(TestStruct)));
    Assert.IsFalse(IsSimpleType(typeof(TestClass1)));

    Assert.IsTrue(IsSimpleType(typeof(TestEnum?)));
    Assert.IsTrue(IsSimpleType(typeof(char?)));
    Assert.IsTrue(IsSimpleType(typeof(Guid?)));

    Assert.IsTrue(IsSimpleType(typeof(bool?)));
    Assert.IsTrue(IsSimpleType(typeof(byte?)));
    Assert.IsTrue(IsSimpleType(typeof(short?)));
    Assert.IsTrue(IsSimpleType(typeof(int?)));
    Assert.IsTrue(IsSimpleType(typeof(long?)));
    Assert.IsTrue(IsSimpleType(typeof(float?)));
    Assert.IsTrue(IsSimpleType(typeof(double?)));
    Assert.IsTrue(IsSimpleType(typeof(decimal?)));

    Assert.IsTrue(IsSimpleType(typeof(sbyte?)));
    Assert.IsTrue(IsSimpleType(typeof(ushort?)));
    Assert.IsTrue(IsSimpleType(typeof(uint?)));
    Assert.IsTrue(IsSimpleType(typeof(ulong?)));

    Assert.IsTrue(IsSimpleType(typeof(DateTime?)));
    Assert.IsTrue(IsSimpleType(typeof(DateTimeOffset?)));
    Assert.IsTrue(IsSimpleType(typeof(TimeSpan?)));

    Assert.IsFalse(IsSimpleType(typeof(TestStruct?)));
}

1
এটি একটি ভাল পদ্ধতির, তবে Enumএটি সমর্থিত নয়, এটি পরীক্ষা করে enum MyEnum { EnumValue }ব্যবহার করে MyEnum। @ জোনাথনও ব্যবহার করছে type.IsValueType। এটি Enumsসঠিকভাবে সনাক্ত করা হয় তবে এটিও Structs। সুতরাং আপনি কি আদিম চান তা দেখুন।
অ্যাপেলকোচা

1
@ আপেলকুয়াছা: আপনি একেবারে ঠিক বলেছেন। তবে পরিবর্তে ব্যবহার করে type.IsValueType, কেন কেবল যোগ type.IsEnumকরবেন না ?
Xav987

আপনি সম্পূর্ণ সঠিক। type.IsEnumসম্ভব। আমি আপনার পোস্টে একটি সম্পাদনা করার পরামর্শ দিয়েছি :)
অ্যাপলকোচা

16

আমি এটি কীভাবে করেছি তা এখানে।

   static class PrimitiveTypes
   {
       public static readonly Type[] List;

       static PrimitiveTypes()
       {
           var types = new[]
                          {
                              typeof (Enum),
                              typeof (String),
                              typeof (Char),
                              typeof (Guid),

                              typeof (Boolean),
                              typeof (Byte),
                              typeof (Int16),
                              typeof (Int32),
                              typeof (Int64),
                              typeof (Single),
                              typeof (Double),
                              typeof (Decimal),

                              typeof (SByte),
                              typeof (UInt16),
                              typeof (UInt32),
                              typeof (UInt64),

                              typeof (DateTime),
                              typeof (DateTimeOffset),
                              typeof (TimeSpan),
                          };


           var nullTypes = from t in types
                           where t.IsValueType
                           select typeof (Nullable<>).MakeGenericType(t);

           List = types.Concat(nullTypes).ToArray();
       }

       public static bool Test(Type type)
       {
           if (List.Any(x => x.IsAssignableFrom(type)))
               return true;

           var nut = Nullable.GetUnderlyingType(type);
           return nut != null && nut.IsEnum;
       }
   }

@RonnieOverby। IsAssignableFromআপনার পরীক্ষায় ব্যবহারের পরিবর্তে কোনও প্যাটিকুলার কারণ রয়েছে কি?
জননি 5

6

এছাড়াও একটি ভাল সম্ভাবনা:

private static bool IsPrimitiveType(Type type)
{
    return (type == typeof(object) || Type.GetTypeCode(type) != TypeCode.Object);
}

প্রতিটি উদাহরণে ইস্প্রিমিটিভType নামে একটি সম্পত্তি রয়েছে । পরিবর্তে আপনার এটি ব্যবহার করা উচিত।
রেনান

3
আমরাও Stringনা Decimalপ্রিমিটিভের হয়।
k3flo

আমার জন্য এই কাজ, কিন্তু আমি IsClrType করতে নতুন নামকরণ প্রকার শ্রেণী উপস্থিত .IsPrimitive সঙ্গে এর অর্থ গুলান না
KnarfaLingus

1
উদাহরণস্বরূপ এটি গাইড বা টাইমস্প্যান পছন্দ করে না।
স্ট্যানিসলাভ

3

ধরে নিচ্ছি আপনার যেমন ফাংশন স্বাক্ষর রয়েছে:

void foo<T>() 

আপনি কেবলমাত্র মান ধরণের অনুমতি দেওয়ার জন্য একটি জেনেরিক সীমাবদ্ধতা যোগ করতে পারেন:

void foo<T>() where T : struct

লক্ষ্য করুন যে এটি কেবল টির জন্য আদিম প্রকারগুলিকেই নয়, কোনও মান ধরণেরও অনুমতি দেয়।


2

এক্সএমএলে রফতানি করার উদ্দেশ্যে আমার ধরণের সিরিয়ালাইজ করার দরকার ছিল। এটি করার জন্য, আমি অবজেক্টের মাধ্যমে পুনরাবৃত্তি করেছি এবং সেই ক্ষেত্রগুলির জন্য নির্বাচন করেছি যেগুলি আদিম, এনাম, মান ধরণের বা সিরিয়ালযোগ্য were এটি আমার প্রশ্নের ফলাফল ছিল:

Type contextType = context.GetType();

var props = (from property in contextType.GetProperties()
                         let name = property.Name
                         let type = property.PropertyType
                         let value = property.GetValue(context,
                                     (BindingFlags.GetProperty | BindingFlags.GetField | BindingFlags.Public),
                                     null, null, null)
                         where (type.IsPrimitive || type.IsEnum || type.IsValueType || type.IsSerializable)
                         select new { Name = name, Value = value});

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

চিয়ার্স!


1

আমার লাইব্রেরিতে আমার যা আছে তা এই। মন্তব্য স্বাগত।

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

  Public Shared Function IsPersistable(Type As System.Type) As Boolean
    With TypeInformation.UnderlyingType(Type)
      Return .IsValueType OrElse Type = GetType(String) OrElse .IsPrimitive
    End With
  End Function

  Public Shared Function IsNullable(ByVal Type As System.Type) As Boolean
    Return (Type.IsGenericType) AndAlso (Type.GetGenericTypeDefinition() Is GetType(Nullable(Of )))
  End Function

  Public Shared Function UnderlyingType(ByVal Type As System.Type) As System.Type
    If IsNullable(Type) Then
      Return Nullable.GetUnderlyingType(Type)
    Else
      Return Type
    End If
  End Function

তারপরে আমি এটি এর মতো ব্যবহার করতে পারি:

  Public Shared Function PersistableProperties(Item As System.Type) As IEnumerable(Of System.Reflection.PropertyInfo)
    Return From PropertyInfo In Item.GetProperties()
                     Where PropertyInfo.CanWrite AndAlso (IsPersistable(PropertyInfo.PropertyType))
                     Select PropertyInfo
  End Function

0

আমি কেবল আমার সমাধানটি ভাগ করতে চাই। সম্ভবত এটি কারও কাজে লাগে।

public static bool IsPrimitiveType(Type fieldType)
{
   return fieldType.IsPrimitive || fieldType.Namespace.Equals("System");
}

5
IsPrimitiveType(typeof(System.AccessViolationException)) == true
রনি ওভারবি

2
namespace System { class MyNonPrimitiveType { } }
রনি ওভারবি

0
public static bool IsPrimitiveType(object myObject)
{
   var myType = myObject.GetType();
   return myType.IsPrimitive || myType.Namespace == null ||  myType.Namespace.Equals("System");
}

নুল নেমস্পেসটি পরীক্ষা করতে ভুলবেন না, কারণ বেনামে অবজেক্টগুলিতে নেমস্পেস নির্ধারিত নেই


0

এখানে আরও একটি কার্যকর বিকল্প।

public static bool CanDirectlyCompare(Type type)
{
    return typeof(IComparable).IsAssignableFrom(type) || type.IsPrimitive || type.IsValueType;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.