यह एक टिप्पणी मैं चला गया के जवाब में है । उम्मीद है कि यह आपके प्रश्न, शिमी का जवाब देता है। बस टिप्पणी करें, और यदि मैं आपके प्रश्न का उत्तर नहीं देता तो मैं इसे छोटा कर दूंगा या हटा दूंगा।
आपको अपनी कक्षा में लागू होने के लिए इनोटिफ़ाईप्रॉपर्टी चेंजिंग और इनोटिफ़ाईप्रॉपर्टी चेंज इंटरफेस दोनों की आवश्यकता होगी (जब तक यह एक इकाई फ्रेमवर्क ऑब्जेक्ट की तरह कुछ न हो, जो मुझे लगता है कि इन आंतरिक रूप से लागू होता है)।
और इससे पहले कि आप इस संपत्ति के लिए मूल्य निर्धारित करें, आपको PropertyChangingEventArgs कन्स्ट्रक्टर में संपत्ति के नाम का उपयोग करके, NotifyPropertyChanging.PropertyChanging ईवेंट को बढ़ाने की आवश्यकता होगी।
और इस मूल्य को सेट करने के बाद आपको NofityPropertyChanged.PropertyChanged ईवेंट, फिर से संपत्ति के नाम का उपयोग करके संपत्तिChangedEventArgs कन्स्ट्रक्टर में उठाया जा रहा है।
फिर आपको PropertyChanging और PropertyChanged ईवेंट को संभालना होगा। PropertyChanging ईवेंट में, आपको मान को कैश करने की आवश्यकता है। प्रॉपर्टी चेंजेड इवेंट में, आप एक अपवाद की तुलना और फेंक सकते हैं।
संपत्तिChanging/PropertyChanged ईवेंट तर्क से संपत्ति प्राप्त करने के लिए, आपको रिलेक्शन का उपयोग करने की आवश्यकता है।
// PropertyName is the key, and the PropertyValue is the value.
Dictionary <string, object> propertyDict = new Dictionary<object, object>();
// Convert this function prototype to C# from VBNet. I like how Handles is descriptive.
Public Sub PropertyChanging(sender As object, e As PropertyChangingEventArgs) Handles Foo.PropertyChanging
{
if (sender == null || preventRecursion)
{
return;
} // End if
Type senderType = sender.GetType();
PropertyInfo info = senderType.GetProperty(e.PropertyName);
object propertyValue = info.GetValue(sender, null);
// Change this so it checks if e.PropertyName already exists.
propertyDict.Add(e.PropertyName, propertyValue);
} // End PropertyChanging() Event
// Convert this function prototype to C# from VBNet. I like how Handles is descriptive.
Public Sub PropertyChanged(sender As object, e As PropertyChangedEventArgs) Handles Foo.PropertyChanged
{
if (sender == null || preventRecursion)
{
return;
} // End if
Type senderType = sender.GetType();
PropertyInfo info = senderType.GetProperty(e.PropertyName);
object propertyValue = info.GetValue(sender, null);
// Change this so it makes sure e.PropertyName exists.
object oldValue = propertyDict(e.PropertyName);
object newValue = propertyValue;
// No longer needed.
propertyDict.Remove(e.PropertyName);
if (/* some condition */)
{
try {
preventRecursion = true;
info.SetValue(oldValue, null);
Throw New Exception();
} finally {
preventRecursion = false;
} // End try
} // End if
} // End PropertyChanging() Event
ध्यान दें कि मैं प्रीवेन्ट रेक्यूशन का उपयोग कैसे कर रहा हूं, जो एक बुलियन है जिसे मैं इन तरीकों से ऊपर जोड़ना भूल गया? जब आप संपत्ति को अपने पिछले मूल्य पर रीसेट करते हैं, तो इन घटनाओं को याद किया जाएगा।
tl; डॉ
अब आप एक ही घटना है जो INotifyPropertyChanged से विरासत है, लेकिन एक तर्क है जो एक वस्तु पिछले मान के साथ-साथ प्रॉपर्टी नाम का प्रतिनिधित्व रखती है का उपयोग करता है प्राप्त कर सकते हैं।और इससे घटनाओं की संख्या कम हो जाएगी, समान कार्यक्षमता हो सकती है, और इनोटिफ़ाईप्रॉपर्टी चेंज के साथ पिछड़ा संगतता हो सकती है।
लेकिन यदि आप संपत्ति सेट होने से पहले कुछ भी संभालना चाहते हैं (कहें कि संपत्ति एक अपरिवर्तनीय परिवर्तन करता है या आपको उस चर को सेट करने से पहले अन्य गुणों को सेट करने की आवश्यकता है, अन्यथा एक अपवाद फेंक दिया जाएगा) आप सक्षम नहीं होंगे वो करें।
कुल मिलाकर, यह विधि चीजों को करने का एक बहुत पुराना तरीका है। मैं पोकर विलायन के जवाब लेता हूं और इसमें अमान्य डेटा दर्ज किया जा सकता है। लेकिन डेटाबेस को सहेजने की अनुमति नहीं है।
इकाई फ्रेमवर्क सत्यापन के प्रति कुछ उत्कृष्ट कोड है। आप गुणों के माध्यम से अपने गुणों में सत्यापन जोड़ते हैं। और फिर यह उन विशेषताओं को संसाधित करने के काम का ख्याल रखता है। फिर आप IsValid नामक एक संपत्ति बना सकते हैं, जो इकाई फ्रेमवर्क विशिष्ट सत्यापन को कॉल करता है। यह दोनों फ़ील्ड त्रुटियों को भी अलग करता है (जैसे गलत वर्णों में टाइप करना या स्ट्रिंग बहुत लंबा होना), और कक्षा त्रुटियां (जैसे गायब डेटा या विवादित कुंजी)।
फिर आप सत्यापन को नियंत्रित करने के लिए IsValid को बाध्य कर सकते हैं, और अमान्य डेटा दर्ज होने पर वे लाल बबल प्रदर्शित करेंगे। या आप केवल IsValid सत्यापन स्वयं लागू कर सकते हैं। लेकिन यदि IsValid गलत है, तो SaveChanges ईवेंट को सहेजना रद्द करना होगा।
बीटीडब्ल्यू। प्रदान किया गया कोड संकलित नहीं होगा और केवल छद्म कोड होगा (वीबी और सी # मिश्रण)। लेकिन मेरा मानना है कि यह अकेले सी # की तुलना में अधिक वर्णनात्मक है - यह दिखा रहा है कि वास्तव में क्या किया जा रहा है।
PropertyChangingEventArgs का CancelEventArgs से कोई संबंध नहीं है। उनके पास कई बार अलग-अलग उद्देश्यों के लिए विशेष रूप से उपयोग करने की आवश्यकता होती है। विरासत को मजबूर करने के लिए अनियंत्रित जटिलता और निराशा होगी (कसकर उन्हें एक साथ जोड़ना)। PropertyChangingEvent और PropertyChangedEvent है, और मेरा मानना है कि वे उन कार्यक्षमताओं को संतुष्ट करते हैं जिन्हें आप चाहते हैं बिना परिवर्तन किए हैं (उल्लेख नहीं है, जो .NET 1.1 को .NET 4.0 संगतता को तोड़ देगा)। – TamusJRoyce
@TamusJRoyce, ठीक है, मैं सहमत हूं, इसे 'CancelEventArgs' से प्राप्त नहीं होना चाहिए, लेकिन मुझे यह करना चाहिए कि मेरा अन्य अनुरोध उम्मीदवार मूल्य प्रदान करता है (जो इसे प्राप्त करने का आसान तरीका है महत्वपूर्ण विधि विशेषताओं को एक महत्वपूर्ण के साथ प्राप्त करना प्रदर्शन लागत की मात्रा)। – Shimmy