2010-05-07 16 views
13

सभी को नमस्कार, एक त्वरित प्रश्न है कि मैं के बारे में कुछ भी नहीं कर पा रहे ...बड़े झंडे enumerations

मैं एक परियोजना पर काम कर रहा हूँ कि झंडे की एक बड़ी संख्या के साथ ध्वज enumerations की आवश्यकता है मिल गया (40-ish के लिए), और मैं वास्तव में प्रत्येक गणना मूल्य के लिए सटीक मुखौटा में टाइप की तरह नहीं लग रहा है:

public enum MyEnumeration : ulong 
{ 
    Flag1 = 1, 
    Flag2 = 2, 
    Flag3 = 4, 
    Flag4 = 8, 
    Flag5 = 16, 
    // ... 
    Flag16 = 65536, 
    Flag17 = 65536 * 2, 
    Flag18 = 65536 * 4, 
    Flag19 = 65536 * 8, 
    // ... 
    Flag32 = 65536 * 65536, 
    Flag33 = 65536 * 65536 * 2 
    // right about here I start to get really pissed off 
} 

इसके अलावा, मैं भी आशा करती हूं कि मेरे लिए एक आसान (ier) जिस तरह से है कि वहाँ विभिन्न एंडियन मशीनों पर बिट्स की वास्तविक व्यवस्था को नियंत्रित करने के लिए, क्योंकि इन मानों को अंततः नेटवर्क पर क्रमबद्ध किया जाएगा:

public enum MyEnumeration : uint 
{ 
    Flag1 = 1,  // BIG: 0x00000001, LITTLE:0x01000000 
    Flag2 = 2,  // BIG: 0x00000002, LITTLE:0x02000000 
    Flag3 = 4,  // BIG: 0x00000004, LITTLE:0x03000000 
    // ... 
    Flag9 = 256, // BIG: 0x00000010, LITTLE:0x10000000 
    Flag10 = 512, // BIG: 0x00000011, LITTLE:0x11000000 
    Flag11 = 1024 // BIG: 0x00000012, LITTLE:0x12000000 
} 

तो, मैं एक तरह से सोच रहा हूँ अगर कोई अच्छा तरीका मैं अपने enumerations सेट कर सकते हैं की तरह है:

public enum MyEnumeration : uint 
{ 
    Flag1 = flag(1), // BOTH: 0x80000000 
    Flag2 = flag(2), // BOTH: 0x40000000 
    Flag3 = flag(3), // BOTH: 0x20000000 
    // ... 
    Flag9 = flag(9), // BOTH: 0x00800000 
} 

मैं क्या कोशिश की है:

// this won't work because Math.Pow returns double 
// and because C# requires constants for enum values 
public enum MyEnumeration : uint 
{ 
    Flag1 = Math.Pow(2, 0), 
    Flag2 = Math.Pow(2, 1) 
} 

// this won't work because C# requires constants for enum values 
public enum MyEnumeration : uint 
{ 
    Flag1 = Masks.MyCustomerBitmaskGeneratingFunction(0) 
} 

// this is my best solution so far, but is definitely 
// quite clunkie 
public struct EnumWrapper<TEnum> where TEnum 
{ 
    private BitVector32 vector; 
    public bool this[TEnum index] 
    { 
     // returns whether the index-th bit is set in vector 
    } 
    // all sorts of overriding using TEnum as args 
} 

बस सोच रहा है कि किसी के पास कोई अच्छा विचार है, धन्यवाद!

+3

आप यहाँ पाठ के कुछ सौ लाइनों टाइप किया का उपयोग करें। आपने बुलेट को काटने क्यों नहीं दिया और मूल 40 लाइनों को टाइप किया? (आपने 1 << 1, 1 << 2, ... का उपयोग किया हो सकता है लेकिन वैसे भी ...) –

+0

उम्म ... मैं उन समाधानों को प्रस्तुत करना चाहता था जो मैंने कोशिश की थी, "<<" and ">>" होगा काम किया, लेकिन जब मैं केवल एक बार मूल्यांकन किया जाता है तो मुझे अंतर दिखाई नहीं देता है। ऐसा नहीं है कि इसे टाइप करने में मुझे आधे घंटे लगते हैं, पाठ की कुछ सौ पंक्तियां ज्यादा नहीं हैं ...मैं बहुत कम जानकारी की तुलना में बहुत अधिक जानकारी प्रदान करता हूं ... – LorenVS

+1

आप शिफ्ट ऑपरेटर के साथ उलंग की पूरी श्रृंखला का उपयोग कर सकते हैं, आपको केवल कंपाइलर को इंगित करने की आवश्यकता होगी कि आप जो स्थानांतरित कर रहे हैं वह एक उलझन है। 1ul << 63, 'उल' को ध्यान दें 1. –

उत्तर

9

आप एक टी -4 टेम्पलेट लिख सकता है enum उत्पन्न करने के लिए:

टेम्पलेट (MyEnumeration.tt)

<#@ template language="C#" #> 
<#@ output extension=".cs" #> 
using System; 

namespace MyNamespace 
{ 
    [Flags] 
    public enum MyEnumeration : ulong 
    { 
<# 
    ulong value = 1; 
    for(int i = 1; i <= 64; i++) 
    { 
#> 
     Flag<#= i #> = <#= string.Format("0x{0:X8}", value) #>, 
<# 
     value = value << 1; 
    } 
#> 
    } 
} 

सी # कोड परिणामस्वरूप (MyEnumeration.cs)

using System; 

namespace MyNamespace 
{ 
    [Flags] 
    public enum MyEnumeration : ulong 
    { 
     Flag1 = 0x00000001, 
     Flag2 = 0x00000002, 
     Flag3 = 0x00000004, 
     Flag4 = 0x00000008, 
     Flag5 = 0x00000010, 
     Flag6 = 0x00000020, 
     Flag7 = 0x00000040, 
     Flag8 = 0x00000080, 
     Flag9 = 0x00000100, 
     Flag10 = 0x00000200, 
     Flag11 = 0x00000400, 
     Flag12 = 0x00000800, 
     Flag13 = 0x00001000, 
     Flag14 = 0x00002000, 
     Flag15 = 0x00004000, 
     Flag16 = 0x00008000, 
     Flag17 = 0x00010000, 
     Flag18 = 0x00020000, 
     Flag19 = 0x00040000, 
     Flag20 = 0x00080000, 
     Flag21 = 0x00100000, 
     Flag22 = 0x00200000, 
     Flag23 = 0x00400000, 
     Flag24 = 0x00800000, 
     Flag25 = 0x01000000, 
     Flag26 = 0x02000000, 
     Flag27 = 0x04000000, 
     Flag28 = 0x08000000, 
     Flag29 = 0x10000000, 
     Flag30 = 0x20000000, 
     Flag31 = 0x40000000, 
     Flag32 = 0x80000000, 
     Flag33 = 0x100000000, 
     Flag34 = 0x200000000, 
     Flag35 = 0x400000000, 
     Flag36 = 0x800000000, 
     Flag37 = 0x1000000000, 
     Flag38 = 0x2000000000, 
     Flag39 = 0x4000000000, 
     Flag40 = 0x8000000000, 
     Flag41 = 0x10000000000, 
     Flag42 = 0x20000000000, 
     Flag43 = 0x40000000000, 
     Flag44 = 0x80000000000, 
     Flag45 = 0x100000000000, 
     Flag46 = 0x200000000000, 
     Flag47 = 0x400000000000, 
     Flag48 = 0x800000000000, 
     Flag49 = 0x1000000000000, 
     Flag50 = 0x2000000000000, 
     Flag51 = 0x4000000000000, 
     Flag52 = 0x8000000000000, 
     Flag53 = 0x10000000000000, 
     Flag54 = 0x20000000000000, 
     Flag55 = 0x40000000000000, 
     Flag56 = 0x80000000000000, 
     Flag57 = 0x100000000000000, 
     Flag58 = 0x200000000000000, 
     Flag59 = 0x400000000000000, 
     Flag60 = 0x800000000000000, 
     Flag61 = 0x1000000000000000, 
     Flag62 = 0x2000000000000000, 
     Flag63 = 0x4000000000000000, 
     Flag64 = 0x8000000000000000, 
    } 
} 

आदेश टी -4 टेम्पलेट संपादित करने के लिए, मैं तुम्हें this one की तरह एक टी -4 संपादक प्लगइन (यह आप वाक्य रचना हाइलाइटिंग देता है और Intellisense)

+0

जैसा ही है, ऐसा करने के लिए आपको शायद ही कभी टी 4 सिस्टम की आवश्यकता है। किसी भी स्क्रिप्टिंग प्रोग्रामिंग भाषा में एक साधारण पाश इस के मूल को मुद्रित कर सकता है। –

+0

हां, लेकिन टी 4 विजुअल स्टूडियो में बनाया गया है, जो इसे इस तरह की चीजों के लिए बहुत सुविधाजनक बनाता है ... –

+0

अच्छा। क्या 64 से ऊपर जाना संभव है? – arao6

0

endianes संबोधित करने के लिए आपके पास दो विकल्प है कि मैं अपने सिर

1- क्रमबद्धता अपने आप को संभाल और System.Net.IPAddress.HostToNetworkOrder का उपयोग के ऊपर से सोच सकते हैं पर आदेश देने से लगातार बाइट सुनिश्चित करने के लिए है ठीक है जब आप deserialize जब तार और निश्चित रूप से System.Net.IPAddress.NetworkToHostOrder के साथ रिवर्स करते हैं।

मेरे पास द्विआधारी क्रमबद्धता के विषय पर दो पुरानी ब्लॉग पोस्ट हैं, वे एक अद्यतन के साथ कर सकते हैं लेकिन यह एक प्रारंभिक बिंदु है।

http://taylorza.blogspot.com/2010/04/archive-binary-data-from-structure.html
http://taylorza.blogspot.com/2010/04/archive-structure-from-binary-data.html

2- एक्सएमएल को क्रमानुसार, जिसमें मामले endianes कोई मुद्दा नहीं है लेकिन निश्चित रूप से इस तरह के पेलोड आकार और सामान्य प्रदर्शन के रूप में अन्य कमियां देखते हैं।

9

क्यों न सिर्फ कार्य करें:

public enum MyEnumeration : ulong 
{ 
    Flag1 = 1, 
    Flag2 = 1 << 1, 
    Flag3 = 1 << 2, 
    Flag4 = 1 << 3, 
    . 
    . 
    . 
    Flag30 = 1 << 29, 
    Flag31 = 1 << 30, 
    Flag32 = 1 << 31 
} 
+0

हम्म ... 8 बिट्स के पीछे थोड़ा स्थानांतरण मेरे लिए अजीब लगता है ... मुझे यकीन नहीं है कि संकलक स्वचालित रूप से इसे संभालता है, लेकिन तकनीकी रूप से, 1 << 8) == 0 थोड़ा एंडियन सिस्टम पर डेटाटाइप के आकार के बावजूद? मैं पूरी तरह से दोपहर के भोजन के लिए बाहर हो सकता हूं, मुझे यकीन नहीं है कि – LorenVS

+7

@LorenVS, आप शिफ्ट ऑपरेटर के साथ उलंग की पूरी श्रृंखला का उपयोग कर सकते हैं, आपको केवल कंपाइलर को इंगित करने की आवश्यकता होगी कि आप जो स्थानांतरित कर रहे हैं वह उलझन में है। 1ul << 63, 'उल' को ध्यान दें 1. –

+3

@LorenVS - संकलक इसके साथ ठीक है। हालांकि, यह डेटा आकार के लिए लपेटा गया है। तो वास्तव में 'int'/'Int32' के लिए, 1 << 33 1 जैसा ही है << 1. चूंकि (क्रिस की टिप्पणी ध्यान दें, हालांकि) हम इस मामले में' ulong' का उपयोग कर रहे हैं, यह% 64 है, इसलिए 1 < <65 1 << 1 –

संबंधित मुद्दे