স্ট্রিংকে নলাবদ্ধ প্রকরণে রূপান্তর করুন (int, ডাবল, ইত্যাদি ...)


137

আমি কিছু ডেটা রূপান্তর করার চেষ্টা করছি। দুর্ভাগ্যক্রমে, বেশিরভাগ ডেটা স্ট্রিংগুলিতে থাকে, যেখানে এটি ইনট বা ডাবল ইত্যাদি হওয়া উচিত ...

আমি যা পেয়েছি তা হ'ল এরকম:

double? amount = Convert.ToDouble(strAmount);

এই পদ্ধতির সাথে সমস্যাটি হল যদি স্ট্রমাউন্টটি খালি থাকে, যদি এটি খালি হয় তবে আমি এটির পরিমাণটি শূন্য হতে চাই, সুতরাং যখন আমি এটি ডাটাবেসে যুক্ত করব তখন কলামটি বাতিল হবে। সুতরাং আমি এই লেখা শেষ:

double? amount = null;
if(strAmount.Trim().Length>0)
{
    amount = Convert.ToDouble(strAmount);
}

এখন এটি সূক্ষ্মভাবে কাজ করে তবে আমার কাছে এখন একের পরিবর্তে পাঁচটি লাইন কোড রয়েছে। এটি জিনিসগুলিকে পড়া আরও জটিল করে তোলে, বিশেষত যখন আমার কাছে রূপান্তর করতে প্রচুর পরিমাণে কলাম থাকে।

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

public static class GenericExtension
{
    public static Nullable<T> ConvertToNullable<T>(this string s, T type) where T: struct
    {
        if (s.Trim().Length > 0)
        {
            return (Nullable<T>)s;
        }
        return null;
    }
}

তবে আমি ত্রুটিটি পেয়েছি: টাইপ 'স্ট্রিং' কে 'টি' তে রূপান্তর করতে পারি না?

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


উত্তর:


157

আরেকটি বিষয় মনে রাখবেন যে স্ট্রিংটি নিজেই নালাগুলি হতে পারে।

public static Nullable<T> ToNullable<T>(this string s) where T: struct
{
    Nullable<T> result = new Nullable<T>();
    try
    {
        if (!string.IsNullOrEmpty(s) && s.Trim().Length > 0)
        {
            TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
            result = (T)conv.ConvertFrom(s);
        }
    }
    catch { } 
    return result;
}

2
"টি টাইপ" প্যারামিটারটি ব্যবহার না করার কারণে আপনি বাদ দিতে পারেন।
মাইকেল Meadows

1
+1, শুধু আমাকে এটি মারধর। একটি ছোট্ট নিটপিক: রূপান্তরিত মানটি ফলাফলের জন্য নয়, ফলাফলের জন্য সরাসরি বরাদ্দ করা দরকার V মূল্য। উদাহরণস্বরূপ, "ফলাফল = (টি) রূপান্তর। কনভার্টফ্রম (গুলি);"।
লুক এইচ

20
এই string.IsNullOrWhiteSpace () সঙ্গে একটি বিট সরলীকৃত যাবে যদি আপনি .Net4 ব্যবহার
Sergej Andrejev

1
@andrefadila - ব্যবহারের জন্য: স্ট্রিং স্যাম্পেলভেেন্ডারআইডি = ""; int? vendorId = saltVendorId.ToNullable <int> ();
মিনার্ভা

1
কলটি কনভেন্টফ্রোম কোনও ক্ষুদ্র প্রকারের টি তে রূপান্তরিত করে না যা এই ফাংশনটিকে কিছুটা স্বজ্ঞাত করে তোলে। এই ফাংশনটিতে আপনার চেষ্টা করার দরকার নেই। এই তিনটি কোডের কোড এটিকে সমস্ত করে তোলে: যদি (স্ট্রিং.আইসনালআরওহাইটস্পেস (স্ট্রিংঅবজেক্ট)) নাল ফিরে আসে; var conv = TypeDescriptor.GetConverter (typof (T)); রিটার্ন (টি?) কনভেন্টফ্রোম (স্ট্রিংওজেক্ট);
ডেভিড

54

আপনি নীচের এক্সটেনশন পদ্ধতিটি ব্যবহার করে দেখতে পারেন:

public static T? GetValueOrNull<T>(this string valueAsString)
    where T : struct 
{
    if (string.IsNullOrEmpty(valueAsString))
        return null;
    return (T) Convert.ChangeType(valueAsString, typeof(T));
}

এইভাবে আপনি এটি করতে পারেন:

double? amount = strAmount.GetValueOrNull<double>();
int? amount = strAmount.GetValueOrNull<int>();
decimal? amount = strAmount.GetValueOrNull<decimal>();

3
আইএমএইচও এটি সমস্যার সর্বাধিক মার্জিত সমাধান
জাফিরো

4
আসলে .. এই সমাধান কাজ করে না। চ্যাঞ্জাইপ টাইপগুলি ধরণের আকারে রূপান্তর করে না। পরিবর্তে টাইপকনভার্টারটি ব্যবহার করুন
অ্যারেএনএইচএস

এটাই আমার জানা দরকার ... কনভার্ট.চেঞ্জটাইপ-পদ্ধতিটি ব্যবহার করার সময় আমাকে অন্তর্নিহিত ধরণের একটি নালাই-টাইপ ব্যবহার করতে হবে। কারণ এটি প্যারামিটার রূপান্তরকরণ টাইপের জন্য নুলাবল-প্রকারের সাথে কাজ করে না।
মার্কাস.ডি

27

এই সম্পর্কে কি:


double? amount = string.IsNullOrEmpty(strAmount) ? (double?)null : Convert.ToDouble(strAmount);

অবশ্যই, এটি রূপান্তর ব্যর্থতার বিষয়টি বিবেচনায় নেয় না।


আপনি যদি রিটার্ন মানগুলির দুটিকে দ্বিগুণ করেন? (বা ইন্ট ?, ইত্যাদি), তাহলে এটি তাদের চূড়ান্ত ডাবলে রূপান্তর করতে সক্ষম হবে ?. উপরের পরিবর্তনটি দেখুন।
15

এর জন্যে দুঃখিত. সংকলক আর্তনাদ না করা পর্যন্ত কাস্ট সর্বদা ভুলে যান। :)
জন ক্রাফট

আপনি যদি শূন্য না হন এবং আপনি পরিমাণ চেষ্টা করেন তবে এটি ব্যর্থ হবে asহাসভ্যালু এবং পরিমাণটিকে ভের হিসাবে ঘোষণা করুন।
স্টিভ

23

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

আমি এটি প্রায় এক বছর ধরে কয়েক ডজন উত্পাদন প্রোগ্রামে ব্যবহার করে আসছি, তাই এটি বেশ শক্ত হওয়া উচিত।

    public static T To<T>(this IConvertible obj)
    {
        Type t = typeof(T);

        if (t.IsGenericType
            && (t.GetGenericTypeDefinition() == typeof(Nullable<>)))
        {
            if (obj == null)
            {
                return (T)(object)null;
            }
            else
            {
                return (T)Convert.ChangeType(obj, Nullable.GetUnderlyingType(t));
            }
        }
        else
        {
            return (T)Convert.ChangeType(obj, t);
        }
    }

    public static T ToOrDefault<T>
                 (this IConvertible obj)
    {
        try
        {
            return To<T>(obj);
        }
        catch
        {
            return default(T);
        }
    }

    public static bool ToOrDefault<T>
                        (this IConvertible obj,
                         out T newObj)
    {
        try
        {
            newObj = To<T>(obj);
            return true;
        }
        catch
        {
            newObj = default(T);
            return false;
        }
    }

    public static T ToOrOther<T>
                           (this IConvertible obj,
                           T other)
    {
        try
        {
            return To<T>(obj);
        }
        catch
        {
            return other;
        }
    }

    public static bool ToOrOther<T>
                             (this IConvertible obj,
                             out T newObj,
                             T other)
    {
        try
        {
            newObj = To<T>(obj);
            return true;
        }
        catch
        {
            newObj = other;
            return false;
        }
    }

    public static T ToOrNull<T>
                          (this IConvertible obj)
                          where T : class
    {
        try
        {
            return To<T>(obj);
        }
        catch
        {
            return null;
        }
    }

    public static bool ToOrNull<T>
                      (this IConvertible obj,
                      out T newObj)
                      where T : class
    {
        try
        {
            newObj = To<T>(obj);
            return true;
        }
        catch
        {
            newObj = null;
            return false;
        }
    }

2
আমি মনে করি না যে সমস্ত রূপান্তর ত্রুটি উপেক্ষা করা সঠিক কাজ। এছাড়াও আপনার সম্ভবত সব ধরণের ব্যতিক্রম গ্রাস করা উচিত নয়। OutOfMemoryExceptionআপনি যদি ব্যতিক্রম ধরণের নির্দিষ্ট সেটটিতে সংকুচিত করতে না পারেন তবে কমপক্ষে পুনরায় নিক্ষেপ করুন ।
পল গ্রোক 24'13

9

আপনি চেষ্টা করতে পারেন:

TypeConverter conv = TypeDescriptor.GetConverter(typeof(int));
conv.ConvertFrom(mystring);

আপনার নিজের নাল চেক করুন এবং int?প্রয়োজনে ফিরে যান । আপনি এটি একটি মোড়ানো করতে চাইবেনtry {}


6

এটি একটি শট দিন ...

public delegate bool TryParseDelegate<T>(string data, out T output);

public static T? ToNullablePrimitive<T>(this string data, 
    TryParseDelegate<T> func) where T:struct
{
    string.IsNullOrEmpty(data) return null;

    T output;

    if (func(data, out output))
    {
        return (T?)output;
    }

    return null;
}

তারপরে এটিকে কল করুন ...

void doStuff()
{
    string foo = "1.0";

    double? myDouble = foo.ToNullablePrimitive<double>(double.TryParse);

    foo = "1";

    int? myInt = foo.ToNullablePrimitive<int>(int.TryParse);

    foo = "haha";

    int? myInt2 = foo.ToNullablePrimitive<int>(int.TryParse);
}

6

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

    /// <summary>
    /// Converts a string to the specified nullable type.
    /// </summary>
    /// <typeparam name="T">The type to convert to</typeparam>
    /// <param name="s">The string to convert</param>
    /// <returns>The nullable output</returns>
    public static T? ToNullable<T>(this string s) where T : struct
    {
        if (string.IsNullOrWhiteSpace(s))
            return null;

        TypeConverter conv = TypeDescriptor.GetConverter(typeof (T));
        return (T) conv.ConvertFrom(s);
    }

    /// <summary>
    /// Attempts to convert a string to the specified nullable primative.
    /// </summary>
    /// <typeparam name="T">The primitive type to convert to</typeparam>
    /// <param name="data">The string to convert</param>
    /// <param name="output">The nullable output</param>
    /// <returns>
    /// True if conversion is successfull, false otherwise.  Null and whitespace will
    /// be converted to null and return true.
    /// </returns>
    public static bool TryParseNullable<T>(this string data, out T? output) where T : struct
    {
        try
        {
            output = data.ToNullable<T>();
            return true;
        }
        catch
        {
            output = null;
            return false;
        }
    }

5

আপনি অবজেক্টগুলির সাথে নিম্নলিখিতটি ব্যবহার করতে পারেন, দুর্ভাগ্যক্রমে এটি স্ট্রিংগুলির সাথে কাজ করে না।

double? amount = (double?)someObject;

আমি এটি কোনও সম্পত্তিতে (একটি বেস পৃষ্ঠায়) সেশন ভেরিয়েবল মোড়ানোর জন্য ব্যবহার করি .. সুতরাং আমার আসল ব্যবহার হ'ল (আমার বেস পৃষ্ঠায়):

public int? OrganisationID
{
    get { return (int?)Session[Constants.Session_Key_OrganisationID]; }
    set { Session[Constants.Session_Key_OrganisationID] = value; }
}

আমি পৃষ্ঠা যুক্তিতে নাল জন্য পরীক্ষা করতে সক্ষম:

if (base.OrganisationID == null)
    // do stuff

হাই ধন্যবাদ এটি আমার জন্য এটি সমাধান। এফওয়াইআই আমি ভিবি.এনইটি ব্যবহার করছিলাম, এবং ভিবি সমতুল্য CType(Object, Nullable(Of Double))স্ট্রিংগুলির সাথে ভাল কাজ করে
রায়জিনজ

আপনার প্রথম উদাহরণের এমন কোনও সংস্করণ আছে যা স্ট্রিংয়ের সাহায্যে ব্যবহার করা যেতে পারে?
ওয়াজ

3

এই সমস্যা এড়ানোর কোনো উপায় নেই। যুক্তিযুক্ত, পাশাপাশি আপনার পদ্ধতিটি তর্ক হিসাবে কেবলমাত্র মান ধরণের ব্যবহারে সীমাবদ্ধ। স্ট্রিং একটি রেফারেন্স টাইপ এবং তাই এই ঘোষণার সাথে বেমানান।



3

একটি জেনেরিক সমাধান রয়েছে (যে কোনও ধরণের জন্য)। ব্যবহারযোগ্যতা ভাল, তবে প্রয়োগের উন্নতি করা উচিত: http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/

এটি আপনাকে এর মতো খুব পরিষ্কার কোড লিখতে দেয়:

string value = null;
int? x = value.ConvertOrDefault<int?>();

এবং যদিও:

object obj = 1;  

string value = null;
int x = 5;
if (value.TryConvert(out x))
    Console.WriteLine("TryConvert example: " + x); 

bool boolean = "false".ConvertOrDefault<bool>();
bool? nullableBoolean = "".ConvertOrDefault<bool?>();
int integer = obj.ConvertOrDefault<int>();
int negativeInteger = "-12123".ConvertOrDefault<int>();
int? nullableInteger = value.ConvertOrDefault<int?>();
MyEnum enumValue = "SecondValue".ConvertOrDefault<MyEnum>();

MyObjectBase myObject = new MyObjectClassA();
MyObjectClassA myObjectClassA = myObject.ConvertOrDefault<MyObjectClassA>();

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

1
ঠিক আছে, প্রথমে আপনার উত্তরটির সাথে খুব খারাপ কিছু আছে এবং এটি "আপনি অন্য সমস্ত উত্তর ভুলতে পারেন"। যা সত্য হলেও ভুল হবে (যা তা নয়)। এবং "সার্বজনীন সমাধান" এর মধ্যে যা ভুল তা হ'ল এটি খারাপ পারফরমেন্সে পূর্ণ typeName.IndexOf? ( সত্যই?) এবং শ্বাসরোধের আচরণ (দেখানো TryConvertফাংশন এমনকি নাল মানগুলিও সঠিকভাবে পরিচালনা করে না)।
পল গ্রোক 24'13

3

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

public static Nullable<T> ToNullable<T>(this string s) where T: struct
{
    if (!string.IsNullOrWhiteSpace(s))
    {
        TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));

        return (T)conv.ConvertFrom(s);
    }

    return default(Nullable<T>);
}

2

অসাধারণ ধরণের জন্য আমার উদাহরণ:

private object ConvertNullable(object value, Type nullableType)
{
    Type resultType = typeof(Nullable<>).MakeGenericType(nullableType.GetGenericArguments());
    return Activator.CreateInstance(resultType, Convert.ChangeType(value, nullableType.GetGenericArguments()[0]));
}

...

Type anonimousType = typeof(Nullable<int>);
object nullableInt1 = ConvertNullable("5", anonimousType);
// or evident Type
Nullable<int> nullableInt2 = (Nullable<int>)ConvertNullable("5", typeof(Nullable<int>));

2

অন্য একটি প্রকরণ। এইটা

  • ব্যতিক্রম গ্রাস করে না
  • NotSupportedExceptionপ্রকারটি রূপান্তর করতে না পারলে একটি ছুড়ে দেয়string । উদাহরণস্বরূপ, কোনও ধরণের রূপান্তরকারী ছাড়াই একটি কাস্টম স্ট্রাক্ট।
  • অন্যথায় (T?)nullস্ট্রিং পার্স করতে ব্যর্থ হলে একটি প্রদান করে। নাল বা সাদা স্থান পরীক্ষা করার প্রয়োজন নেই check
using System.ComponentModel;

public static Nullable<T> ToNullable<T>(this string s) where T : struct
{
    var ret = new Nullable<T>();
    var conv = TypeDescriptor.GetConverter(typeof(T));

    if (!conv.CanConvertFrom(typeof(string)))
    {
        throw new NotSupportedException();
    }

    if (conv.IsValid(s))
    {
        ret = (T)conv.ConvertFrom(s);
    }

    return ret;
}

1

স্ট্যাকের সাথে আরও একটি অনুরূপ সমাধান যুক্ত করা যাক। এটিও এনামগুলিকে পার্স করে, এবং দেখতে সুন্দর লাগে। বেশ নিরাপদ.

/// <summary>
    /// <para>More convenient than using T.TryParse(string, out T). 
    /// Works with primitive types, structs, and enums.
    /// Tries to parse the string to an instance of the type specified.
    /// If the input cannot be parsed, null will be returned.
    /// </para>
    /// <para>
    /// If the value of the caller is null, null will be returned.
    /// So if you have "string s = null;" and then you try "s.ToNullable...",
    /// null will be returned. No null exception will be thrown. 
    /// </para>
    /// <author>Contributed by Taylor Love (Pangamma)</author>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="p_self"></param>
    /// <returns></returns>
    public static T? ToNullable<T>(this string p_self) where T : struct
    {
        if (!string.IsNullOrEmpty(p_self))
        {
            var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
            if (converter.IsValid(p_self)) return (T)converter.ConvertFromString(p_self);
            if (typeof(T).IsEnum) { T t; if (Enum.TryParse<T>(p_self, out t)) return t;}
        }

        return null;
    }

https://github.com/Pangamma/PangammaUtilities-CSharp/blob/master/PangammaUtilities/Extensions/ToNullableStringExtension.cs


0

" জোয়েল কোহোর্ন " প্রদত্ত জেনেরিক উত্তরটি ভাল।

তবে, সেগুলি GetConverter...বা try/catchব্লকগুলি ব্যবহার না করেই এটি অন্য উপায় ... (আমি নিশ্চিত নই তবে এটির কিছু ক্ষেত্রে আরও ভাল পারফরম্যান্স থাকতে পারে):

public static class StrToNumberExtensions
{
    public static short ToShort(this string s, short defaultValue = 0) => short.TryParse(s, out var v) ? v : defaultValue;
    public static int ToInt(this string s, int defaultValue = 0) => int.TryParse(s, out var v) ? v : defaultValue;
    public static long ToLong(this string s, long defaultValue = 0) => long.TryParse(s, out var v) ? v : defaultValue;
    public static decimal ToDecimal(this string s, decimal defaultValue = 0) => decimal.TryParse(s, out var v) ? v : defaultValue;
    public static float ToFloat(this string s, float defaultValue = 0) => float.TryParse(s, out var v) ? v : defaultValue;
    public static double ToDouble(this string s, double defaultValue = 0) => double.TryParse(s, out var v) ? v : defaultValue;

    public static short? ToshortNullable(this string s, short? defaultValue = null) => short.TryParse(s, out var v) ? v : defaultValue;
    public static int? ToIntNullable(this string s, int? defaultValue = null) => int.TryParse(s, out var v) ? v : defaultValue;
    public static long? ToLongNullable(this string s, long? defaultValue = null) => long.TryParse(s, out var v) ? v : defaultValue;
    public static decimal? ToDecimalNullable(this string s, decimal? defaultValue = null) => decimal.TryParse(s, out var v) ? v : defaultValue;
    public static float? ToFloatNullable(this string s, float? defaultValue = null) => float.TryParse(s, out var v) ? v : defaultValue;
    public static double? ToDoubleNullable(this string s, double? defaultValue = null) => double.TryParse(s, out var v) ? v : defaultValue;
}

ব্যবহার নিম্নলিখিত:

var x1 = "123".ToInt(); //123
var x2 = "abc".ToInt(); //0
var x3 = "abc".ToIntNullable(); // (int?)null 
int x4 = ((string)null).ToInt(-1); // -1
int x5 = "abc".ToInt(-1); // -1

var y = "19.50".ToDecimal(); //19.50

var z1 = "invalid number string".ToDoubleNullable(); // (double?)null
var z2 = "invalid number string".ToDoubleNullable(0); // (double?)0

@ মাসিমিলিয়ানো ক্রাউস হতে পারে তবে এটি একটি সহজ 12 লাইনের কোড যা একবার লেখা হয়েছিল, তবে সমস্ত সময় ব্যবহার করে। এবং, যেমনটি আমি বলেছি, এটি TypeDescriptor.GetConverter... কোডগুলি ব্যবহার করার চেয়ে দ্রুত হওয়া উচিত / । এটি ঠিক অন্য একটি উপায়।
এস.স্পার্পোশন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.