मैं कक्षा B में SomeProperty के लिए PropertyChanged कैसे बढ़ाऊं?

यह उदाहरण संकलित नहीं है क्योंकि PropertyChanged इस तरह से पहुंच योग्य नहीं है...

public class A : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
}

public class B : A
{
    private object _someProperty;

    public object SomeProperty
    {
        get => _someProperty;
        set
        {
            _someProperty = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SomeProperty)))
        }
    }
}
1
Jogge 20 फरवरी 2019, 17:56

1 उत्तर

सबसे बढ़िया उत्तर

समाधान 1:

आप इसका उपयोग कर सकते हैं RaisePropertyChangedExtension:

public static class RaisePropertyChangedExtension
{
    public static void RaisePropertyChanged(this INotifyPropertyChanged @this, [CallerMemberName] string propertyName = null)
    {
        var declaringType = @this.GetType().GetEvent(nameof(INotifyPropertyChanged.PropertyChanged)).DeclaringType;
        var propertyChangedFieldInfo = declaringType.GetField(nameof(INotifyPropertyChanged.PropertyChanged), BindingFlags.Instance | BindingFlags.NonPublic);
        var propertyChangedEventHandler = propertyChangedFieldInfo.GetValue(@this) as PropertyChangedEventHandler;
        propertyChangedEventHandler?.Invoke(@this, new PropertyChangedEventArgs(propertyName));
    }
}

इस कदर:

public class B : A
{
    private object _someProperty;

    public object SomeProperty
    {
        get => _someProperty;
        set
        {
            _someProperty = value;
            this.RaisePropertyChanged();
        }
    }
}

मेरी राय में यह अब तक का सबसे अच्छा समाधान है जिसे मैं जानता हूं।

नुकसान यह है कि आप इस तरह से किसी अन्य वर्ग से PropertyChanged बढ़ा सकते हैं:

public class C
{
    public C(B b)
    {
        b.RaisePropertyChanged(nameof(b.SomeProperty));
    }
}

इस तरह से अन्य वर्गों से PropertyChanged उठाना अच्छा अभ्यास नहीं है, इसलिए मैं इस नुकसान से चिंतित नहीं हूं।

यह समाधान थॉमस लेवेस्क के यहां दिए गए उत्तर से प्रेरित है: साधारण छोटा INotifyPropertyबदला हुआ कार्यान्वयन

समाधान 2:

आप आधार वर्ग A में एक संरक्षित RaisePropertyChanged बना सकते हैं:

public class A : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

और व्युत्पन्न वर्ग B में विधि को कॉल करें:

public class B : A
{
    private object _someProperty;

    public object SomeProperty
    {
        get => _someProperty;
        set
        {
            _someProperty = value;
            RaisePropertyChanged();
        }
    }
}

नुकसान यह है कि आपके द्वारा बनाए जा रहे प्रत्येक नए आधार वर्ग के लिए आपको RaisePropertyChanged पद्धति को लागू करना होगा, इसके विपरीत आप समाधान 1 के नुकसान से बचेंगे।

6
Community 20 जून 2020, 12:12