2014-12-29 7 views
19

एफ # "अप्रबंधित" के लिए एक प्रकार बाधा का समर्थन करता है। यह "संरचना" बाधाओं जैसे मूल्य प्रकार की बाधा के समान नहीं है। MSDN notes कि अप्रबंधित बाधा का व्यवहार है:व्यवहार

प्रदान किया गया प्रकार एक अप्रबंधित प्रकार होना चाहिए। अप्रबंधित प्रकार या तो कुछ आदिम प्रकार (sbyte, बाइट, चार, nativeint, unativeint, float32, नाव, int16, uint16, int32, uint32, int64, uint64, या दशमलव), गणन प्रकार, nativeptr < गैर हैं _>, या जेनेरिक संरचना जिसका क्षेत्र सभी अप्रबंधित प्रकार हैं।

यह एक बहुत ही आसान अवरोध प्रकार जब मंच मंगलाचरण कर रही है, और की तुलना में एक बार मैं चाहता हूँ सी # ऐसा करने का एक तरीका था अधिक। सी # में यह बाधा नहीं है। सी # सभी बाधाओं कि सीआईएल में निर्दिष्ट किया जा सकता का समर्थन नहीं करता। इसका एक उदाहरण एक गणना है। सी # में, यदि आप ऐसा नहीं कर सकते हैं:

public void Foo<T>(T bar) where T:enum 

हालांकि, सी # संकलक "enum" बाधा का सम्मान करता है, तो यह एक और पुस्तकालय में यह भर आता है। जॉन स्कीट इस का उपयोग करने के लिए अपने Unconstrained Melody प्रोजेक्ट बनाने के लिए सक्षम है।

तो, मेरा सवाल यह है कि, एफ # की "अप्रबंधित" बाधा है जिसे सीआईएल में एक enum बाधा की तरह प्रदर्शित किया जा सकता है और सी # में खुलासा नहीं किया गया है, या इसे एफ # कंपाइलर द्वारा पूरी तरह से लागू किया गया है जैसे कि कुछ अन्य बाधाएं एफ # समर्थन करता है (स्पष्ट सदस्य प्रतिबंध की तरह)?

+8

एक डिकंपेलर में एक त्वरित उदाहरण को देखते हुए कोई आईएल नहीं है जो इंगित करेगा कि प्रकार बाधित है। मेरा अनुमान है कि जानकारी emdbedded हस्ताक्षर फ़ाइल में शामिल है और इसलिए केवल एफ # कंपाइलर द्वारा लागू किया जाता है। –

+0

@ माइकज़ हाँ, यह निष्कर्ष है कि मैं पहुंच गया हूं। – vcsjones

+0

तब उत्तर की तरह लगता है। – eis

उत्तर

6

मुझे कुछ प्रतिक्रिया मिली है, सावधान रहें कि मुझे एफ # लगभग अच्छी तरह से पता नहीं है। कृपया मुझे कहां जाना है संपादित करें।पहले मूल बातें प्राप्त करना, रनटाइम वास्तव में उन बाधाओं को लागू नहीं करता है जो F # का समर्थन करता है। और सी # समर्थन से अधिक समर्थन करता है।

  • एक संदर्भ प्रकार होना चाहिए (सी # में वर्ग बाधा, एफ # में struct नहीं)
  • एक मान प्रकार
  • चाहिए (सी # और एफ # में struct बाधा) होना चाहिए: यह कमी के सिर्फ 4 प्रकार हैं सी # में एक नया कन्स्ट्रक्टर (नया() बाधा है, एफ # में नया)
  • प्रकार से बाधित है।

और CLI विनिर्देश तो कैसे इन बाधाओं, एक विशिष्ट प्रकार पैरामीटर प्रकार पर मान्य ValueType, Enum, प्रतिनिधि, सरणी और किसी भी अन्य मनमाना प्रकार के अनुसार विभाजित किया जा सकता है पर विशेष नियम तय करता है।

भाषा डिज़ाइनर अपनी भाषा में नवाचार करने के लिए स्वतंत्र हैं, जब तक वे रनटाइम का समर्थन कर सकते हैं। वे स्वयं द्वारा मनमानी बाधाओं को जोड़ सकते हैं, उनके पास उन्हें लागू करने के लिए एक कंपाइलर है। या मनमाने ढंग से रनटाइम का समर्थन करने वाले किसी का समर्थन नहीं करना चुनते हैं क्योंकि यह उनके भाषा डिज़ाइन में फिट नहीं होता है।

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

namespace FSharpLibrary 

type FSharpType<'T when 'T : unmanaged>() = 
    class end 

आशा मुझे लगता है कि अधिकार मिल गया। और एक सी # परियोजना में इस्तेमाल:

class Program { 
    static void Main(string[] args) { 
     var obj = new Example(); // fine 
    } 
} 
class Foo { } 
class Example : FSharpLibrary.FSharpType<Foo> { } 

संकलित करता है तथा ठीक कार्यान्वित करता है, बाधा वास्तव में सब पर लागू नहीं होता। यह नहीं हो सकता है, रनटाइम इसका समर्थन नहीं करता है।

+3

ध्यान दें कि यह एक शानदार उदाहरण है, आपको वास्तव में 'कक्षा फू' का उपयोग करना चाहिए क्योंकि एक खाली 'संरचना' 'अप्रबंधित' बाधा की परिभाषा को फिट करता है (एक 'संरचना' जिसमें केवल अप्रबंधित प्रकार होते हैं) – David

+0

आप सही हैं, धन्यवाद! –

+0

अरवल के जवाब में आईएल को देखते हुए, ऐसा लगता है कि 'संकलन मैपिंग' वास्तव में बाधा को एन्कोड करने के लिए उपयोग नहीं किया जाता है। – svick

5

तो, ILDASM में एक छोटा सा नमूना खोलने, हम निम्नलिखित एफ # कोड

open System.Collections 

type Class1<'T when 'T : unmanaged> = 
    class end 

type Class2<'T> = 
    class end 

type Class3<'T when 'T :> IEnumerable> = 
    class end 

.class public auto ansi serializable beforefieldinit FSharpLibrary.Class1`1<T> 
     extends [mscorlib]System.Object 
{ 
    .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (01 00 03 00 00 00 00 00) 
} // end of class FSharpLibrary.Class1`1 

.class public auto ansi serializable beforefieldinit FSharpLibrary.Class2`1<T> 
     extends [mscorlib]System.Object 
{ 
    .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (01 00 03 00 00 00 00 00) 
} // end of class FSharpLibrary.Class2`1 

.class public auto ansi serializable beforefieldinit FSharpLibrary.Class3`1<([mscorlib]System.Collections.IEnumerable) T> 
     extends [mscorlib]System.Object 
{ 
    .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (01 00 03 00 00 00 00 00) 
} // end of class FSharpLibrary.Class3`1 

विशेष रूप से निम्नलिखित आईएल हो जाता है देखते हैं, Class2 अबाधित सामान्य पैरामीटर है, और पूरी तरह से मेल खाता है Class1 भले ही TClass1 में unmanaged करने के लिए विवश किया जाता है। इसके विपरीत, Class3 इस दिए गए पैटर्न से मेल नहीं खाता है, और हम स्पष्ट रूप से स्पष्ट :> IEnumerable आईएल में बाधा देख सकते हैं।

इसके अलावा, निम्नलिखित सी # कोड

public class Class2<T> 
{ } 

public class Class3<T> 
    where T : IEnumerable 
{ } 

हो जाता है

.class public auto ansi beforefieldinit CSharpLibrary.Class2`1<T> 
     extends [mscorlib]System.Object 
{ 
} // end of class CSharpLibrary.Class2`1 

.class public auto ansi beforefieldinit CSharpLibrary.Class3`1<([mscorlib]System.Collections.IEnumerable) T> 
     extends [mscorlib]System.Object 
{ 
} // end of class CSharpLibrary.Class3`1 

कौन सा, के एफ # अपवाद के साथ कंस्ट्रक्टर (.ctor रों) और Serializable झंडे -generated, मैच एफ # कोड जनरेट ।

Class1 करने के लिए कोई अन्य संदर्भ के साथ इस प्रकार का मतलब है कि संकलक, नहीं है आईएल स्तर पर, खाते में unmanaged बाधा लेने, और संकलित उत्पादन में अपनी उपस्थिति के लिए कोई आगे संदर्भ छोड़ दें।

4

CorGenericParamAttr Enumeration CorHdr.h में सीआईएल स्तर पर सभी संभावित बाधा झंडे सूचीबद्ध करता है, इसलिए एक अप्रबंधित बाधा पूरी तरह से एफ # कंपाइलर द्वारा लागू की जाती है।

typedef enum CorGenericParamAttr { 
    gpVarianceMask      = 0x0003, 
    gpNonVariant      = 0x0000, 
    gpCovariant      = 0x0001, 
    gpContravariant     = 0x0002, 

    gpSpecialConstraintMask   = 0x001C, 
    gpNoSpecialConstraint    = 0x0000, 
    gpReferenceTypeConstraint   = 0x0004, 
    gpNotNullableValueTypeConstraint = 0x0008, 
    gpDefaultConstructorConstraint  = 0x0010 
} CorGenericParamAttr; 
संबंधित मुद्दे