প্রদত্ত কি না তা নির্ধারণ করার কোনও উপায় আছে? নেট টাইপটি একটি সংখ্যা? উদাহরণস্বরূপ: System.UInt32/UInt16/Doubleসমস্ত সংখ্যা। আমি এর উপর একটি দীর্ঘ সুইচ-কেস এড়াতে চাই Type.FullName।
প্রদত্ত কি না তা নির্ধারণ করার কোনও উপায় আছে? নেট টাইপটি একটি সংখ্যা? উদাহরণস্বরূপ: System.UInt32/UInt16/Doubleসমস্ত সংখ্যা। আমি এর উপর একটি দীর্ঘ সুইচ-কেস এড়াতে চাই Type.FullName।
উত্তর:
এটা চেষ্টা কর:
Type type = object.GetType();
bool isNumber = (type.IsPrimitiveImple && type != typeof(bool) && type != typeof(char));
আদিম প্রকারগুলি হ'ল বুলিয়ান, বাইট, এসবাইট, ইন্ট 16, ইউআইএনট 16, ইন্ট 32, ইউআইএনটি 32, ইন্ট 64, ইউআইএন 64, চর, ডাবল এবং একক।
টেকিং Guillaume, এর সমাধান একটু আরো:
public static bool IsNumericType(this object o)
{
switch (Type.GetTypeCode(o.GetType()))
{
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return true;
default:
return false;
}
}
ব্যবহার:
int i = 32;
i.IsNumericType(); // True
string s = "Hello World";
s.IsNumericType(); // False
decimalটাইপ সংখ্যাটি নয়?
decimal এটি সংখ্যাসূচক। এটি আদিম নয় বলে এর অর্থ এটি সংখ্যাসূচক নয়। আপনার কোডটির জন্য এটি অ্যাকাউন্ট করা দরকার।
একটি স্যুইচ ব্যবহার করবেন না - কেবল একটি সেট ব্যবহার করুন:
HashSet<Type> NumericTypes = new HashSet<Type>
{
typeof(decimal), typeof(byte), typeof(sbyte),
typeof(short), typeof(ushort), ...
};
সম্পাদনা: প্রকারের কোড ব্যবহারের মাধ্যমে এর একটি সুবিধা হ'ল যখন নতুন সংখ্যার প্রকারগুলি .NET (যেমন বিগআইন্টিজার এবং কমপ্লেক্স ) এর মধ্যে প্রবর্তিত হয় তখন এটি সামঞ্জস্য করা সহজ - যেখানে এই ধরণের কোনও টাইপ কোড পাবেন না ।
switchতেমন কাজ হয় না Type, তাই আপনি পারবেন না। আপনি TypeCodeঅবশ্যই চালু করতে পারেন , তবে এটি ভিন্ন বিষয় a
সমাধানগুলির কোনওটিই নুলকে বিবেচনায় নেয় না।
আমি জন স্কিটির সমাধানটি কিছুটা সংশোধন করেছি:
private static HashSet<Type> NumericTypes = new HashSet<Type>
{
typeof(int),
typeof(uint),
typeof(double),
typeof(decimal),
...
};
internal static bool IsNumericType(Type type)
{
return NumericTypes.Contains(type) ||
NumericTypes.Contains(Nullable.GetUnderlyingType(type));
}
আমি জানি যে আমি কেবলমাত্র আমার হ্যাশসেটে নল যুক্ত করতে পারি। তবে এই সমাধানটি আপনার তালিকায় একটি নির্দিষ্ট নুলযোগ্য যুক্ত করতে ভুলে যাওয়ার বিপদ এড়াতে পারে।
private static HashSet<Type> NumericTypes = new HashSet<Type>
{
typeof(int),
typeof(int?),
...
};
public static bool IsNumericType(Type type)
{
switch (Type.GetTypeCode(type))
{
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return true;
default:
return false;
}
}
অপ্টিমাইজেশান সম্পর্কে নোট সরানো হয়েছে (এনজি মন্তব্য দেখুন)
এবং আপনি যদি সত্যিই এটি অনুকূল করতে চান (পাঠযোগ্যতা এবং কিছু সুরক্ষা হারাতে ...):
public static bool IsNumericType(Type type)
{
TypeCode typeCode = Type.GetTypeCode(type);
//The TypeCode of numerical types are between SByte (5) and Decimal (15).
return (int)typeCode >= 5 && (int)typeCode <= 15;
}
return unchecked((uint)Type.GetTypeCode(type) - 5u) <= 10u;এভাবে প্রবর্তিত শাখাটি সরিয়ে ফেলবে &&।
মূলত স্কিটির সমাধান তবে আপনি নীচের মতো করে এটি পুনরায় ব্যবহার করতে পারেন:
public static class TypeHelper
{
private static readonly HashSet<Type> NumericTypes = new HashSet<Type>
{
typeof(int), typeof(double), typeof(decimal),
typeof(long), typeof(short), typeof(sbyte),
typeof(byte), typeof(ulong), typeof(ushort),
typeof(uint), typeof(float)
};
public static bool IsNumeric(Type myType)
{
return NumericTypes.Contains(Nullable.GetUnderlyingType(myType) ?? myType);
}
}
ফিলিপের প্রস্তাবের ভিত্তিতে পন্থা , এসফুন 28 এর প্রকারের জন্য অভ্যন্তরীণ প্রকারের চেক দিয়ে বর্ধিত Nullable:
public static class IsNumericType
{
public static bool IsNumeric(this Type type)
{
switch (Type.GetTypeCode(type))
{
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return true;
case TypeCode.Object:
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
return Nullable.GetUnderlyingType(type).IsNumeric();
//return IsNumeric(Nullable.GetUnderlyingType(type));
}
return false;
default:
return false;
}
}
}
কেন এটা? প্রদত্ত Type typeএকটি সংখ্যার ধরণের কিনা তা আমাকে পরীক্ষা করে দেখতে হয়েছিল এবং স্বেচ্ছাসেবী object oসংখ্যাসূচক কিনা তা নয় ।
সি # 7 এর সাথে এই পদ্ধতিটি আমাকে সুইচ কেসের চেয়ে ভাল পারফরম্যান্স দেয় TypeCodeএবং HashSet<Type>:
public static bool IsNumeric(this object o) => o is byte || o is sbyte || o is ushort || o is uint || o is ulong || o is short || o is int || o is long || o is float || o is double || o is decimal;
টেস্টগুলি নিম্নলিখিত:
public static class Extensions
{
public static HashSet<Type> NumericTypes = new HashSet<Type>()
{
typeof(byte), typeof(sbyte), typeof(ushort), typeof(uint), typeof(ulong), typeof(short), typeof(int), typeof(long), typeof(decimal), typeof(double), typeof(float)
};
public static bool IsNumeric1(this object o) => NumericTypes.Contains(o.GetType());
public static bool IsNumeric2(this object o) => o is byte || o is sbyte || o is ushort || o is uint || o is ulong || o is short || o is int || o is long || o is decimal || o is double || o is float;
public static bool IsNumeric3(this object o)
{
switch (o)
{
case Byte b:
case SByte sb:
case UInt16 u16:
case UInt32 u32:
case UInt64 u64:
case Int16 i16:
case Int32 i32:
case Int64 i64:
case Decimal m:
case Double d:
case Single f:
return true;
default:
return false;
}
}
public static bool IsNumeric4(this object o)
{
switch (Type.GetTypeCode(o.GetType()))
{
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return true;
default:
return false;
}
}
}
class Program
{
static void Main(string[] args)
{
var count = 100000000;
//warm up calls
for (var i = 0; i < count; i++)
{
i.IsNumeric1();
}
for (var i = 0; i < count; i++)
{
i.IsNumeric2();
}
for (var i = 0; i < count; i++)
{
i.IsNumeric3();
}
for (var i = 0; i < count; i++)
{
i.IsNumeric4();
}
//Tests begin here
var sw = new Stopwatch();
sw.Restart();
for (var i = 0; i < count; i++)
{
i.IsNumeric1();
}
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
sw.Restart();
for (var i = 0; i < count; i++)
{
i.IsNumeric2();
}
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
sw.Restart();
for (var i = 0; i < count; i++)
{
i.IsNumeric3();
}
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
sw.Restart();
for (var i = 0; i < count; i++)
{
i.IsNumeric4();
}
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
}
আপনি Type.IsPrimitive ব্যবহার করতে পারেন এবং তারপরে Booleanএবং Charপ্রকারগুলি বাছাই করুন , এরকম কিছু:
bool IsNumeric(Type type)
{
return type.IsPrimitive && type!=typeof(char) && type!=typeof(bool);
}
সম্পাদনা : আপনি সংখ্যক হিসাবে বিবেচনা না করে আপনি প্রকার IntPtrএবং UIntPtrপ্রকারগুলিও বাদ দিতে চাইতে পারেন।
decimalটাইপ সংখ্যাটি নয়?
নাল-টাইপ সমর্থন সহ এক্সটেনশন টাইপ করুন।
public static bool IsNumeric(this Type type)
{
if (type == null) { return false; }
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
type = type.GetGenericArguments()[0];
}
switch (Type.GetTypeCode(type))
{
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return true;
default:
return false;
}
}
সংশোধিত স্কিট এবং arviman এর সমাধান ব্যবহার Generics, Reflectionএবং C# v6.0।
private static readonly HashSet<Type> m_numTypes = new HashSet<Type>
{
typeof(int), typeof(double), typeof(decimal),
typeof(long), typeof(short), typeof(sbyte),
typeof(byte), typeof(ulong), typeof(ushort),
typeof(uint), typeof(float), typeof(BigInteger)
};
অনুসরণ করেছেন:
public static bool IsNumeric<T>( this T myType )
{
var IsNumeric = false;
if( myType != null )
{
IsNumeric = m_numTypes.Contains( myType.GetType() );
}
return IsNumeric;
}
এর জন্য ব্যবহার (T item):
if ( item.IsNumeric() ) {}
null মিথ্যা প্রত্যাবর্তন
স্যুইচটি কিছুটা ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে খারাপ সময়কালে পদ্ধতিগুলি সমস্ত ধরণের মধ্য দিয়ে যাবে। আমি মনে করি, ডিক্টোনারি ব্যবহার করা আরও দুর্দান্ত, এই পরিস্থিতিতে আপনারা থাকবেন O(1):
public static class TypeExtensions
{
private static readonly HashSet<Type> NumberTypes = new HashSet<Type>();
static TypeExtensions()
{
NumberTypes.Add(typeof(byte));
NumberTypes.Add(typeof(decimal));
NumberTypes.Add(typeof(double));
NumberTypes.Add(typeof(float));
NumberTypes.Add(typeof(int));
NumberTypes.Add(typeof(long));
NumberTypes.Add(typeof(sbyte));
NumberTypes.Add(typeof(short));
NumberTypes.Add(typeof(uint));
NumberTypes.Add(typeof(ulong));
NumberTypes.Add(typeof(ushort));
}
public static bool IsNumber(this Type type)
{
return NumberTypes.Contains(type);
}
}
ব্যবহার করে দেখুন TypeSupport C # এর জন্য nuget প্যাকেজ। এটিতে সমস্ত সংখ্যার প্রকারগুলি সনাক্ত করার জন্য সমর্থন রয়েছে (অন্যান্য অনেক বৈশিষ্ট্যের মধ্যে):
var extendedType = typeof(int).GetExtendedType();
Assert.IsTrue(extendedType.IsNumericType);
দুর্ভাগ্যক্রমে এই ধরণের সমস্ত মান ধরণের ব্যতীত আর তেমন একটা মিল নেই। তবে দীর্ঘ স্যুইচ-কেস এড়াতে আপনি এই সমস্ত ধরণের সাথে কেবল একটি পঠনযোগ্য তালিকাটি সংজ্ঞায়িত করতে পারেন এবং তারপরে প্রদত্ত প্রকারটি তালিকার ভিতরে রয়েছে কিনা তা পরীক্ষা করে দেখতে পারেন।
এগুলি সমস্ত মান ধরণের (বুল এবং সম্ভবত এনাম বাদে)। সুতরাং আপনি সহজভাবে ব্যবহার করতে পারেন:
bool IsNumberic(object o)
{
return (o is System.ValueType && !(o is System.Boolean) && !(o is System.Enum))
}
struct... আমি মনে করি না এটি আপনি চান।
সম্পাদনা: ঠিক আছে, আমি আরও পারফরম্যান্ট হতে নীচের কোডটি সংশোধন করেছি এবং তারপরে @ হুগো পোস্ট করা পরীক্ষাগুলি এর বিরুদ্ধে চালিয়েছি। গতি @ হুগো এর আইএফ তার অনুক্রমের শেষ দশক (দশমিক) ব্যবহার করে সমান হয়। তবে যদি প্রথম আইটেমটি 'বাইট' ব্যবহার করেন তবে তিনি তার পিষ্টকটি গ্রহণ করেন, তবে পারফরম্যান্সের ক্ষেত্রে বিষয়টি পরিষ্কারভাবে অর্ডার করুন। যদিও নীচের কোডটি ব্যবহার করা আরও সহজ এবং এটির দামের সাথে আরও সামঞ্জস্যপূর্ণ, তবে এটি রক্ষণাবেক্ষণযোগ্য বা ভবিষ্যতের প্রমাণ-সক্ষম নয়।
টাইপ.গেটটাইপকোড () থেকে কনভার্ট.গেটটাইপকোড () থেকে পরিবর্তন প্রায় 25%, ভিএস এনাম.পার্স () যা 10 গুণ ধীর গতির মত পারফরম্যান্সকে দ্রুতগতিতে দেখায় like
আমি জানি এই পোস্টটি পুরানো তবে যদি টাইপকোড এনাম পদ্ধতিটি ব্যবহার করা হয় তবে সবচেয়ে সহজ (এবং সম্ভবত সবচেয়ে সস্তা) এরকম কিছু হবে:
public static bool IsNumericType(this object o)
{
var t = (byte)Convert.GetTypeCode(o);
return t > 4 && t < 16;
}
টাইপকোডের জন্য নিম্নলিখিত এনাম সংজ্ঞা দেওয়া:
public enum TypeCode
{
Empty = 0,
Object = 1,
DBNull = 2,
Boolean = 3,
Char = 4,
SByte = 5,
Byte = 6,
Int16 = 7,
UInt16 = 8,
Int32 = 9,
UInt32 = 10,
Int64 = 11,
UInt64 = 12,
Single = 13,
Double = 14,
Decimal = 15,
DateTime = 16,
String = 18
}
আমি এটি পুরোপুরি পরীক্ষা করে দেখিনি, তবে মৌলিক সি # সংখ্যাগত ধরণের জন্য, এটি এটি আবৃত মনে হবে। যাইহোক, @ জোনস্কিট যেমন উল্লেখ করেছেন, এই এনামটি .NET রাস্তায় যোগ করা অতিরিক্ত ধরণের জন্য আপডেট করা হয়নি।
ওহো! প্রশ্ন ভুল! ব্যক্তিগতভাবে, স্কিটির সাথে রোল করবে ।
এইচআরএম, শোনাচ্ছে আপনি নিজের ডেটা DoSomethingচালু করতে চান Type। আপনি যা করতে পারেন তা নীচে রয়েছে
public class MyClass
{
private readonly Dictionary<Type, Func<SomeResult, object>> _map =
new Dictionary<Type, Func<SomeResult, object>> ();
public MyClass ()
{
_map.Add (typeof (int), o => return SomeTypeSafeMethod ((int)(o)));
}
public SomeResult DoSomething<T>(T numericValue)
{
Type valueType = typeof (T);
if (!_map.Contains (valueType))
{
throw new NotSupportedException (
string.Format (
"Does not support Type [{0}].", valueType.Name));
}
SomeResult result = _map[valueType] (numericValue);
return result;
}
}