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

时间:2014-07-31 16:42:46

标签: c# wpf oop dependency-properties

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

为了论证,我们只是说我在一个名为DependencyProperty的类中定义了privateDynamicGridControl方法,如下所示:

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中是否有我不知道的规则?

提前致谢。

2 个答案:

答案 0 :(得分:2)

可以访问同一个班级的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成员意味着可以从类中访问它,并且在所有这些示例中,它都是从同一个类中访问的。我认为,如果没有此功能,破坏封装和降低内聚力的风险会更大,因为在某些情况下,我们会强制公开更多特定于实现的信息,而不是给定模型的保证。

答案 1 :(得分:0)

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

例如,以下工作正常:

class TestClass
{
    public static void TestStaticMethod()
    {
        TestClass instance = new TestClass();

        instance.PrivateMethod();
    }

    private void PrivateMethod()
    { 
        //Do Something
    }
}