My Custom Sitecore control inherits from Sitecore.Web.UI.HtmlControls.Control. This Class defines the Property Value as follows:
public virtual string Value {
get {
return this.GetViewStateString("Value");
}
set {
if (!(value != this.Value))
return;
this.SetViewStateString("Value", value);
}
}
My custom class is defined as follows:
public class ClientProfileSelector : Sitecore.Web.UI.HtmlControls.Control, IContentField {
...
public override string Value {
get {
return this.MyOwnValue;
}
set {
if (!(value != this.MyOwnValue))
return;
this.MyOwnValue = value;
}
}
...
}
The code of the entire class is available here.
My class is automatically instantiated by Sitecore, but I know it is running because I can step into other methods defined therein. For example the method GetValue() in my custom class calls the field Value like so:
public string GetValue() {
return string.IsNullOrEmpty(CalculatedValue) ? CalculatedValue : Value;
}
but when I step over it after adding breakpoints in both my definition and the base class' one, the execution stops in the base class.
What am I doing wrong?
Related
So, I need to go through my code base and remove all the public setters and change them to private for immutable properties.
I know this will make it harder for me to set the values an I can do that through a constructor. Are there any other ways for me to set the value besides through a constructor?
The point is to limit the access on changing the value.
private string _value;
public SetValue(string value)
{
_value = value;
}
or
ctrl+. on property to encapsulate field
There are several methods that I use to create immutable properties in C#, when I also need to set that property outside of the constructor.
The first scenario is to throw an exception if the object is modified after being set
private object _myProperty;
public object MyProperty
{
public get { return _myProperty; }
public set
{
if(_myProperty == null) { _myProperty = value; }
else { throw new InvalidOperationException("MyProperty can't be changed onece set"); }
}
}
This method doesn't prevent errors before runtime but it can help you catch yourself when you're doing silly things.
Another method is to hide setters using an interface. By explicitly implementing an interface you can hide a property or method from a user unless they cast your class to that specific interface. This doesn't actually make your property immutable, but it helps protect properties from unintentional modification.
public interface MyInterface
{
object MyProperty { get; }
}
public interface MyInterfaceProtected
{
object MyProperty { set; }
}
public class MyClass : MyInterFace, MyInterfaceProtected
{
private object _myProperty;
public object MyProperty { get {return _myProperty;} }
object MyInterfaceProtected.MyProperty
{
set { _myProperty = value; }
}
}
It seems you are talking about C# 6 { get; }. Those properties are settable only from the constructor.
If you will define your property as { get; private set; } you will be able to set it from this class or in derived classes.
I get the exception:
AmbiguousMatchException: ambiguous match found
when opening my Window and the XAML gets parsed. I have a base ViewModel class. It has a property for the SelectedItem property of a DataGrid
public class BaseViewModel<T> : ViewModel, INotifyPropertyChanged where T : MyClass
{
protected T _selectedItem;
public T SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
OnPropertyChanged();
}
}
}
In my inherited ViewModel I override that property which produces the exception
public new MyInheritedClass SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
OnPropertyChanged();
//Do other stuff
}
}
So how to use the overrided property and not get an exception?
Why are you redefining the property in the derived class? The type argument of the derived class should specify the type of the property:
public class MyInheritedClass : BaseViewModel<MyClass>
{
//no need to define a new SelectedItem property...
}
In the above sample code MyInheritedClass already has a SelectedItem property of type MyClass. It is already defined in the base class. You don't need to create a new one.
If the property needs to do something special in the derived class, you should define the property as virtual in the base class:
public virtual T SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
OnPropertyChanged();
}
}
...and override it in the derived class:
public override MyClass SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
OnPropertyChanged();
//Do other stuff
}
}
This happens, if you define a Property (or the accessor of a Dependency property) which already exists in the base class. Because then you make it ambigious. Either you have to override (Topic: virtual) or new (hide) it. Otherwise the reflection happenings in WPF will deal with ambiguity.
Example:
public partial class My : UserControl
{
// this will make the ambiguity with the existing trigges-DP legacy accessor
public int Triggers {get;set;}
// this will not make ambiguities, because it hides the original.
// however it may cause other problems
public new object Background {get;set; }
// also OK, but needs justification as well.
public override object ExistingVirtualProperty {get;set; }
...
I'm having a Property in the Remote Server named HasChar of the type Bool. I need to redefine it in my Derived class with some modification. But the Base Property didn't marked as Partial, abstract or extern. But I need to Redefine, How can I achieve? In the Derived Class, I need to access the HasChar Property of Base Class in the Derived Class, if the value is False, then I have to make the BlogText as String.Empty
Note: The Base Class is in Remote Server, I Can't able to Change it or
initiate for the Changes. The Base Class Property don't marked as
Partial, abstract or extern. Don't create any additional property to achieve this. Kindly give the solution related to Override or similar.
My Base Class
public class BlogBase
{
private string _blogText = string.Empty;
public string BlogText
{
get { return _blogText; };
set
{
_blogText = value;
HasChar = _blogText.Length >0 ? true : false;
}
}
public bool HasChar { get; set; }
}
My Derived Class : Rough Code
public class BlogChild : BlogBase
{
private bool _hasChar = false;
public bool HasChar
{
get { return _hasChar; };
set
{
_hasChar = value;
if(!_hasChar)
BlogText = string.Empty;
}
}
}
Hide the original property with the new keyword.
public new bool HasChar
{
private bool _hasChar;
get { return _hasChar; }
set
{
// do other stuff
_hasChar = value;
}
}
I want to execute some code on derived Form whenever a specific property changes in the base Form.
A form implements some common stuff on forms (skining, etc)
Example:
abstract class A
{
private bool _value;
public abstract void Execute();
public A()
{
_value = false;
}
public bool Value
{
get
{
return _value;
}
set
{
_value = value;
if (value)
{
Execute();
}
}
}
}
class B : A
{
public B()
{
}
public override void Excute()
{
// Do some stuff here
}
}
I have been dealing with abstract methods, but I cannot figure how to solve it.
If I declare A as abstract I cannot open B in the designer.
In fact, the real code is a bit more complex, because I have an A base class (a form with the common functions) and B, C, D wich are derived forms more specific: B with button navitagion, C for special forms, etc. So when I create a form in my application, I must inherit from B, or C, ...
Thanks for your help
You can declare the property as virtual in your base class, then override it in your derived class, calling your Foo method from the derived class's setter. Due to polymorphism, your derived property will always be accessed, even when your object is referenced as a base class instance.
class A
{
public virtual bool Value { get; set; }
}
class B : A
{
public override bool Value
{
get
{
return base.Value;
}
set
{
if (base.Value != value)
{
base.Value = value;
Foo();
}
}
}
private void Foo()
{
// code I want to run when base class property changes
}
}
I have a project called Common along with several other projects. Inside the Common project, I have a class named ItemBase. Inside that class, I have a virtual getter called CachedReference, it looks like so:
public virtual ItemData CachedReference
{
get
{
return new ItemData();
}
}
Now, I'm returning an empty ItemData object because I want the classes that inherit from ItemBase to override this getter so it will refer to the overriden getter and not the default one (I would make it an abstract class, but I can't because the Common project initializes instances of this class).
In my other projects I have a class named Item which inherits from the ItemBase class and overrides the getter. It looks like so:
public override ItemData CachedReference
{
get
{
return LoginServer.Instance.ItemDataProvider[this.MapleId];
}
}
The constructor of the ItemBaseclass uses the CachedReference property to set it's data. However, when I initialize a new instance of the Itemclass that uses the default constructor of ItemBase, it refers to the default getter rather than the overriden one.
Why's that happening? I want to refer the overriden getter only, not the default one so each project can return it's own CachedReference.
EDIT: I've been asked to show how I use CachedReference, so here:
public ItemBase(int mapleId, short quantity = 1)
{
this.MapleId = mapleId;
this.Quantity = quantity;
this.WeaponAttack = this.CachedReference.WeaponAttack;
...
}
This code works as you expect. Can you provide a compilable code of your's that demonstrates your problem?
public static void Main()
{
var derived = new Derived();
}
public class Base
{
protected string _p = "Base";
public virtual string P
{
get { Console.WriteLine("Base get"); return _p; }
set { Console.WriteLine("Base set"); _p = value; }
}
public Base()
{
P = "Base constructor";
}
}
public class Derived : Base
{
public override string P
{
get { Console.WriteLine("Derived get"); return _p; }
set { Console.WriteLine("Derived set"); _p = value; }
}
public Derived()
{
Console.WriteLine(P);
}
}
Output:
Derived set
Derived get
Base constructor