এনাম সংজ্ঞাতে টিলড (~) কী?


149

আমি সর্বদা অবাক হয়েছি যে এই সময়ের জন্য সি # ব্যবহার করার পরেও আমি এখনও এমন জিনিসগুলি সন্ধান করতে পারি যেগুলি সম্পর্কে আমি জানিনা ...

আমি এটির জন্য ইন্টারনেট অনুসন্ধান করার চেষ্টা করেছি, তবে অনুসন্ধানে "~" ব্যবহার করা আমার পক্ষে এত ভাল কাজ করছে না এবং এমএসডিএন-তে আমি কিছুই খুঁজে পাইনি (এটি সেখানে নেই বলে মনে হয় না)

আমি কোডটির এই স্নিপেটটি সম্প্রতি দেখেছি, টিলড (~) এর অর্থ কী?

/// <summary>
/// Enumerates the ways a customer may purchase goods.
/// </summary>
[Flags]
public enum PurchaseMethod
{   
    All = ~0,
    None =  0,
    Cash =  1,
    Check =  2,
    CreditCard =  4
}

আমি এটি দেখে কিছুটা অবাক হয়েছিলাম তাই আমি এটি সংকলন করার চেষ্টা করেছি এবং এটি কাজ করেছে ... তবে এখনও এর অর্থ / কী তা আমি জানি না। কোন সাহায্য??


4
এটি একটি দুর্দান্ত এবং মার্জিত সমাধান যা সময়ের সাথে সাথে এনামের মসৃণ আপগ্রেড করার অনুমতি দেয়। দুর্ভাগ্যক্রমে এটি CA-2217 এর সাথে সাংঘর্ষিক এবং যদি আপনি কোড বিশ্লেষণটি ব্যবহার করেন তবে একটি ত্রুটি ছুঁড়ে ফেলবে :( এমএসডিএন.মাইক্রোসফটকম /en-us/library/ms182335.aspx
জেসন কোয়েন

এটি এখন ২০২০, এবং আমি নিজেকে নিজের পোস্টটি শুরু করার সাথে একই শব্দগুলি ভাবতে দেখি। শুনে আমি খুশী হয়েছি যে আমি একা নই।
ফানকিমশরুম

উত্তর:


136

the হ'ল অ্যানারি যার পরিপূরক অপারেটর - এটি তার অপারেন্ডের বিটগুলি ফ্লিপ করে।

~0 = 0xFFFFFFFF = -1

দুটি পরিপূরক গাণিতিক মধ্যে, ~x == -x-1

~ অপারেটরটি বেশিরভাগ ভাষায় সি থেকে সিটেক্স ধার নিয়েছে, ওজেক্টিভ-সি / সি ++ / সি # / জাভা / জাভাস্ক্রিপ্ট সহ পাওয়া যাবে।


চমৎকার. আমি বুঝতে পারি নি যে আপনি এনামে এটি করতে পারবেন। ভবিষ্যতে অবশ্যই ব্যবহার করবে
অরিয়ন এডওয়ার্ডস

সুতরাং এটি All = Int32.MaxValue এর সমতুল্য? বা UInt32.MaxValue?
জোয়েল মুলার

2
সমস্ত = (স্বাক্ষরবিহীন পূর্ববর্তী) -1 == UInt32.MaxValue। Int32.MaxValue এর কোনও প্রাসঙ্গিকতা নেই।
জিমি

4
@ স্টিভো 3000: ইন্ট 32.মিনভ্যালু 0xF0000000, যা 0 ডলার নয় (এটি আসলে ~ Int32.MaxValue)
জিমি

2
@ জিমি: ইনট 32.মিনভ্যালু 0x80000000। এটিতে কেবল একটি একক বিট সেট রয়েছে (এফ আপনাকে দেবে এমন চারটি নয়)।
ILMTitan

59

আমি এটা মনে করি:

[Flags]
public enum PurchaseMethod
{
    None = 0,
    Cash = 1,
    Check = 2,
    CreditCard = 4,
    All = Cash | Check | CreditCard
 }

আরও কিছুটা পরিষ্কার হবে।


10
এটা অবশ্যই. অ্যানারিটির একমাত্র ভাল প্রভাব হ'ল যদি কেউ গণনায় যোগ করে তবে সমস্ত স্বয়ংক্রিয়ভাবে এটি এতে অন্তর্ভুক্ত থাকে। তবুও, সুবিধাটি স্বচ্ছতার অভাবের চেয়ে বেশি নয়।
সিটিএকে

12
আমি দেখতে পাচ্ছি না কিভাবে এটি আরও পরিষ্কার। এটি হয় অপ্রয়োজনীয়তা বা অস্পষ্টতা যুক্ত করে: "সমস্ত" এর অর্থ "এই 3 এর সমষ্টি" বা "এই এনামের সমস্ত কিছু" কি হয়? আমি যদি একটি নতুন মান যুক্ত করি তবে আমিও কি এটি সমস্তটিতে যুক্ত করব? যদি আমি দেখি যে অন্য কারও কাছে নতুনের সাথে নতুন মান যোগ করা হয়নি , তা কি ইচ্ছাকৃত? ~ 0 স্পষ্ট হয়।
কেন

16
ব্যক্তিগত পছন্দকে বাদ দিয়ে, যদি, 0 এর অর্থ ওপি-র কাছে যেমন আপনার এবং আমি বুঝতে পারি তেমন পরিষ্কার ছিল তবে তিনি কখনই এই প্রশ্নটি প্রথম স্থানে প্রকাশ করতে পারতেন না। আমি নিশ্চিত নই যে এটির তুলনায় একটি পদ্ধতির বিপরীতে স্পষ্টতা সম্পর্কে কি বলে।
শান উজ্জ্বল

9
যেহেতু কিছু প্রোগ্রামার যারা সি # ব্যবহার করে এখনও << এর অর্থ কী তা এখনও জানেন না, তাই আরও স্পষ্টতার জন্য আমাদেরও কি এই চারপাশে কোড করা উচিত? আমি মনে করি না.
কুর্ট কলার

4
@ পল, এ ধরণের পাগল। চলুন ব্যবহার বন্ধ করা যাক; ইংরেজিতে কারণ অনেক লোক এর ব্যবহার বুঝতে পারে না। বা words সমস্ত শব্দ তারা জানে না। বাহ, অপারেটরগুলির একটি ছোট সেট, এবং আমাদের এমন লোকদের জন্য আমাদের কোডটি বোকার মতো করা উচিত যা জানেন না যে বিটগুলি কী কী এবং কীভাবে সেগুলি পরিচালনা করতে পারে?
কার্ট কলার

22
public enum PurchaseMethod
{   
    All = ~0, // all bits of All are 1. the ~ operator just inverts bits
    None =  0,
    Cash =  1,
    Check =  2,
    CreditCard =  4
}

সি # তে দুটি পরিপূরক হওয়ার কারণে, ~0 == -1বাইনারি উপস্থাপনায় সমস্ত বিট 1 হয় এমন সংখ্যা।


দেখে মনে হচ্ছে তারা প্রদানের পদ্ধতির জন্য কিছুটা পতাকা তৈরি করছে: 000 = কিছুই নয়; 001 = নগদ; 010 = চেক; 100 = ক্রেডিট কার্ড; 111 = সমস্ত
ডিলি-ও

এটি দুটির পরিপূরক নয়, এটি সমস্ত বিট উল্টে একটি যুক্ত করে, যাতে দুজনের পরিপূরকটি এখনও 0 হয় The 0 simply কেবল সমস্ত বিট বা তার পরিপূরককে উল্টে দেয়।
বিয়ার্ডো

না, দু'জনের পরিপূরক হ'ল সমস্ত বিট উল্টে।
Configurator

2
@ কনফিগুয়েটর - এটি সঠিক নয়। এই পরিপূরকগুলি হ'ল বিটের একটি সাধারণ বিপরীত।
ডেভ মার্কেল

সি # নেতিবাচক মানগুলি উপস্থাপন করতে দুটি পরিপূরক ব্যবহার করে। অবশ্যই ~ দুটি পরিপূরক নয়, তবে সমস্ত বিটকে সহজভাবে উল্টে দেয়। আমি নিশ্চিত না যে আপনি কোথা থেকে পেয়েছেন, বেয়ার্দো
জোহানেস স্কাউব -

17

এটি এর চেয়ে ভাল

All = Cash | Check | CreditCard

সমাধান, কারণ আপনি যদি পরে অন্য কোনও পদ্ধতি যোগ করেন তবে বলুন:

PayPal = 8 ,

আপনি ইতিমধ্যে টিলড-অল দিয়ে শেষ হয়ে গিয়েছেন, তবে অন্যটির সাথে সমস্ত-লাইনটি পরিবর্তন করতে হবে। সুতরাং এটির পরে ত্রুটি-প্রবণতা কম।

শুভেচ্ছা


এটির চেয়েও ভাল যদি আপনিও বলেন কেন এটি কম ত্রুটিযুক্ত। পছন্দ: আপনি যদি কোনও ডাটাবেস / বাইনারি ফাইলে মানটি সংরক্ষণ করেন এবং তারপরে গণনাতে অন্য পতাকা যুক্ত করেন তবে এটি 'সমস্ত' এর অন্তর্ভুক্ত থাকবেন যার অর্থ 'সব' সবসময় সবই বোঝায়, এবং যতক্ষণ না ততক্ষণ পতাকা একই হয় :)।
এইডিয়াকাপি

11

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

All = Cash | Check | CreditCard

আপনার কাছে অতিরিক্ত সুবিধা রয়েছে যা অন্য মান (-1) এর Cash | Check | CreditCardসাথে মূল্যায়ন করবে Allএবং সমস্ত মান সমেত যখন সকলের সমান নয়। উদাহরণস্বরূপ, আপনি যদি ইউআইতে তিনটি চেক বাক্স ব্যবহার করেন

[] Cash
[] Check
[] CreditCard

এবং তাদের মানগুলি যোগ করে এবং ব্যবহারকারী তাদের সমস্তটি নির্বাচন করে, আপনি Allফলস্বরূপ এনামে দেখতে পাবেন ।


এজন্য আপনি myEnum.HasFlag()পরিবর্তে ব্যবহার করেন : ডি
পাইরিটি

@ পিরিটি: আপনার মন্তব্যের সাথে আমার যা কিছু আছে তার কী কী সম্পর্ক আছে?
কনফিগারেটর

যেমন ... যদি আপনি "সমস্ত" এর জন্য ~ 0 ব্যবহার করেন তবে আপনি এর মতো কিছু করতে পারেন All.HasFlag(Cash | Check | CreditCard)এবং এটি সত্যের কাছে পৌঁছে যাবে। ==সর্বদা ~ 0 দিয়ে কাজ করে না বলে একটি কাজ হবে।
পাইরিটি

ওহ, আমি আপনি ডিবাগারে যা দেখেন তার সাথে কথা বলছিলাম ToString- ব্যবহার সম্পর্কে নয় == All
কনফিগারেটর

9

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

PaintCells (clipBounds, 
    DataGridViewPaintParts.All & ~DataGridViewPaintParts.SelectionBackground);

~অপারেটর ব্যতীত কোডটি সম্ভবত এমন কিছু দেখায়:

PaintCells (clipBounds, DataGridViewPaintParts.Background 
    | DataGridViewPaintParts.Border
    | DataGridViewPaintParts.ContentBackground
    | DataGridViewPaintParts.ContentForeground
    | DataGridViewPaintParts.ErrorIcon
    | DataGridViewPaintParts.Focus);

... কারণ গণনাটি এমন দেখাচ্ছে:

public enum DataGridViewPaintParts
{
    None = 0,
    Background = 1,
    Border = 2,
    ContentBackground = 4,
    ContentForeground = 8,
    ErrorIcon = 16,
    Focus = 32,
    SelectionBackground = 64,
    All = 127 // which is equal to Background | Border | ... | Focus
}

শান ব্রাইটের উত্তরের সাথে এই এনামের মিল লক্ষ্য করুন?

আমি মনে করি যে আমার পক্ষে সবচেয়ে গুরুত্বপূর্ণ ~বিষয়টি হ'ল এটি হ'ল এনওমের একই অপারেটর এটি কোডের একটি সাধারণ লাইনের মতো।


আপনার দ্বিতীয় কোড ব্লক সালে করা উচিত নয় &গুলি হতে |গুলি?
রিক

@ ক্লিকরিক, ধরার জন্য ধন্যবাদ দ্বিতীয় কোড ব্লকটি আসলে এখন বোধগম্য।
মাইক

5

এটি একটি পরিপূরক অপারেটর, এখানে একটি নিবন্ধ যা আমি প্রায়শই বিটওয়াইজ অপারেটরদের জন্য উল্লেখ করি

http://www.blackwasp.co.uk/CSharpLogicalBitwiseOps.aspx

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

http://msdn.microsoft.com/en-us/library/cc138362.aspx


1

বিকল্পটি আমি ব্যক্তিগতভাবে ব্যবহার করি যা @ সান ব্রাইটের উত্তর চেয়ে একই কাজ করে তবে আমার কাছে আরও ভাল দেখাচ্ছে, এটি কি:

[Flags]
public enum PurchaseMethod
{
    None = 0,
    Cash = 1,
    Check = 2,
    CreditCard = 4,
    PayPal = 8,
    BitCoin = 16,
    All = Cash + Check + CreditCard + PayPal + BitCoin
}

লক্ষ্য করুন কিভাবে ঐ সংখ্যা, যা দুই সকল ক্ষমতার হয় বাইনারি প্রকৃতি, তোলে নিম্নলিখিত বিবৃতি সত্য: (a + b + c) == (a | b | c)। এবং আইএমএইচও, +আরও ভাল দেখাচ্ছে।


1

আমি with এর সাথে কিছু পরীক্ষা-নিরীক্ষা করেছি এবং এটি খুঁজে পেয়েছি যে এতে সমস্যাগুলি হতে পারে। লিনকিপ্যাডের এই স্নিপেটটি বিবেচনা করুন যা দেখায় যে সমস্ত মান একসাথে বাড়ে যাওয়ার পরে সমস্ত এনাম মান প্রত্যাশা অনুযায়ী আচরণ করে না।

void Main()
{
    StatusFilterEnum x = StatusFilterEnum.Standard | StatusFilterEnum.Saved;
    bool isAll = (x & StatusFilterEnum.All) == StatusFilterEnum.All;
    //isAll is false but the naive user would expect true
    isAll.Dump();
}
[Flags]
public enum StatusFilterEnum {
      Standard =0,
      Saved =1,   
      All = ~0 
}

স্ট্যান্ডার্ডটি 0 মানটি পাওয়া উচিত নয়, তবে 0 এর চেয়ে বেশি কিছু পেতে পারে
অ্যাড্রিয়ান ইফটোড

0

কেবল যুক্ত করতে চান, আপনি যদি [পতাকা] এনাম ব্যবহার করেন তবে বিটওয়াইস বাম শিফট অপারেটরটি ব্যবহার করা আরও সুবিধাজনক হতে পারে:

[Flags]
enum SampleEnum
{
    None   = 0,      // 0
    First  = 1 << 0, // 1b    = 1d
    Second = 1 << 1, // 10b   = 2d
    Third  = 1 << 2, // 100b  = 4d
    Fourth = 1 << 3, // 1000b = 8d
    All    = ~0      // 11111111b
}

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