访问PropertChangedCallback中的私有方法的非常奇怪的行为

本文关键字:非常 有方法 PropertChangedCallback 访问 | 更新日期: 2023-09-27 18:16:02

好!我问这个只是出于好奇,因为这对我来说很奇怪

为了便于讨论,我们假设我在一个名为DynamicGridControl的类中定义了一个DependencyProperty和一个private方法,如下所示:

public static readonly DependencyProperty ZoomFactorProperty =
    DependencyProperty.Register("ZoomFactor", typeof(double), typeof(DynamicGridControl), new UIPropertyMetadata(1.0, new PropertyChangedCallback(OnZoomFactorPropertyChanged)));
...
private void forceAdornerRender()
{
    //Do Something
}

当然,我在类中有一个static事件处理程序,如下所示:

private static void OnZoomFactorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var vm = (DynamicGridControl)d;
    if (vm != null)
    {
        vm.forceAdornerRender();
    }
}

问题是,为什么我能够在没有任何错误或警告的情况下编译这段代码?!我正在访问该类的私有方法,这当然不应该被允许。我缺少什么吗?OOP中是否有我不知道的规则?

提前谢谢。

访问PropertChangedCallback中的私有方法的非常奇怪的行为

可以访问同一类实例上的private成员,甚至在static成员中也是如此。

在实现IEquatable<T>IComparable<T>等时,可以访问同一类的另一个实例上的私有成员

public class ClassA : IEquatable<ClassA>
{
  private int _value;
  public bool Equals(ClassA other)
  {
    return _value == other._value;
  }
}

来自static的访问专门用于运营商:

public class ClassA 
{
  private string _value;
  public ClassA(string value)
  {
    _value = value;
  }
  public static ClassA operator +(ClassA first, ClassA second)
  {
    return new ClassA(first._value + second._value);
  }
  public static implicit operator string(ClassA a)
  {
    return a._value;
  }
}

一个相关的提示:您可以从嵌套类访问外部类的private成员。

public class ClassA
{
     private string _foo = "foo";
     private class ClassB
     {
          public string Bar(ClassA a)
          {
                return a._foo;
          }
     }
}

有人提出了一个问题:这违反OOP吗
我真的不认为是这样。private成员意味着它可以从类中访问,在所有这些示例中,它都是从同一个类中访问的。我认为,如果没有这个功能,破坏封装和降低内聚性的风险会更大,因为在某些情况下,我们将被迫公开更多特定于实现的信息,而不是给定模型所需的信息。

假设您有对该实例的引用,则类的静态成员仍然可以访问同一类的私有实例方法。

例如,以下操作很好:

class TestClass
{
    public static void TestStaticMethod()
    {
        TestClass instance = new TestClass();
        instance.PrivateMethod();
    }
    private void PrivateMethod()
    { 
        //Do Something
    }
}