如何防止继承属性的修改?

时间:2021-02-21 23:34:18

I added some extra stuff to the standard wpf combobox. In the constructor I set two properties:

我添加了一些额外的东西到标准的wpf combobox。在构造函数中,我设置了两个属性:

public SmartComboBox()
            : base()
        {
            this.IsEditable = true;
            this.IsTextSearchEnabled = false;
            ...
        }

The two properties are inherited from System.Windows.Controls.ComboBox. How do I prevent the modification of these two properties after I set their values in the constructor?

这两个属性是从System.Windows.Controls.ComboBox继承的。在构造函数中设置了这两个属性的值后,如何防止它们的修改?

4 个解决方案

#1


1  

You can't fully prevent it, the closest you can come is re-declaring the properties as new

你不能完全阻止它,你能做的最接近的事情就是重新声明属性为new

public SmartComboBox()
{
    base.IsEditable = true;
    base.IsTextSearchEnabled = false;
    ...
}

public new bool IsEditable { get { return base.IsEditable; } }
public new bool IsTextSearchEnabled { get { return base.IsTextSearchEnabled; } }

The downside to this is that new is not an override, if the object is cast as its parent then the property can be set.

这样做的缺点是new不是覆盖,如果对象被转换为其父对象,那么可以设置属性。

The other option is to wrap the class as Tigran mentioned, however the pita with that is exposing all the other properties you need.

另一种选择是像Tigran提到的那样封装类,但是使用pita公开您需要的所有其他属性。

#2


6  

Short answer: you can't, as that properties modifiers can not be changed by you. If you want to hide an implementation, just encapsulate ComboBox class inside your class.

简短的回答:你不能,因为属性修饰符不能被你改变。如果希望隐藏实现,只需将ComboBox类封装到类中。

public class SmartComboBox {

     private ComboBox _uiCombo = ....
}

And also in addition another thing yet:

另外还有一件事

In your example, in the code presented, there is no any reason of explicitly calling base() on ctor, as it will be called by CLR

在您的示例中,在给出的代码中,没有任何理由在ctor上显式地调用base(),因为它将被CLR调用

#3


1  

What if you override the metadata for the IsEditableProperty and play with PropertyChangedCallBack and CorceValueCallBack? http://msdn.microsoft.com/en-us/library/ms597491.aspx

如果重写IsEditableProperty的元数据并使用PropertyChangedCallBack和CorceValueCallBack,会怎么样?http://msdn.microsoft.com/en-us/library/ms597491.aspx

#4


0  

If IsEditable is marked as virtual, it should be trivial to just do

如果IsEditable标记为虚,那么仅仅这样做应该是微不足道的

bool iseditableSet=false;
override bool IsEditable
{
    get;
    set
    {
      if(!iseditableSet){
        iseditableSet=true;
        base.IsEditable=value;
      }else{
        throw Exception...
    }     
}

If it's not marked as virtual, it's harder, but you can use "hiding" to prevent at least your own code from modifying the property without a very explict base. directive.. Of course, this is physically impossible to do though if you are dealing with a function that takes Combobox and it could possibly modify those properties. Just take it as a lesson why properties should almost always be virtual

如果它没有被标记为虚,那么就比较困难了,但是您可以使用“隐藏”来防止至少您自己的代码在没有明确基础的情况下修改属性。指示. .当然,这在物理上是不可能做到的,如果你处理的是一个带有Combobox的函数,它可能会修改这些属性。只要把它当作一个教训,为什么属性几乎总是虚拟的

#1


1  

You can't fully prevent it, the closest you can come is re-declaring the properties as new

你不能完全阻止它,你能做的最接近的事情就是重新声明属性为new

public SmartComboBox()
{
    base.IsEditable = true;
    base.IsTextSearchEnabled = false;
    ...
}

public new bool IsEditable { get { return base.IsEditable; } }
public new bool IsTextSearchEnabled { get { return base.IsTextSearchEnabled; } }

The downside to this is that new is not an override, if the object is cast as its parent then the property can be set.

这样做的缺点是new不是覆盖,如果对象被转换为其父对象,那么可以设置属性。

The other option is to wrap the class as Tigran mentioned, however the pita with that is exposing all the other properties you need.

另一种选择是像Tigran提到的那样封装类,但是使用pita公开您需要的所有其他属性。

#2


6  

Short answer: you can't, as that properties modifiers can not be changed by you. If you want to hide an implementation, just encapsulate ComboBox class inside your class.

简短的回答:你不能,因为属性修饰符不能被你改变。如果希望隐藏实现,只需将ComboBox类封装到类中。

public class SmartComboBox {

     private ComboBox _uiCombo = ....
}

And also in addition another thing yet:

另外还有一件事

In your example, in the code presented, there is no any reason of explicitly calling base() on ctor, as it will be called by CLR

在您的示例中,在给出的代码中,没有任何理由在ctor上显式地调用base(),因为它将被CLR调用

#3


1  

What if you override the metadata for the IsEditableProperty and play with PropertyChangedCallBack and CorceValueCallBack? http://msdn.microsoft.com/en-us/library/ms597491.aspx

如果重写IsEditableProperty的元数据并使用PropertyChangedCallBack和CorceValueCallBack,会怎么样?http://msdn.microsoft.com/en-us/library/ms597491.aspx

#4


0  

If IsEditable is marked as virtual, it should be trivial to just do

如果IsEditable标记为虚,那么仅仅这样做应该是微不足道的

bool iseditableSet=false;
override bool IsEditable
{
    get;
    set
    {
      if(!iseditableSet){
        iseditableSet=true;
        base.IsEditable=value;
      }else{
        throw Exception...
    }     
}

If it's not marked as virtual, it's harder, but you can use "hiding" to prevent at least your own code from modifying the property without a very explict base. directive.. Of course, this is physically impossible to do though if you are dealing with a function that takes Combobox and it could possibly modify those properties. Just take it as a lesson why properties should almost always be virtual

如果它没有被标记为虚,那么就比较困难了,但是您可以使用“隐藏”来防止至少您自己的代码在没有明确基础的情况下修改属性。指示. .当然,这在物理上是不可能做到的,如果你处理的是一个带有Combobox的函数,它可能会修改这些属性。只要把它当作一个教训,为什么属性几乎总是虚拟的