2009-08-24 9 views
6

के लिए जेनेरिक इंटरफेस मैं संख्या प्रकार से स्वतंत्र कुछ सामान्य संख्या मैनिपुलेशन करने की कोशिश कर रहा हूं। हालांकि, मुझे ऐसा करने के लिए जेनेरिक का उपयोग करने का कोई तरीका नहीं है। पहला विचार आने वाले प्रकारों को एक कथन के साथ फ़िल्टर करना था, लेकिन सभी प्रकार के प्रकार बंद हैं और इसलिए, सामान्य फ़िल्टर के लिए मान्य नहीं हैं। इसके अलावा, जेनेरिक मानक संख्यात्मक संचालन (अतिरिक्त, शिफ्ट, इत्यादि) की अनुमति नहीं देते हैं, इसलिए एकमात्र समाधान जो मैं साथ आ सकता हूं वह गैर-सामान्य रूप से प्रत्येक विधि को फिर से लिखना है। कोई अन्य विचार?सी #: संख्या

private const int BYTE_SIZE = 8; 

    private const int UINT16_SIZE = 16; 

    private const int UINT32_SIZE = 32; 

    private const int UINT64_SIZE = 64; 

    public static byte[] ToBytes(UInt16[] pnaValues) 
    { 
     return ToSmaller<byte, UInt16>(pnaValues, BYTE_SIZE, UINT16_SIZE); 
    } 

    public static byte[] ToBytes(UInt32[] pnaValues) 
    { 
     return ToSmaller<byte, UInt32>(pnaValues, BYTE_SIZE, UINT32_SIZE); 
    } 

    .... 

    public static UInt16[] ToUInt16s(byte[] pnaValues) 
    { 
     return ToLarger<UInt16, byte>(pnaValues, UINT16_SIZE, BYTE_SIZE); 
    } 

    public static UInt16[] ToUInt16s(UInt32[] pnaValues) 
    { 
     return ToSmaller<UInt16, UInt32>(pnaValues, UINT16_SIZE, UINT32_SIZE); 
    } 

    ... 

    public static UInt64[] ToUInt64s(UInt32[] pnaValues) 
    { 
     return ToLarger<UInt64, UInt32>(pnaValues, UINT64_SIZE, UINT32_SIZE); 
    } 

    private static TLarger[] ToLarger<TLarger, TSmaller>(TSmaller[] pnaSmaller, int pnLargerSize, int pnSmallerSize) 
     where TLarger : byte, UInt16, UInt32, UInt64 
     where TSmaller : byte, UInt16, UInt32, UInt64 
    { 
     TLarger[] lnaRetVal = null; 
     int lnSmallerPerLarger = pnLargerSize/pnSmallerSize; 

     System.Diagnostics.Debug.Assert((pnLargerSize % pnSmallerSize) == 0); 

     if (pnaSmaller != null) 
     { 
      System.Diagnostics.Debug.Assert((pnaSmaller % lnSmallerPerLarger) == 0); 

      lnaRetVal = new TLarger[pnaSmaller.Length/lnSmallerPerLarger]; 

      for (int i = 0; i < lnaRetVal.Length; i++) 
      { 
       lnaRetVal[i] = 0; 

       for (int j = 0; j < lnSmallerPerLarger; j++) 
       { 
        lnaRetVal[i] = (lnaRetVal[i] << pnLargerSize) + pnaSmaller[i * lnSmallerPerLarger + j]; 
       } 
      } 
     } 

     return lnaRetVal; 
    } 

    private static TSmaller[] ToSmaller<TSmaller, TLarger>(TLarger[] pnaLarger, int pnSmallerSize, int pnLargerSize) 
     where TSmaller : byte, UInt16, UInt32, UInt64 
     where TLarger : byte, UInt16, UInt32, UInt64 
    { 
     TSmaller[] lnaRetVal = null; 
     int lnSmallerPerLarger = pnLargerSize/pnSmallerSize; 

     System.Diagnostics.Debug.Assert((pnLargerSize % pnSmallerSize) == 0); 

     if (pnaSmaller != null) 
     { 
      lnaRetVal = new TSmaller[pnaLarger.Length * lnSmallerPerLarger]; 

      for (int i = 0; i < lnaRetVal.Length; i++) 
      { 
       for (int j = 0; j < lnSmallerPerLarger; j++) 
       { 
        lnaRetVal[i * lnSmallerPerLarger + (lnSmallerPerLarger - 1 - j)] 
         = pnaLarger[i] >> (j * pnLargerSize); 
       } 
      } 
     } 

     return lnaRetVal; 
    } 

उत्तर

11

वहाँ अंकगणितीय आपरेशनों सांख्यिक प्रकार द्वारा कार्यान्वित के लिए कोई आम इंटरफेस है:

संदर्भ के लिए, निम्नलिखित कोड है कि मैं शुरू में करने की कोशिश की है। Generic operators आपकी समस्या को हल करने में मदद कर सकता है।

+4

विशेष रूप से इस मामले के लिए, 'ऑपरेटर। (TFrom मान) कनवर्ट करें उपयोगी हो सकता है। –

+0

ध्यान दें कि मैंने 'वामशफ्ट' और 'राइटशफ्ट' लागू नहीं किया है, लेकिन वे जोड़ने के लिए तुच्छ होंगे। –

0

पुनर्लेखन शायद सबसे आसान है। एकमात्र अन्य समाधान जिसके साथ मैं आ सकता हूं, टेम्पलेट्स से परे जाना है, एक स्ट्रिंग लिखना जो आपके फ़ंक्शन का प्रतिनिधित्व करता है, प्रकार के लिए प्लेसहोल्डर वर्णों के साथ, फिर इसे प्रत्येक प्रकार के नाम से प्रतिस्थापित करें और इसे रनटाइम पर संकलित करें।

संकलन के कारण प्रारंभिक प्रदर्शन हिट के अलावा इन कार्यों को कॉल करना भी मुश्किल होगा।

+0

पोर्टिंग 'eval()' से सी #? मत्स्यावरोध नहीं! :) –

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