টি তে বস্তু নিক্ষেপ করুন


91

আমি XmlReader.NET এ ক্লাসের সাথে একটি এক্সএমএল ফাইল পার্স করছি এবং আমি ভেবেছিলাম যে জেনেরিকভাবে বিভিন্ন গুণাবলী পড়ার জন্য একটি জেনেরিক পার্স ফাংশন লিখতে হবে smart আমি নিম্নলিখিত ফাংশন নিয়ে এসেছি:

private static T ReadData<T>(XmlReader reader, string value)
{
    reader.MoveToAttribute(value);
    object readData = reader.ReadContentAsObject();
    return (T)readData;
}

আমি যেমন বুঝতে পেরেছি, এটি যেমনটি পরিকল্পনা করেছিলাম তেমনভাবে কাজ করে না; এটি আদিম ধরণের যেমন intবা এর সাথে ত্রুটি ছুঁড়ে ফেলেছে double, যেহেতু একটি কাস্ট একটি stringথেকে একটি সংখ্যার ধরণের রূপান্তর করতে পারে না । আমার ফাংশনটি পরিবর্তিত আকারে ছড়িয়ে দেওয়ার কি কোনও উপায় আছে?

উত্তর:


208

এটি কাস্ট করা যেতে পারে কিনা তা দেখতে প্রথমে পরীক্ষা করে দেখুন।

if (readData is T) {
    return (T)readData;
} 
try {
   return (T)Convert.ChangeType(readData, typeof(T));
} 
catch (InvalidCastException) {
   return default(T);
}

4
আমি কনভার্ট.চ্যাঞ্জটাইপ দিয়ে লাইনটি পরিবর্তিত করেছি: 'রিটার্ন (টি) রূপান্তর করুন han চেঞ্জটাইপ (রিডডাটা, টাইপফ (টি), সিস্টেম.গ্লোবালাইজেশন.ক্ল্যাচারআইফোন.ইনস্টলড ইউআইকচারাল্ট.নম্বার ফর্ম্যাট) যাতে এটি বিভিন্ন বিভিন্ন সাংস্কৃতিক কনফিগারেশনে কাজ করে।
ক্যাস্পার হোল্ডাম

4
এটা সঠিক উত্তর. তবে আমি একটি যুক্তি দিতে পারি যে চেষ্টা / ধরা এখানে সম্পূর্ণ অপ্রয়োজনীয়। বিশেষত নিঃশব্দ ব্যতিক্রম বিবেচনা। আমি মনে করি যদি (পঠিত ডেটা টি হয়) {...} অংশটি যথেষ্ট প্রচেষ্টা।
পিম

আপনি পরীক্ষা করতে পারেন রিডেটটি রূপান্তর করার আগে নাল কিনা। যদি তাই হয় ডিফল্ট (টি)।
ম্যানুয়েল কোচ

আমি পেয়েছি "অবজেক্ট অবশ্যই আইকনভার্টেবল বাস্তবায়ন করতে হবে"।
কেসি ক্রুকস্টন

19

আপনি কি কনভার্ট.চেনজ টাইপ চেষ্টা করেছেন ?

যদি পদ্ধতিটি সর্বদা একটি স্ট্রিং ফেরত দেয়, যা আমার কাছে বিজোড় মনে হয় তবে এটি বিন্দু ছাড়াও হয় তবে সম্ভবত এই পরিবর্তিত কোডটি আপনি যা চান তা করতে পারে:

private static T ReadData<T>(XmlReader reader, string value)
{
    reader.MoveToAttribute(value);
    object readData = reader.ReadContentAsObject();
    return (T)Convert.ChangeType(readData, typeof(T));
}

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


3

আপনার প্রকারটি রেফারেন্স ধরণের হতে পারে:

 private static T ReadData<T>(XmlReader reader, string value) where T : class
 {
     reader.MoveToAttribute(value);
     object readData = reader.ReadContentAsObject();
     return (T)readData;
 }

এবং তারপরে আর একটি করুন যা মান ধরণের এবং ট্রাইপার্স ব্যবহার করে ...

 private static T ReadDataV<T>(XmlReader reader, string value) where T : struct
 {
     reader.MoveToAttribute(value);
     object readData = reader.ReadContentAsObject();
     int outInt;
     if(int.TryParse(readData, out outInt))
        return outInt
     //...
 }

3

আসলে, এখানে সমস্যা হ'ল রিডকন্টেন্টএএসবজেক্টের ব্যবহার। দুর্ভাগ্যক্রমে, এই পদ্ধতিটি তার প্রত্যাশা অনুসারে বাস করে না; যখন এটির মানটির জন্য সর্বাধিক অ্যাপপ্রায়ারেট প্রকারটি সনাক্ত করা উচিত, এটি আসলে একটি স্ট্রিং প্রদান করে, যাই হোন না কেন (এটি রিফ্লেক্টর ব্যবহার করে যাচাই করা যেতে পারে)।

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

পরিবর্তে রিডকন্টেন্টএ ব্যবহার করার চেষ্টা করুন, এটি আপনার প্রয়োজন ঠিক।

private static T ReadData<T>(XmlReader reader, string value)
{
    reader.MoveToAttribute(value);
    object readData = reader.ReadContentAs(typeof(T), null);
    return (T)readData;
}

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

2

আপনি সম্ভবত প্যারামিটার হিসাবে, একটি প্রতিনিধি যা স্ট্রিং থেকে টিতে রূপান্তরিত করতে পারেন তা পাস করতে পারেন uma


1

একটি 'শ্রেণি' সীমাবদ্ধতা যুক্ত করুন (বা আরও বিশদ, যেমন আপনার এক্সপেক্টেড টি অবজেক্টগুলির বেস ক্লাস বা ইন্টারফেসের মতো):

private static T ReadData<T>(XmlReader reader, string value) where T : class
{
    reader.MoveToAttribute(value);
    object readData = reader.ReadContentAsObject();
    return (T)readData;
}

বা where T : IMyInterfaceবা where T : new(), ইত্যাদি


1

আসলে, প্রতিক্রিয়াগুলি একটি আকর্ষণীয় প্রশ্ন নিয়ে আসে, যা ত্রুটির ক্ষেত্রে আপনার ফাংশনটি করতে চান want

এটি টি-তে পড়ার চেষ্টা করে এমন একটি ট্রাইপার্স পদ্ধতি হিসাবে এটি তৈরি করা আরও অর্থবোধ করে, তবে এটি করা সম্ভব না হলে মিথ্যা ফিরিয়ে দেয়?

    private static bool ReadData<T>(XmlReader reader, string value, out T data)
    {
        bool result = false;
        try
        {
            reader.MoveToAttribute(value);
            object readData = reader.ReadContentAsObject();
            data = readData as T;
            if (data == null)
            {
                // see if we can convert to the requested type
                data = (T)Convert.ChangeType(readData, typeof(T));
            }
            result = (data != null);
        }
        catch (InvalidCastException) { }
        catch (Exception ex)
        {
            // add in any other exception handling here, invalid xml or whatnot
        }
        // make sure data is set to a default value
        data = (result) ? data : default(T);
        return result;
    }

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.