কীভাবে সিস্টেম.ইনম থেকে বেস পূর্ণসংখ্যায় রূপান্তর করবেন?


96

আমি যে কোনও সিস্টেমকে রূপান্তর করার জন্য একটি জেনেরিক পদ্ধতি তৈরি করতে চাই n

উদাহরণস্বরূপ, আমি যা চাই তা হ'ল কিছু:

// Trivial example, not actually what I'm doing.
class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        (int)anEnum;
    }
}

তবে এটি কাজ করে না। রিশার্পার রিপোর্ট করেছেন যে আপনি 'int' টাইপ করতে 'System.Enum' টাইপের অভিব্যক্তি কাস্ট করতে পারবেন না।

এখন আমি এই সমাধানটি নিয়ে এসেছি তবে এর চেয়ে আরও কিছু দক্ষ হতে হবে।

class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        return int.Parse(anEnum.ToString("d"));
    }
}

কোনও পরামর্শ?


4
আমি বিশ্বাস করি এটি সংকলক যা অভিযোগ করছে, পুনরায় ভাগ না করে।
কুগেল

4
অগত্যা। আমার সিস্টেমে একটি এক্সটেনশন পদ্ধতি রয়েছে n এনুম, এবং মাঝে মাঝে পুনরায় ভাগ করা অভিযোগ করার সিদ্ধান্ত নিয়েছে: উদাহরণস্বরূপ আর্গুমেন্ট টাইম 'Some.Cool.Type.That.Is.An.Enum' কে 'System.Enum' এ রূপান্তর করতে পারবেন না যখন এটি সন্দেহাতীতভাবে এনাম হয়। যদি আমি কোডটি সংকলন ও চালনা করি তবে এটি ঠিক কাজ করে। আমি যদি তখন ভিএস বন্ধ করে দিই, পুনরায় ভাগ করা ক্যাশেটি উড়িয়ে দেব এবং এটি পুনরায় ফায়ার করব, পুনরায় কাজ শেষ হয়ে গেলে সবকিছু ঠিক হয়ে যায়। আমার জন্য এটি এক ধরণের ক্যাশে স্নাফু। তার জন্য একই হতে পারে।
মির

@ মীর আমারও এই বিষয়ে "অভিযোগ" পেয়েছি। আমার জন্য একই ফিক্স। কেন এটি এই ধরণের মিশ্রিত হয় তা নিশ্চিত নয়, তবে এটি অবশ্যই সংকলক নয়।
আকস্মমত ২

উত্তর:


137

আপনি যদি কাস্ট করতে না চান,

Convert.ToInt32()

কৌতুক করতে পারে

সরাসরি কাস্ট (মাধ্যমে (int)enumValue) সম্ভব নয়। নোট করুন যে এটি হবে "বিপজ্জনক" যেহেতু একটি enum বিভিন্ন অন্তর্নিহিত ধরনের পারেন ( int, long, byte...)।

আরও আনুষ্ঠানিকভাবে: System.Enumএর সাথে সরাসরি উত্তরাধিকারের সম্পর্ক নেই Int32(যদিও উভয়ই ValueTypeসমান) তাই প্রকারের সিস্টেমের মধ্যে সুস্পষ্ট কাস্ট সঠিক হতে পারে না


4
Converter.ToInteger(MyEnum.MyEnumConstant);এখানে আপনাকে কোনও ত্রুটি দেবে না দয়া করে সেই অংশটি সম্পাদনা করুন।
নওফাল

ধন্যবাদ, @ নফল, আপনি ঠিক বলেছেন। আমি প্রতিক্রিয়াটি সম্পাদনা করেছি (এবং নতুন কিছু শিখেছি :) ...)
মার্টিনস্টটনার

অন্তর্নিহিত ধরণের থেকে পৃথক হলে কাজ করছে নাint
অ্যালেক্স ঝুকভস্কি

@ ইয়ারোস্লাভসিভাকভ এটি এনামের মতো কাজ করবে না long
অ্যালেক্স ঝুকভস্কি

System.Enumএটি একটি শ্রেণি, তাই এটি একটি রেফারেন্স টাইপ। মানগুলি সম্ভবত বাক্সযুক্ত।
তেজয়

45

আমি এটি কোনও বস্তুর কাছে কাস্ট করে কাজ করতে পেরেছিলাম এবং তারপরে একটি ইনট:

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return (int)((object)enumValue);
    }
}

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

সম্পাদনা: কনভার্ট। টোইন্ট 32 (এনামভ্যালু) পাশাপাশি কাজ করে পোস্ট করার কথা ছিল, এবং লক্ষ্য করেছে যে মার্টিনস্টটনার আমাকে এতে মারধর করেছে।

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

পরীক্ষা:

int x = DayOfWeek.Friday.ToInt();
Console.WriteLine(x); // results in 5 which is int value of Friday

সম্পাদনা 2: মন্তব্যগুলিতে, কেউ বলেছেন যে এটি কেবল সি # 3.0 তে কাজ করে। আমি এটি ঠিক এইভাবে ভিএস ২০০৫ এ পরীক্ষা করেছি এবং এটি কাজ করেছে:

public static class Helpers
{
    public static int ToInt(Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

    static void Main(string[] args)
    {
        Console.WriteLine(Helpers.ToInt(DayOfWeek.Friday));
    }

আমি আপনাকে +1 দিয়েছি তবে এই সমাধানটি কেবলমাত্র # # 3.0 এবং তার থেকেও বেশি দিয়ে কাজ করবে।
ভাদিম

আমি মনে করি, এটি কেবল সংকলককে সন্তুষ্ট করে। আপনি রানটাইম এ পরীক্ষা করতে পরিচালিত? আমি এই ফাংশনটির কোনও মূল্য দিতে পারিনি ...
মার্টিনস্টটনার

কারণ এটি একটি এক্সটেনশন পদ্ধতি? অথবা সি # এর পুরানো সংস্করণগুলিতে এনামগুলিতে কিছু আলাদা?
বিফ্রি

আমি আমার পোস্টের শেষে একটি পরীক্ষা যুক্ত করেছি। আমি এটি চেষ্টা করেছিলাম এবং এটি আমার পক্ষে কাজ করে।
বিফ্রি

@ বিফ্রি: কেবলমাত্র এক্সটেনশন পদ্ধতিতে কাজ করা মনে হচ্ছে। আমি এটি একটি "পুরানো-শৈলী" ফাংশন দিয়ে চেষ্টা করেছি (সি # ২.০ তে) এবং প্রকৃতপক্ষে এটির কোনও মান পাস করার জন্য সিনট্যাক্সটি সন্ধান করতে পারি নি (এটি আমার আগের
মতামতটি

15

আপনার যদি কোনও এনামকে তার অন্তর্নিহিত ধরণের রূপান্তর করতে হয় (সমস্ত এনামগুলি সমর্থন করে না int) তবে আপনি ব্যবহার করতে পারেন:

return System.Convert.ChangeType(
    enumValue,
    Enum.GetUnderlyingType(enumValue.GetType()));

5
এটিই কেবল বুলেটপ্রুফ উত্তর।
রুডি

এই কারণে বক্সিং আনবক্সিং হয়?
বি.ভেন

@ বি.বেন হ্যাঁ প্রথম যুক্তির জন্য Convert.ChangeTypeগ্রহণ করে objectএবং ফেরত দেয় object
ড্রয় নোকস

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

10

আপনাকে সহায়িকার পদ্ধতির সাহায্যে চাকাটি পুনরায় উদ্ভাবন করতে হবে কেন? enumএটির অন্তর্নিহিত ধরণের কাছে কোনও মান দেওয়া পুরোপুরি আইনী ।

এটি কম টাইপিং, এবং আমার মতে আরও পাঠযোগ্য, ব্যবহারের জন্য ...

int x = (int)DayOfWeek.Tuesday;

... এর চেয়ে ভালো কিছু ...

int y = Converter.ToInteger(DayOfWeek.Tuesday);
// or
int z = DayOfWeek.Tuesday.ToInteger();

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

@ জর্জ, আপনার অর্থ কী তা আমি সত্যিই নিশ্চিত নই। আপনার প্রয়োজনীয় ব্যবহার দেখিয়ে একটি উদাহরণ দিতে পারেন?
লুক এইচ

4
কখনও কখনও আপনি সরাসরি একটি এনাম কাস্ট করতে পারবেন না, যেমন জেনেরিক পদ্ধতির ক্ষেত্রে। যেহেতু জেনেরিক পদ্ধতিগুলি এনামগুলিতে সীমাবদ্ধ করা যায় না, আপনি এটি স্ট্রাক্ট জাতীয় কিছুতে সীমাবদ্ধ রেখেছেন, যা কোনও int- এ ফেলে দেওয়া যায় না। সেক্ষেত্রে এটি করার জন্য আপনি কনভার্ট.টোইন্ট 32 (এনাম) ব্যবহার করতে পারেন।
ড্যানিয়েল টি।

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

এছাড়াও, একটি এক্সটেনশন পদ্ধতি ব্যবহার করা আপনার কোড বেসগুলিতে সামঞ্জস্যতা যুক্ত করতে পারে। যেহেতু @ নওফাল ইঙ্গিত করেছেন, আপনি এনামের কাছ থেকে মান মূল্য পেতে পারেন এমন একাধিক উপায় রয়েছে যা একটি এক্সটেনশন পদ্ধতি তৈরি করে এবং এর ব্যবহার প্রয়োগ করে তার অর্থ হ'ল প্রতিবার আপনি যখন একই পদ্ধতি ব্যবহার করছেন তখন এনামের অন্তর্নির্মিত মূল্য পাবেন
লুইস এগলটন

4

আমার উত্তর থেকে এখানে :

eহিসাবে দেওয়া হয়েছে:

Enum e = Question.Role;

তারপরে এই কাজগুলি:

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

শেষ দুটি সরল কদর্য। প্রথমটি আরও বেশি পঠনযোগ্য হওয়া উচিত, যদিও দ্বিতীয়টিটি আরও দ্রুত। বা একটি এক্সটেনশন পদ্ধতি হতে পারে উভয় বিশ্বের সেরা, সেরা।

public static int GetIntValue(this Enum e)
{
    return e.GetValue<int>();
}

public static T GetValue<T>(this Enum e) where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{
    return (T)(object)e;
}

এখন আপনি কল করতে পারেন:

e.GetValue<int>(); //or
e.GetIntValue();

আপনি কি নিশ্চিত যে দ্বিতীয়টি দ্রুত? আমি ধরে নিলাম এটি এনাম বক্স করবে এবং তারপরে ইনবক্সে ফিরে যাবে?
yoyo

4
@ ইয়য়ো eভেরিয়েবলটির ইতিমধ্যে প্রকৃত মান ধরণের, যেমন এনুমের বক্সযুক্ত উদাহরণ রয়েছে। আপনি যখন লিখবেন Enum e = Question.Role;এটি ইতিমধ্যে বাক্সযুক্ত। প্রশ্নটি বাক্সটিকে System.Enumঅন্তর্নিহিত ইন্ট টাইপ (আনবক্সিং) এ রূপান্তর করার বিষয়ে । সুতরাং এখানে আনবক্সিং কেবল পারফরম্যান্সের উদ্বেগ। (int)(object)eএকটি সরাসরি আনবক্স কল; হ্যাঁ অন্যান্য পদ্ধতির চেয়ে দ্রুত হওয়া উচিত। এটি দেখুন
নওফাল

ব্যাখ্যার জন্য ধন্যবাদ. আমি ভুল ধারণাটির মধ্যে ছিলাম যে সিস্টেমের একটি উদাহরণ n এনাম একটি আনবক্সড মান। এটিও দেখুন - এমএসডিএন.মাইক্রোসফটকম /en-us/library/aa691158(v=vs.71).aspx
yoyo

@ ইয়য়ো হুঁ হ্যাঁ লিঙ্কটি থেকে প্রাসঙ্গিক উক্তি: যেকোন এনাম-টাইপ থেকে টাইপ System.Enum।
নওফাল

1

আমার কাছ System.Enumথেকে একটি intকাজ জরিমানা করা (এটি এমএসডিএন তেও রয়েছে ) সম্ভবত এটি একটি পুনরায় ভাগ করা বাগ।


4
আপনি রানটাইমের কোন সংস্করণ ব্যবহার করছেন?
জোশবার্ক

4
লিঙ্কটি নিজে System.Enumনয়, সাব ধরণের কাস্টিং দেখায় System.Enum
নওফাল

আমার একই রকম সমস্যা ছিল রিশার্পার ক্যাশে স্নাফু। ভিএস বন্ধ করে এবং পুনঃভাগের ক্যাশে মুছে ফেলা ত্রুটিটি পুরো পুনরায় ছাড়ার পরেও অদৃশ্য হয়ে গেছে।
মির

1

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

বৃহত্তম উপলব্ধ কন্টেইনার ব্যবহার করে আমরা রূপান্তরকালে ব্যতিক্রমগুলি এড়াতে পারি। দুর্ভাগ্যক্রমে, কোন ধারকটি ব্যবহার করবেন তা পরিষ্কার নয় কারণ উলংটি নেতিবাচক সংখ্যার জন্য উড়ে যাবে এবং দীর্ঘের জন্য দীর্ঘ হবে blow ম্যাক্সভ্যালু এবং উলং। ম্যাক্সভ্যালু numbers অন্তর্নিহিত ধরণের ভিত্তিতে আমাদের এই পছন্দগুলির মধ্যে পরিবর্তন করতে হবে।

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

  1. int (দীর্ঘ এবং উলং) এর চেয়ে বড় ফিল্ড স্পেস সহ প্রকারের ভিত্তিতে এনামগুলির জন্য, কিছু এনাম একই মানকে মূল্যায়ন করতে পারে।
  2. আপনি যদি চেক করা অঞ্চলে থাকেন তবে ম্যাক্সভ্যালু থেকে বড় একটি সংখ্যা ingালাই একটি ব্যতিক্রম ছুঁড়ে ফেলবে।

এখানে আমার পরামর্শ, আমি এই ফাংশনটি কোথায় প্রকাশ করব তা স্থির করার জন্য এটি পাঠকের কাছে ছেড়ে দেব; সহায়ক বা এক্সটেনশন হিসাবে।

public int ToInt(Enum e)
{
  unchecked
  {
    if (e.GetTypeCode() == TypeCode.UInt64)
      return (int)Convert.ToUInt64(e);
    else
      return (int)Convert.ToInt64(e);
  }
}

-1

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

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

public static EnumHelpers
{
    public static T Convert<T, E>(E enumValue)
    {
        return (T)enumValue;
    }
}

এটি তখন এর মতো ব্যবহার করা যেতে পারে:

public enum StopLight: int
{
    Red = 1,
    Yellow = 2,
    Green = 3
}

// ...

int myStoplightColor = EnumHelpers.Convert<int, StopLight>(StopLight.Red);

আমি আমার মাথার উপরের অংশটি সুনিশ্চিতভাবে বলতে পারি না, তবে উপরের কোডটি এমনকি সি # এর ধরণের অনুক্রম দ্বারা সমর্থিত হতে পারে যা নিম্নলিখিতগুলির অনুমতি দিচ্ছে:

int myStoplightColor = EnumHelpers.Convert<int>(StopLight.Red);

4
দুর্ভাগ্যক্রমে, আপনার উদাহরণে E কোনও প্রকার হতে পারে। জেনারিকস আমাকে এনামকে টাইপ প্যারামিটার সীমাবদ্ধতা হিসাবে ব্যবহার করতে দেয় না। আমি বলতে পারি না: কোথায় টি: এনুম
ভাদিম

যদিও আপনি টি: স্ট্রাক্ট ব্যবহার করতে পারেন। এটি আপনি যেভাবে চান তা ততটা কঠোর নয়, তবে এটি কোনও রেফারেন্সের ধরণটি কেটে ফেলবে (যা আমি মনে করি যে আপনি যা করার চেষ্টা করছেন))
ধরণটি

আপনি ব্যবহার করতে পারেন: যদি (! typof (E) .IsEnum) নতুন আর্গুমেন্টএক্সসেপশন ("E অবশ্যই একটি গণিত প্রকারের হতে হবে") ফেলে দিন;
ডায়াদিওর

4
এটি এমনকি দূরবর্তী অবস্থান থেকে সঠিক নয়, স্থির সহায়ক এমনকি বৈধ নয়।
নিকলি

4
কারও EnumHelpers.Convert<int, StopLight>(StopLight.Red);পরিবর্তে ব্যবহার করা উচিত কেন (int)StopLight.Read;? এছাড়াও প্রশ্নটি কথা বলছে System.Enum
নওফাল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.