স্পষ্টভাবে 'int' প্রকারটি 'টি' তে রূপান্তর করতে পারে না


90

আমি কল করতে পারি Get<int>(Stat);বাGet<string>(Name);

কম্পাইল করার সময় আমি পাই:

'Int' টাইপকে স্পষ্টভাবে 'টি' তে রূপান্তর করতে পারে না

এবং একই জিনিস জন্য string

public T Get<T>(Stats type) where T : IConvertible
{
    if (typeof(T) == typeof(int))
    {
        int t = Convert.ToInt16(PlayerStats[type]);
        return t;
    }
    if (typeof(T) == typeof(string))
    {
        string t = PlayerStats[type].ToString();
        return t;
    }
}

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

উত্তর:


132

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

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


4
<Car> পান যেখানে গাড়ি প্রয়োগ করে আইকনভার্টেবল ভাঙ্গন সৃষ্টি করবে। যখন কেউ দেখেন আপনার একটি জেনেরিক পদ্ধতি রয়েছে তখন তারা ধরে নেবেন যে তারা আইকনভারটেবলকে কার্যকর করে এমন কোনও ক্ষেত্রে পাস করতে পারে।
Tjart

10
আমি কেবলমাত্র আপনার সাথেই একমত হতে পারি, @ এরিক। আমার এমন একটি পরিস্থিতি রয়েছে যেখানে আমাকে এক্সএমএল-ট্যাগগুলিতে সঞ্চিত অ্যারেগুলি পার্স করতে হয় problem সমস্যাটি হ'ল এক্সএমএল ডকুমেন্ট অনুসরণ করে (আমার ক্ষেত্রে COLLADA) বলে যে এই ধরণের অ্যারেগুলি হতে পারে শুধুমাত্র ভাসা, ইন্ট এবং বুলই নয় কিছু কাস্টম প্রকারও H আপনি যদি কোনও ফ্লোট পান তবে [] (অ্যারে-ট্যাগগুলিতে তাদের নামে সঞ্চিত ডেটার ধরণ রয়েছে: ফ্লোট_আরে স্টোরগুলি ভাসমান) আপনার স্ট্রিংটির অ্যারে হিসাবে পার্স করতে হবে ভাসমান, যার জন্য কিছু আইফোর্ম্যাটপ্রাইডার ব্যবহার করা দরকার) I আমি অবশ্যই "টি.পার্স (...)" ব্যবহার করতে পারি না So
rbaleksandar

4
এই উত্তর আপনাকে খরগোশের গর্ত থেকে দূরে রাখবে। আমি এর জন্য একটি ফাংশন জেনেরিক করতে চেয়েছিলাম int, int?, bool, bool?, stringএবং এটি অসম্ভব বলে মনে হয়।
জেস

এটি জেনেরিক এনুমারেটেড টাইপ ব্যবহারিককে স্যুইচ করে।
ডেভিড এ। গ্রে

4
আমি উত্তর হিসাবে এটি ব্যবহার করতে চাই না। তবে তিনি ঠিক বলেছেন। আমি প্রকারটি যাচাই করতে চেয়েছিলাম এবং যদি কোনও নির্দিষ্ট থাকে তবে এটিতে একটি সম্পত্তি সেট করা উচিত। সমাধানটি এমন একটি পদ্ধতি তৈরি করা ছিল যা দৃ strongly়ভাবে টাইপ করা প্যারামিটার নিয়েছিল।
ম্যাট ড্যাডি

141

Convert.ChangeType()আপনার কাস্টম কোডের পরিবর্তে আপনার কেবলমাত্র সক্ষম হওয়া উচিত :

public T Get<T>(Stats type) where T : IConvertible
{
    return (T) Convert.ChangeType(PlayerStats[type], typeof(T));
}

21
কিভাবেreturn (T)(object)PlayerStats[type];
সর্বোচ্চ

11
public T Get<T>(Stats type ) where T : IConvertible
{
    if (typeof(T) == typeof(int))
    {
        int t = Convert.ToInt16(PlayerStats[type]);
        return (T)t;
    }
    if (typeof(T) == typeof(string))
    {
        string t = PlayerStats[type].ToString();
        return (T)t;
    }
}

4
return (T) t;কারণ কোনও নাল চেকের দরকার নেই।
বোল্টক্লক

এটি উপরেরটি আমার জন্য সংকলন করবে না। সংকলনের জন্য টি হিসাবে একটি "রেফারেন্স টাইপ" হওয়া দরকার।
রবার্ট শ্মিড্ট

9

ChangeTypeসম্ভবত আপনার সেরা বিকল্প। আমার সমাধানটি ব্রোকেনগ্লাস দ্বারা সরবরাহ করা যুক্তটির সাথে সামান্য কিছু চেষ্টা করার চেষ্টা করুন catch

static void Main(string[] args)
{
    object number = "1";
    bool hasConverted;
    var convertedValue = DoConvert<int>(number, out hasConverted);

    Console.WriteLine(hasConverted);
    Console.WriteLine(convertedValue);
}

public static TConvertType DoConvert<TConvertType>(object convertValue, out bool hasConverted)
{
    hasConverted = false;
    var converted = default(TConvertType);
    try
    {
        converted = (TConvertType) 
            Convert.ChangeType(convertValue, typeof(TConvertType));
        hasConverted = true;
    }
    catch (InvalidCastException)
    {
    }
    catch (ArgumentNullException)
    {
    }
    catch (FormatException)
    {
    }
    catch (OverflowException)
    {
    }

    return converted;
}

আমার ব্যবহারের ক্ষেত্রটি জেনেরিক অ্যাবস্ট্রাক্ট ক্লাস থেকে উদ্ভূত একটি কংক্রিট শ্রেণি। বর্গটি বিমূর্ত হিসাবে চিহ্নিত করা হয়েছে কারণ এটি একটি বিমূর্ত পদ্ধতি সংজ্ঞায়িত করে যা বেস শ্রেণীর জেনেরিক ব্যক্তিগত সদস্যকে পরিচালনা করে। জেনেরিকটি তার জেনেরিক ধরণের ক্ষেত্রে সি # 7.3 এনাম সীমাবদ্ধতা ব্যবহার করে। আমি সবেমাত্র একটি পরীক্ষা সফলভাবে শেষ করেছি এবং এটি যেমনটি আশা করেছিল ঠিক তেমনভাবে কাজ করে।
ডেভিড এ। গ্রে

8

এটা চেষ্টা কর:

public T Get<T>(Stats type ) where T : IConvertible
{
    if (typeof(T) == typeof(int))
    {
        return (T)(object)Convert.ToInt16(PlayerStats[type]);

    }
    if (typeof(T) == typeof(string))
    {

        return (T)(object)PlayerStats[type];
    }
}

আপনাকে সাহায্য করার জন্য ধন্যবাদ, আমার প্রয়োজনটি আলাদা। আমি বিদ্যমান স্ট্যাটিক পদ্ধতির জন্য একটি মক পদ্ধতি লিখছি যাতে আমি এটি পরীক্ষা করতে পারি। এই osherove.com/blog/2012/7/8/…
Esen

8

আসলে, আপনি কেবল এটিকে objectএবং তারপরে রূপান্তর করতে পারেন T

T var = (T)(object)42;

উদাহরণস্বরূপ bool:

public class Program
{
    public static T Foo<T>()
    {
        if(typeof(T) == typeof(bool)) {
            return (T)(object)true;
        }

        return default(T);
    }

    public static void Main()
    {
        bool boolValue = Foo<bool>(); // == true
        string stringValue = Foo<string>(); // == null
    }
}

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


6

@ ব্রোকেনগ্লাস লজিক ( Convert.ChangeType) বিবেচনা করা জিইউইডি প্রকারের জন্য সমর্থন করে না।

public T Get<T>(Stats type) where T : IConvertible
{
    return (T) Convert.ChangeType(PlayerStats[type], typeof(T));
}

ত্রুটি : 'সিস্টেম.স্ট্রিং' থেকে 'সিস্টেম.গুইড' এ অবৈধ কাস্ট।

পরিবর্তে, নেমস্পেস TypeDescriptor.GetConverterযুক্ত করে নীচের যুক্তি ব্যবহার করুন System.ComponentModel

public T Get<T>(Stats type) where T : IConvertible
{
    (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(PlayerStats[type])
}

পড়ুন এই



0

আপনি কেবল নীচের মত কাস্ট করতে পারেন,

public T Get<T>(Stats type) where T : IConvertible
{
  if (typeof(T) == typeof(int))
  {
    int t = Convert.ToInt16(PlayerStats[type]);
    return t as T;
  }
 if (typeof(T) == typeof(string))
 {
    string t = PlayerStats[type].ToString();
    return t as T;
 }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.