How to override the property [duplicate] - c#

This question already has answers here:
Can I override a property in c#? How?
(5 answers)
Closed 6 years ago.
in base LocalStorage
public class BaseStorageRepository<T>
{
protected string OneKey = null;
protected string ListKey = null;
public async Task UpdateAllAsync(List<T> data)
{
await BlobCache.LocalMachine.InsertObject(ListKey, data);
}
}
in child
public class CompanyStorageRepository : BaseStorageRepository<Company>
{
protected new string OneKey = "Company";
protected new string ListKey = "CompaniesList";
}
When execution in
UpdateAllAsync
then OneKey == null;
But why ?
After all, I redefined the property in the derived class

After all, I redefined the property in the derived class
No, you hid the field (not property) in the derived class. Effectively the derived class now has two distinct OneKey fields. The base class code is still looking at the field from the base class, not the new one in the derived class.
Also note that fields can't be virtual or overridden. You could set the field value in the derived class's constructor, though:
public class CompanyStorageRepository : BaseStorageRepository<Company>
{
public CompanyStorageRepository()
{
OneKey = "Company";
ListKey = "CompaniesList";
}
}
A marginally better design would be to use properties instead of fields. With properties, you can control (and detect) when a value is changed, and you can change how the value is stored without breaking the classes semi-public signature.

Related

C#: Inherit and override property [duplicate]

This question already has answers here:
C#: override a property of the parent class
(3 answers)
Closed 4 years ago.
I have a class Base which is like:-
class Base
{
public virtual string a=>SomeMethod(a);
}
I need to override the variable a in Base.
class Derived: Base
{
public string a ="Hello";
}
Is this correct?What is the correct way to inherit from Base and override the value of a?
Thanks!
Use the keyword 'override'. However, you cannot use it on fields. If you want to override the virtual property in your base class, create a corressponding property in your derived class.
class Derived: Base
{
public override string a => "Hello";
}

How to have a default method while still be able to override it? [duplicate]

This question already has answers here:
What is the difference between an abstract method and a virtual method?
(28 answers)
Closed 8 years ago.
This is a C# project.
I have several classes inherited from a base class. Most of the child classes have the same behavior while some of them behave differently.
I'm using the new keyword.
public class Parent
{
public DataTable FetchScore()
{
// blahblah
}
}
public class ChildNormal : Parent
{
}
public class ChildOdd : Parent
{
public new DataTable FetchScore()
{
DataTable dt = base.FetchScore();
// blahblah
}
}
But the build says using new is not a good practice.
I cannot use virtual and override either, because I want a default. I don't want to copy the same override implementation many times.
How do I do this in C#?
You need to declare the base virtual (which means it can be overridden if necessary) and override it where you need different behavior from the original. The non-overridden derived class will behave just like the base class.
public class Parent()
{
public virtual DataTable FetchScore()
{
// blahblah
}
}
public class ChildNormal() : Parent
{
}
public class ChildOdd() : Parent
{
public override DataTable FetchScore()
{
DataTable dt = base.FetchScore();
// blahblah
}
}

modifying access permissions from an abstract class in the derived class [duplicate]

This question already has answers here:
Adding a set accessor to a property in a class that derives from an abstract class with only a get accessor
(3 answers)
Closed 9 years ago.
So I have an abstract class called AbstactSearchWithTwoLevelCache that was provided to me. All of its abstract properties only have read access (with a get;). I am not permitted to add a set; to the those abstract properties. Is there a way to change this in the derived class, SearchWithTwoLevelCache? In other words, is there a way to set these properties in the derived class?
If you mark the property with new, you define a new property, like this:
abstract class BaseClass
{
public int Property
{
get { ... }
}
}
class NewClass : BaseClass
{
public new int Property
{
get { return base.Property; }
set { ... }
}
}
EDIT:
The above works if the property in the base class is not abstract. When it is abstract, this will not work since you need to implement it. One option you do have is to create a class in between, like this:
abstract class BaseClass
{
public abstract int Property { get; }
}
class Between : BaseClass
{
public override int Property
{
get { ... }
}
}
class NewClass : Between
{
public new int Property
{
get { return base.Property; }
set { ... }
}
}
This however in no way is an elegant solution. Then, the real answer becomes that you cannot really do this (at least not without the above work around).
I can't imagine a way you can override them directly. Indirectly when you override the abstract class properties, the Getters can retrieve from a private field, and then you can create new properties that have Setters that set those fields.
Kind of a rig I know. Maybe there is a more elegant way around this.

Different Generics T in the same collection [duplicate]

This question already has answers here:
Collection of generic types
(10 answers)
Closed 7 years ago.
public abstract Column<T>
{
private T Value {get;set;}
public abstract string Format();
}
public class DateColumn : Column<DateTime>
{
public override string Format()
{
return Value.ToString("dd-MMM-yyyy");
}
}
public class NumberColumn : Column<decimal>
{
public override string Format()
{
return Value.ToString();
}
}
The problem I have is adding these into a generic collection. I know its possible but how can I store multiple types in a collection etc
IList<Column<?>> columns = new List<Column<?>()
I would really appreciate any advice on achieving this goal. The goal being having different column types stored in the same List. Its worth mentioning I am using NHibernate and the discriminator to load the appropriate object.Ultimately the Value needs to have the type of the class.
Many thanks for your help in advance.
In order to be stored in a List<T> together the columns must have a common base type. The closest common base class of DateColumn and NumberColumn is object. Neither derives from Column<T> but instead a specific and different instantiation of Column<T>.
One solution here is to introduce a non-generic Column type which Column<T> derives from and store that in the List
public abstract class Column {
public abstract object ValueUntyped { get; }
}
public abstract class Column<T> : Column {
public T Value { get; set; }
public override object ValueUntyped { get { return Value; } }
}
...
IList<Column> list = new List<Column>();
list.Add(new DateColumn());
list.Add(new NumberColumn());
Generics are all about specifying type. If you want to use dynamic types, use classic ArrayList instead.
It probably makes sense to derive from a non-generic Column class that wraps up as much of the non-generic common interface of a column... then to declare your list as List<Column>.

C# Inheritance to hide inherited Members

I read other threads like this but they didn't work for me.
I got two classes:
public class ClassA
{
public string _shouldBeInteger;
public string _shouldBeBool;
public string _shouldBeDateTime;
}
public class ClassB : ClassA
{
public int? shouldBeInteger
{
get { return (_shouldBeInteger != null) ? Convert.ToInt32(Convert.ToDouble(_shouldBeInteger)) : new int?(); }
set { _shouldBeInteger = Convert.ToString(value); }
}
//... same thing with datetime etc.
}
If I now create a new object of ClassB I get
_shouldBeInteger, _shouldBeBool, _shouldBeDateTime;
shouldBeInteger,shouldBeBool,shouldBeDateTime
But I want to hide the _variables to the User.
Setting them private in ClassB will override them, but I need to access them in order to parse there string values.
Update
There is a ClassC filling ClassAs' values, which mainly is the reason why they have to be writeable. There is no way for me to change the way that works, but I'm fully in Control of ClassA and ClassB
ClassC //not changeAble for me
{
//infomagic filling values of ClassA
}
Setting ClassA variables to private won't work, because programmer of ClassA produced it in a strange way.
Solution
Because ClassA needs to be writeable, but not readable to other classes than inheritated, I finally got this:
ClassA
{
public string _shouldBeInteger { protected get; set; }
//and so on
}
which causes ClassB to work with theese properties, without giving them outside.
Intellisense still shows them, but you might consider using:
[EditorBrowsable(EditorBrowsableState.Never)]
to solve that.
Thanks to all.
I think you can solve your problem using:
public class ClassA
{
protected string _shouldBeInteger;
protected string _shouldBeBool;
protected string _shouldBeDateTime;
}
so those variables are accessible to derived classes but not to user.
EDITED after user update:
I don't know if this could be a vali solution for you, but try:
public class ClassB : ClassA
{
public new int? _shouldBeInteger
{
get { return (base._shouldBeInteger != null) ?
Convert.ToInt32(Convert.ToDouble(base._shouldBeInteger)) :
new int?(); }
set { base._shouldBeInteger = Convert.ToString(value); }
}
}
Inheritance can't hide the members as you would think. The new modifier exists to "hide" a base member, but that doesn't play nice when talking to base types.
http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
You can either change the access level of the fields (the preferred way) or you can wrap the class instead of inheriting from it and provide simple pass-through methods to delegate to the wrapped class. This is called the Adapter Pattern:
public class ClassB
{
private ClassA _wrappedClass;
}
Just as an aside, your public fields are following the naming convention commonly used for private fields.
The required access level for derived classes is protected. If the members are used publicly but in the same assembly you can use protected internal. If the members are used publicly by other assemblies... I'd suggest refactoring.
The problem is that you declared the fields public in the base class. In order not to violate the polymorphic nature of inheritance, anything public in the base class must be public in all derived classes as well. If you could change that, you could never be sure that a ClassB could be passed to something expecting a ClassA.
Therefore, as other people have suggested, you probably want the base class fields to be declared protected, which is like private except derived classes can see them.
However if you do need to access them via an actual instance of ClassA, you could declare them private and give them virtual public properties which the derived class can then override. This at least allows the derived class to change their behaviour, but it still can't actually hide them.
If that also doesn't fit, then it's probably worth considering using composition instead of inheritance because the substitution principle is actually getting in your way, and that's an inheritance fundamental.
If you don't have control over ClassA, you'll need to create a wrapper/adapter class like so:
public class ClassB
{
private readonly _classA = new ClassA();
public int? shouldBeInteger
{
get
{
return (this._classA._shouldBeInteger != null)
? Convert.ToInt32(Convert.ToDouble(this._classA._shouldBeInteger))
: new int?();
}
set
{
this._classA._shouldBeInteger = Convert.ToString(value);
}
}
}
public class ClassB
{
private int shouldBeInteger;
public int ShouldBeInteger
{
get { return shouldBeInteger; }
set { shouldBeInteger = value; }
}
}
OR
public class ClassB
{
public int ShouldBeInteger{ get; set; }
}
In both of this case ShouldBeInteger will be accesible outside the class.
In first case there were a private field, which cannot be accesible outside the class,
values to private filed can be set through the public field.
In second case the compiler automatically create a private backing field and do the same
process as above. This is auto implemented property.
Hope this may help you.

Categories

Resources