2008-11-26 25 views
11

कुछ सी # कोड के साथ एक अजीब समस्या होने के कारण - एक संपत्ति के लिए गेटटर विधि स्पष्ट रूप से चिह्नित नहीं होने पर वर्चुअल के रूप में दिखाई दे रही है।यह संपत्ति गेटर वर्चुअल क्यों है?

इस वर्ग पर DbKey संपत्ति के साथ समस्या यह दर्शाती है (पूरा कोड):

public class ProcessingContextKey : BusinessEntityKey, IProcessingContextKey 
{ 
    public ProcessingContextKey() 
    { 
     // Nothing 
    } 

    public ProcessingContextKey(int dbKey) 
    { 
     this.mDbKey = dbKey; 
    } 

    public int DbKey 
    { 
     get { return this.mDbKey; } 
     set { this.mDbKey = value; } 
    } 
    private int mDbKey; 

    public override Type GetEntityType() 
    { 
     return typeof(IProcessingContextEntity); 
    } 
} 

जब मैं प्रतिबिंब का उपयोग DbKey संपत्ति का निरीक्षण करने, मैं निम्नलिखित (अप्रत्याशित) परिणाम प्राप्त:

Type t = typeof(ProcessingContextKey); 
PropertyInfo p = t.GetProperty("DbKey"); 
bool virtualGetter = p.GetGetMethod(true).IsVirtual; // True! 
bool virtualSetter = p.GetSetMethod(true).IsVirtual; // False 

वर्चुअल गेटटर क्यों सत्य पर सेट हो जाता है? मुझे झूठी उम्मीद थी, यह देखते हुए कि संपत्ति न तो सार और न ही वर्चुअल है।

पूर्णता के लिए - और दूरदराज संभावना वे प्रासंगिक हैं के लिए, यहाँ BusinessEntityKey, IProcessingContextKey, और IBusinessEntityKey के लिए घोषणाओं हैं:

public abstract class BusinessEntityKey : IBusinessEntityKey 
{ 
    public abstract Type GetEntityType(); 
} 

public interface IProcessingContextKey : IBusinessEntityKey 
{ 
    int DbKey { get; } 
} 

public interface IBusinessEntityKey 
{ 
    Type GetEntityType(); 
} 

आपकी मदद के लिए अग्रिम धन्यवाद।

स्पष्टीकरण - यह मेरे लिए क्यों मायने रखता है?

हम NHibernate का उपयोग कर रहे हैं और आंशिक गेटटर लेकिन निजी सेटर के लिए आधा अतिसंवेदनशील गुणों के आलसी लोडिंग के साथ कुछ मुद्दों का पता लगाया है। इन ऊपर फिक्सिंग के बाद, हम किसी भी अन्य स्थानों पर जहां यह हो सकता है को पकड़ने के लिए एक इकाई परीक्षण कहा:

public void RequirePropertiesToBeCompletelyVirtualOrNot() 
{ 
    var properties 
     = typeof(FsisBusinessEntity).Assembly 
      .GetExportedTypes() 
      .Where(type => type.IsClass) 
      .SelectMany(
       type => 
        type.GetProperties(
         BindingFlags.Instance 
         | BindingFlags.Public 
         | BindingFlags.NonPublic)) 
      .Where(property => property.CanRead 
       && property.CanWrite) 
      .Where(property => 
       property.GetGetMethod(true).IsVirtual 
        != property.GetSetMethod(true).IsVirtual); 

    Assert.That(
     properties.Count(), 
     Is.EqualTo(0), 
     properties.Aggregate(
      "Found : ", 
      (m, p) => m + string.Format("{0}.{1}; ", 
        p.DeclaringType.Name, 
        p.Name))); 
} 

इस इकाई परीक्षण DbKey संपत्ति ऊपर उल्लेख किया पर असफल रहा था, और मैं क्यों समझ में नहीं आया।

+0

साइड सवाल, यह एक समस्या क्यों है? – user7116

उत्तर

21

यह आभासी है क्योंकि यह एक इंटरफ़ेस विधि लागू करता है। जहां तक ​​सीएलआर का संबंध है, इंटरफ़ेस कार्यान्वयन विधियां हमेशा आभासी होती हैं।

6

डीबीकेई संपत्ति गेटर आईएल में आभासी है क्योंकि यह एक इंटरफ़ेस में है। सेटर वर्चुअल नहीं है क्योंकि यह इंटरफ़ेस का हिस्सा नहीं है बल्कि कंक्रीट क्लास का हिस्सा है।

ECMA-335: Common Language Infrastructure धारा 8.9.4 नोट्स:

इंटरफेस स्थिर या आभासी तरीकों हो सकता है, लेकिन उदाहरण के तरीकों नहीं होगा।

इसलिए व्युत्पन्न कक्षा में लागू होने पर आपके इंटरफ़ेस द्वारा परिभाषित गेटर को वर्चुअल चिह्नित किया जाएगा।

5

Link दस्तावेज में जो बताता है कि इंटरफेस को लागू करने वाले गुण हमेशा वर्चुअल चिह्नित होते हैं। यह देखने के लिए कि क्या यह वास्तव में आभासी है (क्योंकि यह एक इंटरफ़ेस लागू करता है) आपको यह भी जांचना होगा कि यह IsFinal है या नहीं।

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