Access to member of abstract class - c#

I have the following class hierarchy:
public abstract class BaseClass : IBaseInterface
{
public int PropertyA{
get
{
return this.propertyA;
}
set
{
this.propertyA = value;
// ... some additional processing ...
}
}
}
DerivedClassB : BaseClass
{
// some other fields
}
public class ContainingClassC
{
public IBaseInterface BaseInterfaceObjectD
{
get;
set;
}
}
Now, in order to access PropertyA of a DerivedClassB-Object (inherited from BaseClass), I have to cast the object to BaseClassA's ancestor, like so:
// This ContainingClassC is returned from a static, enum-like class:
// containingObject.PropertyA is DerivedClassB by default.
ContainingClassC containingObject = new ContainingClassC();
((IBaseInterface)containingObject.BaseInterfaceObjectD).PropertyA = 42;
Is there a way I can restructure these classes to do away with the cast? This code is part of a library, and my colleague wants me to get rid of the cast.
The goal is to simply write containingObject.BaseInterfaceObjectD.PropertyA = 42.

First of all in the line ((IBaseInterface)containingObject.BaseInterfaceObjectD).PropertyA = 42; you are casting the member to the same type that it is declared in, so the casting doesn't actually do anything.
To be able to access the PropertyA in the derived class - since you are casting it to an interface - the property must be declared in the interface and then implemented in the BaseClass.
public interface IBaseInterface{
int PropertyA{get;set;}
}
public abstract class BaseClass : IBaseInterface{
public int PropertyA{
get{ return this.propertyA;}
set {this.propertyA = value;}
}
}
As long as the interface is implemented properly, ProprtyA should be available in the base class, the derived class or with either of them cast'ed to the interface type.
If it's just a problem of the property not showing up in IntelliSense, then it might be a problem with your settings. Check out Options->Text Editor->C# and make sure you have IntelliSense turned on and not set to hiding anythig.

Related

Moq abstract class Property is NULL when cast as interface

I've got some weird behaviour in Moq 4.2. When I make a mock of an abstract class which implements an interface which defines properties, I can access the properties just fine, as long as the instance is the original type. If I cast that instance to the underlying interface, the properties return default values.
See below for an example. Anyone have a solution to this?
In the example below, doing foo.As<IFoo>() does not help.
public interface IFoo { string Thingy { get; } }
public abstract class Foo : IFoo
{
public Foo() { Thingy = "Howdy"; }
public string Thingy { get; }
}
public class Test
{
public void DoIt()
{
var foo = new Mock<Foo>();
Console.WriteLine(foo.Object.Thingy); // prints "Howdy"
Console.WriteLine((foo.Object as IFoo).Thingy); // prints nothing
}
}
Mock - generates a proxy of some object with its own implementation.
proxyImpl1 : IFoo { string Thingy => default }
call Thingy return proxied property
proxyImpl : Foo {nothing, since the parent object does not contain virtual methods} call Thingy return parent non-overrided property.
POCO works the same way in EF

How to make the interface enforce the implementation not having a setter?

following the example:
interface ISomeInterface
{
string SomeProperty { get; }
}
I have the implementation that compiles:
public class SomeClass : ISomeInterface
{
public string SomeProperty
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
which is a problem. How do I make the interface a contract that, won't allow set in it's implementation?
notice: I'm not looking for a solution how to avoid set IN the implementation but in the interface that will validate it from any new implementation, thanks.
Interfaces only specify what MUST be implemented, but do not restrict what other methods, or properties may also be implemented.
So the get is the only thing that you have specified.
Since you are silent on the set, any implementer of the interface is at liberty to add or not to add the set.
In short, with an interface specification you cannot do what you want to do.
If you want to make sure the set is never called then you could always cast the instance to the Interface
If you really need to make sure there is no set you could use an abstract class instead of an interface
abstract class SomeInterface
{
virtual string SomeProperty { get; }
}
Based on Mike answer, you could write something like that :
public interface ISomeInterface
{
string SomeProperty { get; }
}
public abstract class SomeInterfaceBase : ISomeInterface
{
public abstract string SomeProperty { get; }
}
So you can define your class like that:
public class SomeClass : SomeInterfaceBase
{
public override string SomeProperty { get; }
}
If you try to implement a setter, it will not compile.
Having a setter isn't an issue. The reason for this is because of how we treat interfaces.
Whether the concrete class has a setter or not does not matter, because we are supposed to treat the object as an ISomeInterface. In this case it only has a setter.
For instance lets take a factory method:
class Program
{
interface ISomeInterface
{
string SomeProperty { get; }
}
static ISomeInterface CreateSomeClass()
{
return new SomeClass();
}
class SomeClass : ISomeInterface
{
public string SomeProperty
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
static void Main(string[] args)
{
ISomeInterface someInterface = CreateSomeClass();
someInterface.SomeProperty = "test"; //Wont compile
}
}
The class's implementation of a setter is meaningless, because we are only interested in treating the object as ISomeInterface. Interfaces are additive. In other words, they define a contract of what needs to be defined, rather than what should not.
If I was to treat it in any other way, it would be something like this:
((SomeClass) someInterface).SomeProperty = "test"; //Code smell
which I would consider a code smell, because it's assuming that someInterface is SomeClass (treating interfaces as concrete classes)

Correct use of C# 'new' modifier to make protected property public

Let's say I have an abstract base class:
public abstract class BaseClass
{
private MyObject myObject;
protected MyObject PropA
{
get
{
if(myObject == null) this.myObject = new MyObject();
return this.myObject;
}
}
}
...and that in one of my derived classes, I want to make the protected base class property PropA public. Would it be correct to use the new modifier in this context?
public class DerivedClass : BaseClass
{
public new MyObject PropA
{
get
{
return base.PropA;
}
}
}
Would it be correct use of the new modifier in this context?
Technically - yes, there will no errors or warnings.
As for me, using of new keyword itself as a modifier indicates a design drawback.
I'll give one example.
public class MyList<T> : List<T>
{
public int AddCallsCount;
public new void Add(T t)
{
AddCallsCount++;
base.Add(t);
}
}
[TestClass]
public class Test
{
[TestMethod]
public void TestThatsNotGood()
{
List<object> list = new MyList<object>();
list.Add(1);
list.Add(2);
MyList<object> myList = list as MyList<object>;
Assert.AreEqual(0, myList.AddCallsCount);
}
}
It looks like polymorphism works, but actually does not.
UPDATE:
Ok, there is very simplified explanation. I omit explanation of what polymorphism is.
Polymorphims is realized with implementation of abstract\virtual and overriding methods. As soon as neither virtual nor override modifiers are specified MyList<T>.Add is just another 'common' public method. And with MyList<T> inherited List<T>, MyList<T>.Add 'hides' List<T>.Add because name and parameters of both methods are same.
At lower level: as soon as List<T> type definition of method Add isn't marked with virtual keyword, compiler won't search for overriding methods of actual instance type (MyList<T> in this certain case) for variable of given type (List<T> in this certain case).
Definetely it may lead to logic errors and incorrect usage of class API.
Hence, compiler 'thinks' that probably there is a logical mistake or design drawback and warns programmer. The new keyword is just a way to talk to the compiler
yes, I know that it's not good, but I need it because of my bad design
.
The new keyword works and is correct, if you want to add a member in a derived class that has the same name as a member in the base class; however, it seems that this design defies the purpose of abstract classes. Make PropA public and virtual in the base class or public and abstract:
public abstract class BaseClass
{
// Property not implemented here.
public abstract MyObject PropA { get; }
private MyObject _propB;
// Property implemented, but implementation can be overridden in derived class.
public virtual MyObject PropB
{
get { return _propB ?? (_propB = new MyObject()); }
}
public int PropC { get { return 5; } }
}
public class DerivedClass : BaseClass
{
// You must provide an implementation here.
private MyObject _propA;
public override MyObject PropA
{
get { return _propA ?? (_propA = new MyObject()); }
}
// You are free to override this property and to provide an new implementation
// or to do nothing here and to keep the original implementation.
public override MyObject PropB
{
get { return <new implementation...>; }
}
// PropC is inherited as is and is publicly visible through DerivedClass as well.
}
That's correct. Anytime you have a class with a member that has the same name as a member in an inherited class you need to use the new keyword (even if the two properties/methods have different return types).
I would recommend you perhaps
public new string test {
get { return (this as T).test; }
set { (this as T).test = value; }
}
because base give you only parent but if you want to go higher you have to cast.

Adding setters to properties in overrides

Why is it allowed to change the visibility and existence of getters or setters in a property when implementing an interface?
interface IFoo
{
string Bar { get; }
}
class RealFoo : IFoo
{
public RealFoo(string bar)
{
this.Bar = bar;
}
public string Bar { get; private set; }
}
class StubFoo : IFoo
{
public string Bar { get; set; }
}
...and not legal to do the same when implementing an abstract class?
abstract class AbstractFoo : IFoo
{
public abstract string Bar { get; }
}
class RealFoo : AbstractFoo
{
public RealFoo(string bar)
{
this.Bar = bar;
}
// Cannot override because 'Bar' does not have an overridable set accessor
public override string Bar { get; private set; }
}
The interface declares what public properties the class must have (It's just a contract). Which means you need to have those properties, but can add to them.
The abstract class declares the actual structure of those properties. So if you don't have the setter in the abstract base, you can't add to it in the implementation.
When you write the override modifier it looks in the base class for something to override.
It perhaps becomes clearer if you think of the getters and setters as the methods that they eventually become.
In the case of the interface you are defining this:
interface IFoo
{
string GetBar();
}
Which can be read as "all classes that implement this interface must include this method."
Both of your classes do:
class RealFoo : IFoo
{
public string GetBar();
private void SetBar(string value);
}
they also implement SetBar(), but that is immaterial; they have fulfilled the contract defined by the interface and are valid.
The abstract class, on the other hand is this:
abstract class AbstractFoo : IFoo
{
public abstract string GetBar();
}
Which means that all child classes must provide a method body for GetBar()
The class you made is this:
class RealFoo : AbstractFoo
{
public override string GetBar();
public override void SetBar(string value);
}
By putting the override modifier in front of the SetBar method the compiler is expecting to find an abstract or virtual version in the base class. You don't have that so the compilation fails.
An abstract class is a class that cannot be instantiated, but must be inherited from. An abstract class may be fully implemented, but is more usually partially implemented or not implemented at all, thereby encapsulating common functionality for inherited classes.
An interface, by contrast, is a totally abstract set of members that can be thought of as defining a contract for conduct. The implementation of an interface is left completely to the developer.
Taken from the MSDN
http://msdn.microsoft.com/en-us/library/scsyfw1d(v=VS.71).aspx
According to the C# specification
An accessor that is used to implement
an interface may not have an
accessor-modifier. If only one
accessor is used to implement an
interface, the other accessor may be
declared with an accessor-modifier:
public interface I
{
string Prop { get; }
}
public class C: I
{
public Prop {
get { return "April"; } // Must not have a modifier here
internal set {...} // Ok, because I.Prop has no set accessor
}
}
That means it is OK to have an access modified on a class implementing the interface. However, the abstract class declares an implementation and you cannot change that with a derived class.

C#: Semi-Abstract Automatic Properties?

In a base class, I want to define an abstract get, but at that point, I don't care about the set. How can I define a setter in my child class?
I tried a few things, but I can't get it to work. For example I tried :
public class BaseClass
{
public abstract bool MyBool { get; }
}
public class ChildClass : BaseClass
{
public override bool MyBool { get; protected set;}
}
And :
public class BaseClass
{
public bool MyBool { abstract get; }
}
public class ChildClass : BaseClass
{
public bool MyBool { override get; protected set;}
}
I know I can workaround this by not using automatic properties in the child class and directly setting the underlying field instead of creating a setter, but I'm looking for something better.
Edit: I don't want to add an abstract setter in the BaseClass.
It may make more sense to use an interface rather than a base class. Then you simply have the classes that need to provide that property implement that interface.
For instance, you can create this interface:
public interface IBoolable {
bool MyBool { get; }
}
Then it is still valid to implement the interface like so:
public class BoolableItem : IBoolable {
public bool MyBool { get; protected set; }
}
Done this way, your code can safely assume anything that implements IBoolable has a property called MyBool that is at minimum read-only.
One solution is to make MyProperty not abstract but delegate its implementation to an abstract protected property that children must override:
public abstract class BaseClass
{
public bool MyBool { get { return MyBoolInternal; } }
protected abstract bool MyBoolInternal { get; set; }
}
public class ChildClass : BaseClass
{
protected override bool MyBoolInternal { get; set; }
}
You have to make up your mind what behavior you want: if it is defined as abstract then a deriving class MUST implement it.
So what you should do is this:
public abstract class BaseClass
{
public abstract string MyProperty { get; set; }
}
public class DerivedClass : BaseClass
{
public override string MyProperty
{
get { return "myValue"; }
set { /* do nothing, not applicable for this class */ }
}
}
Don't throw the NotImplementedException - that is not what you want, you simply want the setter to do nothing for some child classes.
To leave it ambiguous whether you want a setter in inherited classes would violate OOP principles--that is, if a class (abstract or not) has a public/protected setter (abstract or not), then all inheriting classes must also; if a class does not, then inheriting classes must not.
Another way to think about this is to consider properties such that read-only or read-write is part of the contract of the class. Since instances of inheriting classes must adhere to an "Is-a relationship" (the LSP), inheriting classes cannot "add a setter" where the main class didn't have one, because the fact that the main class had a property without as setter is part of the main class definition. In effect, since the main class cannot change the property in question via a setter, therefore all inheriting classes MUST guarantee the same behavior.
Consider using a protected backing field; then you can split this property into a read-only property and a separate setter method. Then, the main class can have the property only and the subclass can have a setter method that the main class doesn't know about. However, I'm not sure this would be a good design either.

Categories

Resources