2011-04-27 10 views
5

मैं मुख्य रूप से एक सी ++ डेवलपर हूं, लेकिन हाल ही में मैं सी # में एक परियोजना पर काम कर रहा हूं। ऑब्जेक्ट प्रारंभकर्ताओं का उपयोग करते समय आज मुझे कुछ व्यवहार का सामना करना पड़ा जो कम से कम मेरे लिए अप्रत्याशित था। मुझे आशा है कि यहां कोई व्यक्ति यह बता सकता है कि क्या हो रहा है।सी # में, फ़ील्ड प्रारंभकर्ता और ऑब्जेक्ट प्रारंभकर्ता कैसे इंटरैक्ट करते हैं?

उदाहरण A

public class Foo { 
    public bool Bar = false; 
} 

PassInFoo(new Foo { Bar = true }); 

उदाहरण B

public class Foo { 
    public bool Bar = true; 
} 

PassInFoo(new Foo { Bar = false }); 

उदाहरण एक काम करता है के रूप में मैं उम्मीद थी। PassInFoo में पारित ऑब्जेक्ट बार को सत्य पर सेट किया गया है। हालांकि, उदाहरण बी में, foo.Bar ऑब्जेक्ट प्रारंभकर्ता में झूठा असाइन किए जाने के बावजूद सत्य पर सेट है। उदाहरण बी में ऑब्जेक्ट प्रारंभकर्ता को क्या अनदेखा किया जा रहा है?

+6

कुछ भी नहीं। आप जो देख रहे हैं उसे आप नहीं देख रहे हैं। – mquander

+3

मैं इसे पुन: पेश नहीं कर सकता, नेट 3.5, आपके पास कौन सा संस्करण है और क्या आप वाकई यह व्यवहार कर रहे हैं जो आप देख रहे हैं? –

+2

ऑब्जेक्ट प्रारंभकर्ता से पहले कन्स्ट्रक्टर चलाया जाएगा और फील्ड प्रारंभकर्ता कन्स्ट्रक्टर का हिस्सा हैं। सी # चश्मा देखें: 7.6 से।10 - किसी ऑब्जेक्ट निर्माण अभिव्यक्ति की प्रसंस्करण जिसमें ऑब्जेक्ट प्रारंभकर्ता या संग्रह प्रारंभकर्ता शामिल है, पहले प्रस्तुति कन्स्ट्रक्टर को प्रोसेस करना और उसके बाद ऑब्जेक्ट प्रारंभकर्ता (§7.6.10.2) या संग्रह प्रारंभकर्ता (§7.6) द्वारा निर्दिष्ट सदस्य या तत्व प्रारंभिक प्रक्रियाओं को संसाधित करना शामिल है। 10.3)। – VinayC

उत्तर

3

क्या हो रहा है यह देखने का सबसे आसान तरीका यह है कि लाइन-दर-लाइन होने पर अपने बयान को बराबर में तोड़ना है।

मूल:

PassInFoo(new Foo { Bar = false }); 

बाहर टूटी:

var tmp = new Foo(); //Bar initialized to true 
tmp.Bar = false; 
PassInFoo(tmp); 
+0

बीटीडब्ल्यू, मैंने ऊपर 3.5 और 4.0 में परीक्षण किया और दोनों मामलों में, बार वास्तव में 'पासइनफू' के अंदर झूठा है। – Thomas

+0

मैंने अभी यह मेरी यूनिटी 3 डी प्रोजेक्ट में एक कोशिश की है और यह सही तरीके से काम करता है। यूनिट या मोनो डेवलपमेंट ऑब्जेक्ट प्रारंभकर्ता असाइनमेंट को अनदेखा करने के कुछ 'अनुकूलन' कर रहे हैं यदि असाइनमेंट प्रकार के डिफ़ॉल्ट मान (मेरे उदाहरण कोड में बूल के लिए गलत) हैं। मुझे शायद यह प्रश्न उन समुदायों को अधिक विशिष्ट उत्तर के लिए लेना होगा। – nschrag

+2

@nschrag - यह पता लगाने के लिए यह बेहद परेशान होगा कि उन वातावरणों में से एक मूल्यांकन आदेश के साथ गड़बड़ कर रहा था। सौभाग्य! – Thomas

2
class Program 
{ 
    static void Main(string[] args) 
    { 
     PassInFoo(new Foo { Bar = false }); 
    } 
    public class Foo 
    { 
     public bool Bar = true; 
    } 

    public static void PassInFoo(Foo obj) 

    { 
     Console.WriteLine(obj.Bar.ToString()); 
     Console.ReadLine(); 
    } 
} 

उपरोक्त कोड ठीक काम कर रहा है, जब फ्रेमवर्क 3.5 (गलत कंसोल विंडो पर प्रदर्शित होता है) के साथ सत्यापित।

3

मुझे एकता & मोनो के साथ एक ही समस्या थी।

मैं कंस्ट्रक्टर में फ़ील्ड को प्रारंभ करके और फिर ऑब्जेक्ट प्रारंभकर्ताओं के साथ ओवरराइट करके इसे प्राप्त कर रहा था।

हाउवर! पहले यह काम नहीं किया था। इसलिए मैंने फ़ील्ड को बैकिंग फ़ील्ड वाले गुणों के साथ बदल दिया और यह अपेक्षित व्यवहार को मजबूर करना प्रतीत होता था।

5

मैं मोनो (मोनो 2.6.5, यूनिटी 3 डी 4.1.2 एफ 1, ओएसएक्स) के यूनिटी 3 डी निर्माण में इस बदसूरत बग की पुष्टि करता हूं।

ऐसा लगता है कि यह ValueType के लिए डिफ़ॉल्ट मान का उपयोग करना पसंद नहीं करता है, तो आप पास कर सकते हैं एक int != 0, (bool)true आदि ठीक है, लेकिन (int)0 या (bool)false तरह डिफ़ॉल्ट मान में गुजर यह मूल्य है ध्यान नहीं देता।

सबूत:

using UnityEngine; 
using System.Collections; 

public class Foo1 { 
    public bool Bar=false; 
} 

public class Foo2 { 
    public bool Bar=true; 
} 

public class Foo1i { 
    public int Bar=0; 
} 

public class Foo2i { 
    public int Bar=42; 
} 

public class PropTest:MonoBehaviour { 

    void Start() { 
     PassInFoo(new Foo1 {Bar=true}); // FOO1: True (OK) 
     PassInFoo(new Foo2 {Bar=false});/// FOO2: True (FAIL!) 
     PassInFoo(new Foo1i {Bar=42}); // FOO1i: 42 (OK) 
     PassInFoo(new Foo2i {Bar=0});/// FOO2i: 42 (FAIL!) 
     PassInFoo(new Foo2i {Bar=13});/// FOO2i: 13 (OK) 
    } 

    void PassInFoo(Foo1 f) {Debug.Log("FOO1: "+f.Bar);} 

    void PassInFoo(Foo2 f) {Debug.Log("FOO2: "+f.Bar);} 

    void PassInFoo(Foo1i f) {Debug.Log("FOO1i: "+f.Bar);} 

    void PassInFoo(Foo2i f) {Debug.Log("FOO2i: "+f.Bar);} 
} 

एक गैर unity3d OSX मोनो 2.10.11 (मोनो 2-10/2baeee2 बुध जनवरी 16 16:40:16 ईएसटी 2013) पर परीक्षण ठीक चल रहे हैं:

FOO1: True 
FOO2: False 
FOO1i: 42 
FOO2i: 0 
FOO2i: 13 

संपादित करें: unity3d के बगट्रैकर में एक बग में भरा: https://fogbugz.unity3d.com/default.asp?548851_3gh8hi55oum1btda

+1

बस यूनिटी 5 (केवल संपादक) पर चेक किया गया - यह बग अभी भी बनी हुई है। हैप्पी डीबगिंग। –

+1

अभी यूनिटी क्यूए से एक संदेश मिला - वे इस बग को एक अनिश्चित भविष्य की रिलीज में ठीक कर देंगे। –

+0

प्रभावशाली सामान, @ चेनिबाल – Fattie

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