জেনেরিক ট্রাই পার্সে


196

আমি একটি জেনেরিক এক্সটেনশান তৈরি করার চেষ্টা করছি যা 'ট্রাই পার্সে' ব্যবহার করে স্ট্রিং প্রদত্ত প্রকারের কিনা তা পরীক্ষা করে দেখার জন্য:

public static bool Is<T>(this string input)
{
    T notUsed;
    return T.TryParse(input, out notUsed);
}

এটি সংকলন করবে না কারণ এটি 'ট্রাইপার্স' প্রতীকটি সমাধান করতে পারে না

আমি যেমন বুঝতে পেরেছি, 'ট্রাইপার্স' কোনও ইন্টারফেসের অংশ নয়।

এটি কি আদৌ সম্ভব?

হালনাগাদ:

নীচের উত্তরগুলি ব্যবহার করে আমি এনেছি:

public static bool Is<T>(this string input)
{
    try
    {
        TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(input);
    }
    catch
    {
        return false;
    }

    return true;
}

এটি বেশ ভালভাবে কাজ করে তবে আমি মনে করি যে ব্যতিক্রমগুলি সেভাবে ব্যবহার করা আমার পক্ষে সঠিক মনে হয় না।

Update2:

জেনেরিক ব্যবহার না করে পাস করার ধরণের পরিবর্তন করা হয়েছে:

public static bool Is(this string input, Type targetType)
{
    try
    {
        TypeDescriptor.GetConverter(targetType).ConvertFromString(input);
        return true;
    }
    catch
    {
        return false;
    }
}

1
আমি মনে করি এই সাধারণ ক্ষেত্রে আপনাকে কেবল ব্যতিক্রমী ক্লেজটি মোকাবেলা করতে হবে। আপনি ইনটস বা ডাবলগুলির মতো জিনিসগুলি পরীক্ষা করতে এবং তারপরে নির্দিষ্ট ট্রাইপার্স পদ্ধতি ব্যবহার করতে পারেন তবে অন্য ধরণের ধরণের ক্ষেত্রে আপনাকে এখনও এটির পিছনে পড়তে হবে।
luke

1
জেনেরিক ব্যবহার অপ্রয়োজনীয়। পরামিতি হিসাবে কেবল টাইপ করুন। সর্বজনীন স্ট্যাটিক বুল হয় (এই স্ট্রিং ইনপুট, টাইপ টার্গেটটাইপ)। এইভাবে কল করাটিকে কিছুটা সুন্দর দেখাচ্ছে: x.Is (typof (int)) -VS- x.Is <int> ()
মাইকসিগ

2
রূপান্তরটিতে সমস্যা আছে কিনা তা যাচাই করার জন্য আপনার কনভার্টারে একটি ইসওয়ালিড পদ্ধতি রয়েছে। আমি নীচের পদ্ধতিটি ব্যবহার করেছি এবং ভাল কাজ করছে বলে মনে হচ্ছে। protected Boolean TryParse<T>(Object value, out T result) { result = default(T); var convertor = TypeDescriptor.GetConverter(typeof(T)); if (convertor == null || !convertor.IsValid(value)) { return false; } result = (T)convertor.ConvertFrom(value); return true; }
কাস্ত্রোএক্সএক্সএলএল

@ কাস্ট্রোএক্সএক্সএল এই প্রশ্নে আগ্রহ দেখানোর জন্য ধন্যবাদ, তবে আপনার পদ্ধতিটি বেশ কার্যকর হবে না কারণ আমি স্ট্রিংয়ের মানটি কোনও বস্তুর পরিবর্তে নির্দিষ্ট ধরণের কিনা তা পরীক্ষা করতে চেয়েছিলাম, যদিও আপনার পদ্ধতিটি বস্তুর ধরণের জন্য কার্যকর হবে (তবে হবে মোড়ানো আছে ConvertFrom(value)একটি পদ্ধতি try-catchব্লক ব্যতিক্রম ধরা।
পিয়ার্স ম্যাইইয়ার্স

2
(টার্গেটটাইপ == নাল) আপনার পরীক্ষা করা উচিত কারণ আপনার কোডে এটির প্রথম ব্যবহার নিক্ষেপ করতে পারে তবে এই ব্যতিক্রমটি আপনার ধরা পড়ে গ্রাস করবে।
নিক স্ট্রাপ্যাট

উত্তর:


183

আপনার টাইপডেস্ক্রিপ্টর ক্লাসটি ব্যবহার করা উচিত :

public static T Convert<T>(this string input)
{
    try
    {
        var converter = TypeDescriptor.GetConverter(typeof(T));
        if(converter != null)
        {
            // Cast ConvertFromString(string text) : object to (T)
            return (T)converter.ConvertFromString(input);
        }
        return default(T);
    }
    catch (NotSupportedException)
    {
        return default(T);
    }
}

3
পুনরুত্থানের জন্য দুঃখিত, তবে কী getConverter শূন্য ফিরে আসে? আমি মনে করি এটি যদি হয় তবে সম্ভবত নীরবে চুপচাপ ব্যর্থ হওয়ার পরিবর্তে কোনও ব্যতিক্রম ছুঁড়ে ফেলা উচিত এবং অন্য কোনও কিছু ফিরিয়ে দেওয়া উচিত। যখন আমি এটি আমার নিজের ক্লাসে চেষ্টা করেছি (যার মধ্যে আমি টাইপ কনভার্টারের সংজ্ঞা দিইনি), আমি গেটকনভার্টারের কাছ থেকে একটি রূপান্তরকারী পেয়েছিলাম তবে কনভার্টফ্র্যামস্ট্রিং একটি নটসপোর্টড এক্সসেপশন ছুঁড়ে ফেলেছে।
ব্যবহারকারী420667

3
@ ইউজার ৪২০667,, আমি বিশ্বাস করি স্ট্রিং থেকে রূপান্তর করার চেষ্টা করার আগে আপনার CanConvertFrom (typof (স্ট্রিং)) এর ফলাফল পরীক্ষা করা উচিত। TypeConverter স্ট্রিং থেকে রূপান্তর সমর্থন করতে পারে না।
রূবেণ বন্ড

3
আপনি যোগ করতে পারেন যদি (typeof (টি) .IsEnum) {ফিরতি (টি) Enum.Parse (typeof (টি), ইনপুট); ver [সমস্ত এনাম প্রকারের জন্য মোটামুটি জেনেরিক শর্টকাট হিসাবে] কনভার্টার পাওয়ার আগে। আমি মনে করি এটি আরও জটিল ধরণের বিপরীতে আপনি কতবার এনাম টাইপ করবেন তার উপর নির্ভর করে।
জেসি চিশলম

10
আমি বুঝতে পারছি না কেন এটি উত্তর হিসাবে চিহ্নিত হয়েছে এবং যখন এটি অনুরোধ করা হয়েছিল তা বাস্তবায়ন করে না কেন: জেনেরিক চেষ্টা করুন পার্স। ট্রাইপার্স পদ্ধতিগুলির মূল উদ্দেশ্যটি হল পার্সিং সম্পাদন করার চেষ্টা করার সময় তারা ব্যতিক্রমগুলি ছুঁড়ে না ফেলে এবং পার্সিং ব্যর্থ হয়ে যায় এবং এই সমাধানটি কেবল এটি সরবরাহ করতে ব্যর্থ হলে পারফরম্যান্সের উপর খুব কম প্রভাব ফেলে।
ফ্লোরিন ডুমিট্রেস্কু

2
একটি সমস্যা ডাব্লু / এটি হ'ল টি যদি কোন অন্তর্নিহিত হয় এবং ইনপুটটি ইনট্যাক্স-ম্যাক্সভ্যালুয়ের চেয়ে বড় হয় তবে এটি একটি সিস্টেম.এক্সেপশন ডাব্লু / সিস্টেম.অন্তরের ব্যতিক্রম হিসাবে .ভারফ্লোএক্সেপশন নিক্ষেপ করবে। সুতরাং যদি আপনি কোনও ওভারফ্লো এক্সপশন আশা করে থাকেন, তবে আপনি ফেলে দেওয়া ব্যতিক্রম সম্পর্কে জিজ্ঞাসাবাদ না করলে আপনি তা পাবেন না। কারণটি হ'ল কনভার্টফ্রম স্ট্রিং একটি ওভারফ্লো এক্সেক্সশন ছুড়ে দেয় এবং তারপরে টিতে কাস্ট করা একটি সিস্টেম নিক্ষেপ করে x
ট্রেভর

78

আমার সম্প্রতি একটি জেনেরিক ট্রাইপার্স প্রয়োজন। আমি যা এলাম তা এখানে;

public static T? TryParse<T>(string value, TryParseHandler<T> handler) where T : struct
{
    if (String.IsNullOrEmpty(value))
        return null;
    T result;
    if (handler(value, out result))
        return result;
    Trace.TraceWarning("Invalid value '{0}'", value);
    return null;
}

public delegate bool TryParseHandler<T>(string value, out T result);

তারপরে এটি কেবল এইভাবে কল করার বিষয়:

var value = TryParse<int>("123", int.TryParse);
var value2 = TryParse<decimal>("123.123", decimal.TryParse);

3
ঠিক কয়েক মাস পরে এই পোস্টটি জুড়ে এসে আবার ব্যবহার করার সময় লক্ষ্য করা গেছে যে পদ্ধতিটি Tহ্যান্ডলার থেকে অনুমান করতে পারে না এবং আমরা Tযখন এটি কল করি তখন আমাদের স্পষ্টভাবে উল্লেখ করতে হবে। আমি কৌতুহলী, কেন এটি অনুমান করতে পারি না T?
নিক স্ট্রাপ্যাট

25
আপনি কেন এই ফাংশনটি ব্যবহার করতে চান? আপনি যদি জানেন যে কোন ফাংশনটি মানটিকে বিশ্লেষণ করতে কল করতে হবে, তবে কেন কেবল এটি সরাসরি কল করবেন না? এটি ইতিমধ্যে সঠিক ইনপুট প্রকারটি জানে এবং জেনেরিকের প্রয়োজন নেই Try ট্রাইপার্সহ্যান্ডলার ছাড়া এই সমাধানটি ধরণের জন্য কাজ করে না।
xxbbcc

2
@xxbbcc: আমি এই ফাংশনটি ব্যবহার করতে চাই কারণ ট্রাই পার্সে এমন একটি বুলিয়ান দেয় যা পার্স সফল হয়েছিল কিনা তা বোঝায়। এটি আউটপুট প্যারামিটারের মাধ্যমে আপনার পার্সড মানটি প্রদান করে। কখনও কখনও আমি SomeMethod(TryParse<int>(DollarTextbox.Text, int.TryParse))ফলাফলটি আউটপুট ভেরিয়েবল না তৈরি করে এই জাতীয় কিছু করতে চাই int.TryParse। যাইহোক, ফাংশনটি ধরণের অনুধাবন করা সম্পর্কে নিকের অনুভূতির সাথে আমি একমত নই।
ওয়াল্টার স্টাবোসজ

1
খুব দক্ষ পদ্ধতি। অত্যন্ত বাঞ্ছনীয়.
ভ্লাদিমির কোকজানিক

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

33

প্রবাহ নিয়ন্ত্রণের জন্য ট্র্যাচ / ক্যাচ ব্যবহার করা একটি ভয়ানক নীতি। ব্যতিক্রম ছড়িয়ে যাওয়ার সময় রানটাইম যখন কাজ করে তখন একটি ব্যতিক্রম কর্মক্ষমতা পিছিয়ে দেয়। পরিবর্তে রূপান্তর করার আগে ডেটা বৈধ করুন।

var attemptedValue = "asdfasdsd";
var type = typeof(int);
var converter = TypeDescriptor.GetConverter(type);
if (converter != null &&  converter.IsValid(attemptedValue))
    return converter.ConvertFromString(attemptedValue);
else
    return Activator.CreateInstance(type);

2
আমি একটি রিশার্পার নোটিশ পাচ্ছি converter != nullযা সর্বদা সত্য, তাই এটি কোড থেকে সরানো যায়।
এরিক

5
@ এরিক আমি সবসময় এই রিসার্পার সতর্কতাগুলিতে বিশ্বাস করি না। রানটাইমের সময় কী ঘটে তা প্রায়শই তারা দেখতে পায় না।
অধ্যাপক

1
@ProfK দুটিই MSDN বলে না এটি নাল ফিরে আসতে পারেন msdn.microsoft.com/en-us/library/ewtxwhzx.aspx
Danio

@दानিও আমি সাধারণভাবে এই জাতীয় আর # সতর্কতার সাথে আমার অভিজ্ঞতাটি ভাগ করে নিচ্ছি। আমি অবশ্যই বোঝাতে পারি নি যে এই ক্ষেত্রে এটি ভুল ছিল।
প্রোফেক

14

যদি আপনি ট্রাইপার্স ব্যবহার করে সেট করা থাকে তবে আপনি প্রতিবিম্বটি ব্যবহার করতে পারেন এবং এটি এর মতো করে করতে পারেন:

public static bool Is<T>(this string input)
{
    var type = typeof (T);
    var temp = default(T);
    var method = type.GetMethod(
        "TryParse",
        new[]
            {
                typeof (string),
                Type.GetType(string.Format("{0}&", type.FullName))
            });
    return (bool) method.Invoke(null, new object[] {input, temp});
}

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

6
চমৎকার সমাধান, তবে প্রতিবিম্বের সাথে জড়িত যে কোনও উত্তরের (বিশেষত কোনও ইউটিলিটি পদ্ধতিতে যা সহজেই কোনও অভ্যন্তরীণ লুপ থেকে ডাকতে পারে) পারফরম্যান্স সম্পর্কে অস্বীকৃতি দাবি করতে হবে। দেখুন: স্ট্যাকওভারফ্লো.com
প্যাট্রিক এম

দীর্ঘশ্বাস. সুতরাং পছন্দগুলি হ'ল (১) কোড প্রবাহ নিয়ন্ত্রণের ক্ষেত্রে ব্যতিক্রমগুলি ব্যবহার করুন, (২) এর গতির ব্যয়ের সাথে প্রতিচ্ছবি ব্যবহার করুন। আমি @ পাইয়ারমায়ার্সের সাথে একমত - কোনও পছন্দই আদর্শ নয়। তারা উভয় ভাল জিনিস। :)
জেসি চিশলম

আমার মনে হয় আপনি প্রতিস্থাপন করতে পারেন Type.GetType(string.Format(...))সঙ্গে type.MakeByRefType()
ড্র নোকস

3
পদ্ধতিটি কেবল প্রতি কল প্রতি একবার নয়, প্রতি টাইপ প্রতি একবার প্রতিবিম্বিত করা প্রয়োজন। যদি আপনি এটিকে একটি স্ট্যাটিক সদস্য ভেরিয়েবল সহ জেনেরিক ক্লাস করেন তবে আপনি প্রথম প্রতিফলনের আউটপুটটিকে পুনরায় ব্যবহার করতে পারেন।
অ্যান্ড্রু হিল

7

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

    public static bool TryParse<t>(this string Value, out t result)
    {
        return TryParser<t>.TryParse(Value.SafeTrim(), out result);
    }
    private delegate bool TryParseDelegate<t>(string value, out t result);
    private static class TryParser<T>
    {
        private static TryParseDelegate<T> parser;
        // Static constructor:
        static TryParser()
        {
            Type t = typeof(T);
            if (t.IsEnum)
                AssignClass<T>(GetEnumTryParse<T>());
            else if (t == typeof(bool) || t == typeof(bool?))
                AssignStruct<bool>(bool.TryParse);
            else if (t == typeof(byte) || t == typeof(byte?))
                AssignStruct<byte>(byte.TryParse);
            else if (t == typeof(short) || t == typeof(short?))
                AssignStruct<short>(short.TryParse);
            else if (t == typeof(char) || t == typeof(char?))
                AssignStruct<char>(char.TryParse);
            else if (t == typeof(int) || t == typeof(int?))
                AssignStruct<int>(int.TryParse);
            else if (t == typeof(long) || t == typeof(long?))
                AssignStruct<long>(long.TryParse);
            else if (t == typeof(sbyte) || t == typeof(sbyte?))
                AssignStruct<sbyte>(sbyte.TryParse);
            else if (t == typeof(ushort) || t == typeof(ushort?))
                AssignStruct<ushort>(ushort.TryParse);
            else if (t == typeof(uint) || t == typeof(uint?))
                AssignStruct<uint>(uint.TryParse);
            else if (t == typeof(ulong) || t == typeof(ulong?))
                AssignStruct<ulong>(ulong.TryParse);
            else if (t == typeof(decimal) || t == typeof(decimal?))
                AssignStruct<decimal>(decimal.TryParse);
            else if (t == typeof(float) || t == typeof(float?))
                AssignStruct<float>(float.TryParse);
            else if (t == typeof(double) || t == typeof(double?))
                AssignStruct<double>(double.TryParse);
            else if (t == typeof(DateTime) || t == typeof(DateTime?))
                AssignStruct<DateTime>(DateTime.TryParse);
            else if (t == typeof(TimeSpan) || t == typeof(TimeSpan?))
                AssignStruct<TimeSpan>(TimeSpan.TryParse);
            else if (t == typeof(Guid) || t == typeof(Guid?))
                AssignStruct<Guid>(Guid.TryParse);
            else if (t == typeof(Version))
                AssignClass<Version>(Version.TryParse);
        }
        private static void AssignStruct<t>(TryParseDelegate<t> del)
            where t: struct
        {
            TryParser<t>.parser = del;
            if (typeof(t).IsGenericType
                && typeof(t).GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                return;
            }
            AssignClass<t?>(TryParseNullable<t>);
        }
        private static void AssignClass<t>(TryParseDelegate<t> del)
        {
            TryParser<t>.parser = del;
        }
        public static bool TryParse(string Value, out T Result)
        {
            if (parser == null)
            {
                Result = default(T);
                return false;
            }
            return parser(Value, out Result);
        }
    }

    private static bool TryParseEnum<t>(this string Value, out t result)
    {
        try
        {
            object temp = Enum.Parse(typeof(t), Value, true);
            if (temp is t)
            {
                result = (t)temp;
                return true;
            }
        }
        catch
        {
        }
        result = default(t);
        return false;
    }
    private static MethodInfo EnumTryParseMethod;
    private static TryParseDelegate<t> GetEnumTryParse<t>()
    {
        Type type = typeof(t);

        if (EnumTryParseMethod == null)
        {
            var methods = typeof(Enum).GetMethods(
                BindingFlags.Public | BindingFlags.Static);
            foreach (var method in methods)
                if (method.Name == "TryParse"
                    && method.IsGenericMethodDefinition
                    && method.GetParameters().Length == 2
                    && method.GetParameters()[0].ParameterType == typeof(string))
                {
                    EnumTryParseMethod = method;
                    break;
                }
        }
        var result = Delegate.CreateDelegate(
            typeof(TryParseDelegate<t>),
            EnumTryParseMethod.MakeGenericMethod(type), false)
            as TryParseDelegate<t>;
        if (result == null)
            return TryParseEnum<t>;
        else
            return result;
    }

    private static bool TryParseNullable<t>(string Value, out t? Result)
        where t: struct
    {
        t temp;
        if (TryParser<t>.TryParse(Value, out temp))
        {
            Result = temp;
            return true;
        }
        else
        {
            Result = null;
            return false;
        }
    }

6

কিভাবে ভালো কিছু সম্পর্কে?

http://madskristensen.net/post/Universal-data-type-checker.aspx ( সংরক্ষণাগার )

/// <summary> 
/// Checks the specified value to see if it can be 
/// converted into the specified type. 
/// <remarks> 
/// The method supports all the primitive types of the CLR 
/// such as int, boolean, double, guid etc. as well as other 
/// simple types like Color and Unit and custom enum types. 
/// </remarks> 
/// </summary> 
/// <param name="value">The value to check.</param> 
/// <param name="type">The type that the value will be checked against.</param> 
/// <returns>True if the value can convert to the given type, otherwise false. </returns> 
public static bool CanConvert(string value, Type type) 
{ 
    if (string.IsNullOrEmpty(value) || type == null) return false;
    System.ComponentModel.TypeConverter conv = System.ComponentModel.TypeDescriptor.GetConverter(type);
    if (conv.CanConvertFrom(typeof(string)))
    { 
        try 
        {
            conv.ConvertFrom(value); 
            return true;
        } 
        catch 
        {
        } 
     } 
     return false;
  }

এটি খুব সহজেই একটি জেনেরিক পদ্ধতিতে রূপান্তরিত হতে পারে।

 public static bool Is<T>(this string value)
 {
    if (string.IsNullOrEmpty(value)) return false;
    var conv = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));

    if (conv.CanConvertFrom(typeof(string)))
    { 
        try 
        {
            conv.ConvertFrom(value); 
            return true;
        } 
        catch 
        {
        } 
     } 
     return false;
}

আপনি চেষ্টা ব্লক থেকে সত্য ফিরে আসেন বা ক্যাচ ব্লক থেকে মিথ্যা প্রত্যাবর্তন করেন কিনা তা বিবেচ্য নয়? আমি মনে করি না, তবে আমি এখনও মনে করি এইভাবে ব্যতিক্রমগুলি ব্যবহার করা আমার পক্ষে খারাপ লাগছে ...
পাইয়ার্স মায়ার্স

3
আপনি ক্যাচ ব্লক থেকে ফিরে আসেন কিনা তা বিবেচ্য নয়, এটি একই। BTW। সাধারণত এটা একটি জেনেরিক ধরা দফা আছে খারাপ হল: catch { }। তবে, এই ক্ষেত্রে কোনও বিকল্প নেই, কারণ রূপান্তর ত্রুটির ক্ষেত্রে .NET বেস ক্লাসটি BaseNumberConverterছুড়ে দেয় Exception। এটি অত্যন্ত দুর্ভাগ্যজনক। বাস্তবে এখনও বেশ কয়েকটি জায়গা রয়েছে যেখানে এই বেস টাইপটি ফেলে দেওয়া হয়েছিল। আশা করি মাইক্রোসফ্ট ফ্রেমওয়ার্কের ভবিষ্যতের সংস্করণে এগুলি ঠিক করবে।
স্টিভেন

ধন্যবাদ স্টিভেন, এটি আরও ভাল বলতে পারত না।
বব

রূপান্তরটির ফলাফলের কোনও ব্যবহারই করা হয়নি: কোডটি অতিরিক্ত কাজ is
বিলডব্লিউ

4

আপনি সাধারণ ধরণের ক্ষেত্রে এটি করতে পারবেন না।

আপনি যা করতে পারেন তা হ'ল একটি ইন্টারফেস ITryParsable তৈরি করা এবং এটি কাস্টম ধরণের জন্য ব্যবহার করুন যা এই ইন্টারফেসটি বাস্তবায়ন করে।

আমি অনুমান করি যে আপনি এটিকে মৌলিক ধরণের intএবং এর মতো ব্যবহার করতে চান DateTime। আপনি নতুন ইন্টারফেস প্রয়োগ করতে এই ধরণের পরিবর্তন করতে পারবেন না।


1
আমি ভাবছি এটি। নেট 4 এ গতিশীল কীওয়ার্ড ব্যবহার করে যদি কাজ করে?
পিয়েরে-আলাইন ভিজিয়েন্ট

@ পিয়ার: এটি সি # তে dynamicকিওয়ার্ড সহ ডিফল্টরূপে কাজ করবে না , কারণ এটি স্ট্যাটিক টাইপিংয়ে কাজ করবে না। আপনি নিজের ডায়নামিক অবজেক্ট তৈরি করতে পারেন যা এটি পরিচালনা করতে পারে তবে এটি ডিফল্ট নয়।
স্টিভেন

4

চার্লি ব্রাউন এখানে পোস্ট করা সমাধান দ্বারা অনুপ্রাণিত হয়ে, আমি প্রতিচ্ছবি ব্যবহার করে একটি জেনেরিক ট্রাইপার্স তৈরি করেছি যা allyচ্ছিকভাবে পার্স করা মানকে ছাড়িয়ে যায়:

/// <summary>
/// Tries to convert the specified string representation of a logical value to
/// its type T equivalent. A return value indicates whether the conversion
/// succeeded or failed.
/// </summary>
/// <typeparam name="T">The type to try and convert to.</typeparam>
/// <param name="value">A string containing the value to try and convert.</param>
/// <param name="result">If the conversion was successful, the converted value of type T.</param>
/// <returns>If value was converted successfully, true; otherwise false.</returns>
public static bool TryParse<T>(string value, out T result) where T : struct {
    var tryParseMethod = typeof(T).GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, null, new [] { typeof(string), typeof(T).MakeByRefType() }, null);
    var parameters = new object[] { value, null };

    var retVal = (bool)tryParseMethod.Invoke(null, parameters);

    result = (T)parameters[1];
    return retVal;
}

/// <summary>
/// Tries to convert the specified string representation of a logical value to
/// its type T equivalent. A return value indicates whether the conversion
/// succeeded or failed.
/// </summary>
/// <typeparam name="T">The type to try and convert to.</typeparam>
/// <param name="value">A string containing the value to try and convert.</param>
/// <returns>If value was converted successfully, true; otherwise false.</returns>
public static bool TryParse<T>(string value) where T : struct {
    T throwaway;
    var retVal = TryParse(value, out throwaway);
    return retVal;
}

এটি এভাবে বলা যেতে পারে:

string input = "123";
decimal myDecimal;

bool myIntSuccess = TryParse<int>(input);
bool myDecimalSuccess = TryParse<decimal>(input, out myDecimal);

আপডেট:
এছাড়াও YotaXP এর সমাধানটি যা আমি সত্যিই পছন্দ করি তার জন্য ধন্যবাদ, আমি এমন একটি সংস্করণ তৈরি করেছি যা এক্সটেনশন পদ্ধতিগুলি ব্যবহার করে না তবে এখনও একটি সিঙ্গলটন রয়েছে, প্রতিবিম্ব করার প্রয়োজন হ্রাস করুন:

/// <summary>
/// Provides some extra parsing functionality for value types.
/// </summary>
/// <typeparam name="T">The value type T to operate on.</typeparam>
public static class TryParseHelper<T> where T : struct {
    private delegate bool TryParseFunc(string str, out T result);

    private static TryParseFunc tryParseFuncCached;

    private static TryParseFunc tryParseCached {
        get {
            return tryParseFuncCached ?? (tryParseFuncCached = Delegate.CreateDelegate(typeof(TryParseFunc), typeof(T), "TryParse") as TryParseFunc);
        }
    }

    /// <summary>
    /// Tries to convert the specified string representation of a logical value to
    /// its type T equivalent. A return value indicates whether the conversion
    /// succeeded or failed.
    /// </summary>
    /// <param name="value">A string containing the value to try and convert.</param>
    /// <param name="result">If the conversion was successful, the converted value of type T.</param>
    /// <returns>If value was converted successfully, true; otherwise false.</returns>
    public static bool TryParse(string value, out T result) {
        return tryParseCached(value, out result);
    }

    /// <summary>
    /// Tries to convert the specified string representation of a logical value to
    /// its type T equivalent. A return value indicates whether the conversion
    /// succeeded or failed.
    /// </summary>
    /// <param name="value">A string containing the value to try and convert.</param>
    /// <returns>If value was converted successfully, true; otherwise false.</returns>
    public static bool TryParse(string value) {
        T throwaway;
        return TryParse(value, out throwaway);
    }
}

এটিকে কল করুন:

string input = "987";
decimal myDecimal;

bool myIntSuccess = TryParseHelper<int>.TryParse(input);
bool myDecimalSuccess = TryParseHelper<decimal>.TryParse(input, out myDecimal);

3

পার্টিতে বেশ খানিকটা দেরি হলেও এখানে আমি কী নিয়ে এসেছি। কোনও ব্যতিক্রম নয়, এককালীন (প্রতি টাইপ) প্রতিবিম্ব।

public static class Extensions {
    public static T? ParseAs<T>(this string str) where T : struct {
        T val;
        return GenericHelper<T>.TryParse(str, out val) ? val : default(T?);
    }
    public static T ParseAs<T>(this string str, T defaultVal) {
        T val;
        return GenericHelper<T>.TryParse(str, out val) ? val : defaultVal;
    }

    private static class GenericHelper<T> {
        public delegate bool TryParseFunc(string str, out T result);

        private static TryParseFunc tryParse;
        public static TryParseFunc TryParse {
            get {
                if (tryParse == null)
                    tryParse = Delegate.CreateDelegate(
                        typeof(TryParseFunc), typeof(T), "TryParse") as TryParseFunc;
                return tryParse;
            }
        }
    }
}

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

"5643".ParseAs<int>()

3

এখানে অন্য বিকল্প।

আমি এমন একটি ক্লাস লিখেছিলাম যা কোনও সংখ্যক TryParseহ্যান্ডলারের নিবন্ধন করা সহজ করে তোলে । এটি আমাকে এটি করতে দেয়:

var tp = new TryParser();

tp.Register<int>(int.TryParse);
tp.Register<decimal>(decimal.TryParse);
tp.Register<double>(double.TryParse);

int x;
if (tp.TryParse("42", out x))
{
    Console.WriteLine(x);
};

আমি 42কনসোলে মুদ্রিত হই।

ক্লাসটি হ'ল:

public class TryParser
{
    public delegate bool TryParseDelegate<T>(string s, out T result);

    private Dictionary<Type, Delegate> _tryParsers = new Dictionary<Type, Delegate>();

    public void Register<T>(TryParseDelegate<T> d)
    {
        _tryParsers[typeof(T)] = d;
    }

    public bool Deregister<T>()
    {
        return _tryParsers.Remove(typeof(T));
    }

    public bool TryParse<T>(string s, out T result)
    {
        if (!_tryParsers.ContainsKey(typeof(T)))
        {
            throw new ArgumentException("Does not contain parser for " + typeof(T).FullName + ".");
        }
        var d = (TryParseDelegate<T>)_tryParsers[typeof(T)];
        return d(s, out result);
    }
}

আমি এটি পছন্দ করি তবে আপনি জেনেরিক ছাড়াই এটি কীভাবে করবেন। অবশ্যই কেস প্রতিবিম্বিত হচ্ছে ব্যবহার করুন।
সিনেস্টেথিক

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

2

যখন আমি প্রায় এই সঠিক কাজটি করতে চেয়েছিলাম, প্রতিচ্ছবি দেখিয়ে আমাকে এটিকে কঠিন পদ্ধতিতে প্রয়োগ করতে হয়েছিল। প্রদত্ত T, প্রতিবিম্বিত হন typeof(T)এবং কোনও TryParseবা Parseপদ্ধতির সন্ধান করুন, যদি এটি খুঁজে পেয়ে থাকেন তবে এটি অনুরোধ করুন।


এই আমি পরামর্শ যাচ্ছি।
স্টিভেন এভার্স

2

এটা আমার চেষ্টা। আমি এটি "অনুশীলন" হিসাবে করেছি। আমি এটিকে বিদ্যমান " কনভার্ট.টক্স () " -অনস ইত্যাদির মতোই ব্যবহার করার চেষ্টা করেছি তবে এটি হ'ল এক্সটেনশন পদ্ধতি:

    public static bool TryParse<T>(this String str, out T parsedValue)
    {
        try
        {
            parsedValue = (T)Convert.ChangeType(str, typeof(T));
            return true;
        }

        catch { parsedValue = default(T); return false; }
    }

এর তুলনায় এর প্রধান অসুবিধা TypeConverter.ConvertFrom()হ'ল উত্স শ্রেণীর ধরণের রূপান্তর সরবরাহ করতে হয়, যার অর্থ সাধারণত আপনি কাস্টম ধরণের রূপান্তরকে সমর্থন করতে পারবেন না।
আয়ান গোল্ডবি

1

যেমনটি আপনি বলেছেন, TryParseকোনও ইন্টারফেসের অংশ নয়। এটি কোনও প্রদত্ত বেস শ্রেণীর সদস্য না কারণ এটি প্রকৃতপক্ষে staticএবং staticফাংশনগুলি হতে পারে না virtual। সুতরাং, সংকলকটির আশ্বাস দেওয়ার কোনও উপায় নেই যে Tআসলে একজন সদস্য ডেকেছে TryParse, সুতরাং এটি কার্যকর হয় না।

@ মার্ক যেমন বলেছিল, আপনি নিজের ইন্টারফেস তৈরি করতে এবং কাস্টম প্রকারগুলি ব্যবহার করতে পারেন, তবে বিল্ট-ইন টাইপের জন্য আপনার ভাগ্যের বাইরে।


1
public static class Primitive
{
    public static DateTime? TryParseExact(string text, string format, IFormatProvider formatProvider = null, DateTimeStyles? style = null)
    {
        DateTime result;
        if (DateTime.TryParseExact(text, format, formatProvider, style ?? DateTimeStyles.None, out result))
            return result;
        return null;
    }

    public static TResult? TryParse<TResult>(string text) where TResult : struct
    {
        TResult result;
        if (Delegates<TResult>.TryParse(text, out result))
            return result;
        return null;
    }

    public static bool TryParse<TResult>(string text, out TResult result) => Delegates<TResult>.TryParse(text, out result);

    public static class Delegates<TResult>
    {
        private delegate bool TryParseDelegate(string text, out TResult result);

        private static readonly TryParseDelegate _parser = (TryParseDelegate)Delegate.CreateDelegate(typeof(TryParseDelegate), typeof(TResult), "TryParse");

        public static bool TryParse(string text, out TResult result) => _parser(text, out result);
    }
}

0

এটি 'জেনেরিক সীমাবদ্ধতার' প্রশ্ন। কারণ আপনার কোনও নির্দিষ্ট ইন্টারফেস নেই তবে আপনি পূর্ববর্তী উত্তরের পরামর্শগুলি অনুসরণ না করে আপনি আটকে রয়েছেন।

এটিতে ডকুমেন্টেশনের জন্য, নীচের লিঙ্কটি চেক করুন:

http://msdn.microsoft.com/en-us/library/ms379564(VS.80).aspx

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


0

থেকে ধার http://blogs.msdn.com/b/davidebb/archive/2009/10/23/using-c-dynamic-to-call-static-members.aspx

এই রেফারেন্সটি অনুসরণ করার সময়: গতিশীল প্রকারের সাথে সি # 4.0 এ স্থিত পদ্ধতিটি কীভাবে প্রেরণ করা যায়?

using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Reflection;

namespace Utils
{
   public class StaticMembersDynamicWrapper : DynamicObject
   {
      private Type _type;

      public StaticMembersDynamicWrapper(Type type) { _type = type; }

      // Handle static methods
      public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
      {
         var methods = _type
            .GetMethods(BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public)
            .Where(methodInfo => methodInfo.Name == binder.Name);

         var method = methods.FirstOrDefault();
         if (method != null)
         {
            result = method.Invoke(null, args);
            return true;
         }

         result = null;
         return false;
      }
   }

   public static class StaticMembersDynamicWrapperExtensions
   {
      static Dictionary<Type, DynamicObject> cache =
         new Dictionary<Type, DynamicObject>
         {
            {typeof(double), new StaticMembersDynamicWrapper(typeof(double))},
            {typeof(float), new StaticMembersDynamicWrapper(typeof(float))},
            {typeof(uint), new StaticMembersDynamicWrapper(typeof(uint))},
            {typeof(int), new StaticMembersDynamicWrapper(typeof(int))},
            {typeof(sbyte), new StaticMembersDynamicWrapper(typeof(sbyte))}
         };

      /// <summary>
      /// Allows access to static fields, properties, and methods, resolved at run-time.
      /// </summary>
      public static dynamic StaticMembers(this Type type)
      {
         DynamicObject retVal;
         if (!cache.TryGetValue(type, out retVal))
            return new StaticMembersDynamicWrapper(type);

         return retVal;
      }
   }
}

এবং এটি নিম্নলিখিত হিসাবে ব্যবহার করুন:

  public static T? ParseNumeric<T>(this string str, bool throws = true)
     where T : struct
  {
     var statics = typeof(T).StaticMembers();

     if (throws) return statics.Parse(str);

     T retval;
     if (!statics.TryParse(str, out retval)) return null;

     return retval;
  }

0

আমি এই জাতীয় কাজ করে এমন কিছু পেতে সক্ষম হয়েছি

    var result = "44".TryParse<int>();

    Console.WriteLine( "type={0}, value={1}, valid={2}",        
    result.Value.GetType(), result.Value, result.IsValid );

আমার কোড এখানে

 public static class TryParseGeneric
    {
        //extend int
        public static dynamic TryParse<T>( this string input )
        {    
            dynamic runner = new StaticMembersDynamicWrapper( typeof( T ) );

            T value;
            bool isValid = runner.TryParse( input, out value );
            return new { IsValid = isValid, Value = value };
        }
    }


    public class StaticMembersDynamicWrapper : DynamicObject
    {
        private readonly Type _type;
        public StaticMembersDynamicWrapper( Type type ) { _type = type; }

        // Handle static properties
        public override bool TryGetMember( GetMemberBinder binder, out object result )
        {
            PropertyInfo prop = _type.GetProperty( binder.Name, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public );
            if ( prop == null )
            {
                result = null;
                return false;
            }

            result = prop.GetValue( null, null );
            return true;
        }

        // Handle static methods
        public override bool TryInvokeMember( InvokeMemberBinder binder, object [] args, out object result )
        {
            var methods = _type
            .GetMethods( BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public ).Where( methodInfo => methodInfo.Name == binder.Name );

            var method = methods.FirstOrDefault();

            if ( method == null )
            {
                result = null;

                return false;
            }

            result = method.Invoke( null, args );

            return true;
        }
    }

স্ট্যাটিক মেম্বার্সডায়নামিক ওয়ালপেপার ডেভিড এবো এর নিবন্ধ থেকে রূপান্তরিত হয়েছে (এটি একটি দ্ব্যর্থহীন ম্যাচএক্সেপশন নিক্ষেপ করছিল)


0
public static T Get<T>(string val)
{ 
    return (T) TypeDescriptor.GetConverter(typeof (T)).ConvertFromInvariantString(val);
}

0

সঙ্গে TypeDescriptorক্লাস ব্যবহার TryParseসংশ্লিষ্ট পদ্ধতিতে:

public static bool TryParse<T>(this string input, out T parsedValue)
{
    parsedValue = default(T);
    try
    {
        var converter = TypeDescriptor.GetConverter(typeof(T));
        parsedValue = (T)converter.ConvertFromString(input);
        return true;
    }
    catch (NotSupportedException)
    {
        return false;
    }
}

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

0

উপরের তথ্য ব্যবহার করে, এটি আমি বিকাশ করেছি। এটি অবজেক্টকে সরাসরি রূপান্তরিত করা সম্ভব, অন্যথায় এটি বস্তুকে স্ট্রিংয়ে রূপান্তর করবে এবং পছন্দসই অবজেক্ট টাইপের জন্য ট্রাইপার্স পদ্ধতিটি কল করবে।

আমি অভিধানে পদ্ধতিগুলি ক্যাশে করি কারণ প্রত্যেকেই পদ্ধতিটি আনার লোড হ্রাস করার জন্য সম্মুখীন হয়।

এটি পরীক্ষা করা সম্ভব যদি অবজেক্টটি সরাসরি টার্গেটের ধরণে রূপান্তর করা যায় যা স্ট্রিং রূপান্তর অংশটিকে আরও কমাবে। তবে আমি আপাতত এটি ছেড়ে দেব।

    /// <summary>
    /// Used to store TryParse converter methods
    /// </summary>
    private static readonly Dictionary<Type, MethodInfo> TypeConverters = new Dictionary<Type, MethodInfo>();

    /// <summary>
    /// Attempt to parse the input object to the output type
    /// </summary>
    /// <typeparam name="T">output type</typeparam>
    /// <param name="obj">input object</param>
    /// <param name="result">output result on success, default(T) on failure</param>
    /// <returns>Success</returns>
    public static bool TryParse<T>([CanBeNull] object obj, out T result)
    {
        result = default(T);

        try
        {
            switch (obj)
            {
                // don't waste time on null objects
                case null: return false;

                // if the object is already of type T, just return the value
                case T val:
                    result = val;
                    return true;
            }

            // convert the object into type T via string conversion
            var input = ((obj as string) ?? obj.ToString()).Trim();
            if (string.IsNullOrEmpty(input)) return false;

            var type = typeof (T);
            Debug.WriteLine($"Info: {nameof(TryParse)}<{type.Name}>({obj.GetType().Name}=\"{input}\")");

            if (! TypeConverters.TryGetValue(type, out var method))
            {
                // get the TryParse method for this type
                method = type.GetMethod("TryParse",
                    new[]
                    {
                        typeof (string),
                        Type.GetType($"{type.FullName}&")
                    });

                if (method is null)
                    Debug.WriteLine($"FAILED: Cannot get method for {type.Name}.TryParse()");

                // store it so we don't have to do this again
                TypeConverters.Add(type, method);
            }

            // have to keep a reference to parameters if you want to get the returned ref value
            var parameters = new object[] {input, null};
            if ((bool?) method?.Invoke(null, parameters) == true)
            {
                result = (T) parameters[1];
                return true;
            }                
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }

        return false;
    }

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

0

আমি এখানে একসাথে বিভিন্ন ধারণাগুলি রেখেছি এবং একটি খুব সংক্ষিপ্ত সমাধান দিয়ে শেষ করেছি।

এটি একটি স্ট্রিংয়ের একটি এক্সটেনশন পদ্ধতি

enter code here

আমি সংখ্যার প্রকারে ট্রাইপার্স পদ্ধতি হিসাবে একই পাদদেশ মুদ্রণ দিয়ে এটি তৈরি করেছি

    /// <summary>
    /// string.TryParse()
    /// 
    /// This generic extension method will take a string
    ///     make sure it is not null or empty
    ///     make sure it represents some type of number e.g. "123" not "abc"
    ///     It then calls the appropriate converter for the type of T
    /// </summary>
    /// <typeparam name="T">The type of the desired retrunValue e.g. int, float, byte, decimal...</typeparam>
    /// <param name="targetText">The text to be converted</param>
    /// <param name="returnValue">a populated value of the type T or the default(T) value which is likely to be 0</param>
    /// <returns>true if the string was successfully parsed and converted otherwise false</returns>
    /// <example>
    /// float testValue = 0;
    ///  if ( "1234".TryParse<float>( out testValue ) )
    ///  {
    ///      doSomethingGood();
    ///  }
    ///  else
    ///  {
    ///      handleTheBadness();
    ///  }
    /// </example>
    public static bool TryParse<T>(this string targetText, out T returnValue )
    {
        bool returnStatus = false;

        returnValue = default(T);

        //
        // make sure the string is not null or empty and likely a number...
        // call whatever you like here or just leave it out - I would
        // at least make sure the string was not null or empty  
        //
        if ( ValidatedInputAnyWayYouLike(targetText) )
        {

            //
            // try to catch anything that blows up in the conversion process...
            //
            try
            {
                var type = typeof(T);
                var converter = TypeDescriptor.GetConverter(type);

                if (converter != null && converter.IsValid(targetText))
                {
                    returnValue = (T)converter.ConvertFromString(targetText);
                    returnStatus = true;
                }

            }
            catch
            {
                // just swallow the exception and return the default values for failure
            }

        }

        return (returnStatus);

    }

'' '


ভাসমান টেস্টভ্যালু = 0; if ("1234"। ট্রাইপার্স <ফ্লাট> (টেস্টভ্যালু আউট)) {doSomethingGood (); } অন্য {হ্যান্ডেলপ্যাডনেস (); }
জেডি হিক্স

0

টি.TryParse ... কেন?

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

  • নিবেদিত ট্রাইপার্স ফাংশন সহ ক্লাসগুলি কল করা যেতে পারে
  • নিবেদিত পার্স ফাংশন সহ ক্লাসগুলি চেষ্টা-ধরা এবং বুল ফলাফলের সাথে মোড়ানো হতে পারে
  • অপারেটর ওভারলোড সহ ক্লাস, আপনি কীভাবে তাদের পার্সিং পরিচালনা করতে দেবেন?
  • প্রকার বর্ণনাকারী ব্যবহার করে অন্তর্নির্মিত Convert.ChangeType। এই API রানটাইম অনুসারে কাস্টমাইজযোগ্য। আপনার ফাংশন ডিফল্ট আচরণ প্রয়োজন বা কাস্টমাইজেশনের জন্য অনুমতি দেয়?
  • আপনার জন্য কোনও ম্যাপিং ফ্রেমওয়ার্ককে পার্স করার চেষ্টা করার অনুমতি দেওয়া উচিত?
  • আপনি উপরের বিরোধগুলি কীভাবে পরিচালনা করবেন?

-2

এক্সডোকামেন্ট থেকে বংশধর পেতে একটি সংস্করণ।

public static T Get<T>(XDocument xml, string descendant, T @default)
{
    try
    {
        var converter = TypeDescriptor.GetConverter(typeof (T));
        if (converter != null)
        {
            return (T) converter.ConvertFromString(xml.Descendants(descendant).Single().Value);
        }
        return @default;
    }
    catch
    {
        return @default;
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.