I have a base class that has an abstract property:
public class BottomClass {
public abstract string Name {get;set;}
}
I now have a class that derives from that:
public class MiddleClass:BottomClass {
public override string Name {get;set;}
}
what I now want is that the "MiddleClass" itself defines that property as abstract so that a class deriving from that will be forced to implement the property. The following code is not working that way:
public class MiddleClass:BottomClass {
public abstract override string Name {get;set;} // Not possible that way
}
public class TopClass:MiddleClass {
public override string Name {get;set;} ="tothetop";
}
Is there a way to achieve what I want?
If you define a property as abstract, you have to implement it in some non abstract class. So the only possible way to have the property in both classes is
public abstract class BottomClass
{
public abstract string NameB { get; set; }
}
public abstract class MiddleClass : BottomClass
{
public abstract string NameM { get; set; }
}
public class TopClass : MiddleClass {
public override string NameB { get; set; }
public override string NameM { get; set; }
}
As far as I can understand, your intention is to have 'Name' property in MiddleClass.
Or don't implement it, as Damien commented above.
Throw exceptions if you have some reason not to make the class abstract.
public class MiddleClass:BottomClass
{
public override string Name
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
}
Related
Is there any possibility to create an interface in order to require a virtual collection type in my class?
Regards
namespace Models.Entities
{
public partial class FileType : IMyInterface
{
public long CompanyId { get; set; }
public long FileTypeId { get; set; }
public string AcceptType { get; set; }
//IMyInterface contract
public virtual ICollection<Translation> FileTypeTranslations { get; set; }
public FileType()
{
this.FileTypeTranslations = new HashSet<FileTypeTranslation>();
}
}
public class Translation : EntityTranslation<long, FileType>
{
[Required]
public string TypeName { get; set; }
}
}
No. virtual is an implementation detail not a contract (ie. interface) detail.
The virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class.
I marked the key part of that description from the documentation in bold
You can try to use abstract class instead of interface. So at classes, inherited from FileType, you can override this property again, i.e. behavior like with virtual access modifier at FileType declaration:
public abstract class MyInterface
{
public abstract ICollection<Translation> FileTypeTranslations { get; set; }
}
public class FileType : MyInterface
{
public override ICollection<Translation> FileTypeTranslations { get; set; }
}
public class FileTypeInherited : FileType
{
public override ICollection<Translation> FileTypeTranslations { get; set; }
}
In order to override method, property, event, indexer they must be virtual. But if they are virtual its not mandatory to override them its optional. and if we talk about abstract classes the member of abstract class is virtual implicitly. That's why we need to use override keyword when defining them in some subclass.
I created the following abstract class:
public abstract class AbstractClass
{
public abstract string Name { get; set; }
public abstract object Value { get; set; }
}
Now I want to derive two classes of the abstract class. I want to use an enum instead of the type object. My derived classes look like this:
First class:
public class InheritanceClass1:AbstractClass
{
public override string Name { get; set; }
public override FirstEnum Value { get; set; }
}
Second class:
public class InheritanceClass2 : AbstractClass
{
public override string Name { get; set; }
public override SecondEnum Value { get; set; }
}
I'm getting an error showed in my code, that the type of the property Value isn't object. I tryed to use the new-keyword instead of override like this:
In my abstract class:
public object Value { get; set; }
In my derived class:
public new FirstEnum Value { get; set; }
But if I create a List<AbstractClass> I have the problem that I can't use it for example for Linq because I would retrieve the "wrong" property. It is just hided, but still there, so I have to override the property.
So how do I have to change my abstract class and my derived classes, that I can use different types in my derived classes?
You can use abstract class like this:
public abstract class AbstractClass<T>
{
public abstract string Name { get; set; }
public abstract T Value { get; set; }
}
And derived class will change like this:
public class InheritanceClass1 : AbstractClass<FirstEnum>
{
public override string Name { get; set; }
public override FirstEnum Value { get; set; }
}
If you know that you will need only enums, you can add struct, IConvertible restriction to T:
public abstract class AbstractClass<T> where T : struct, IConvertible
{
public abstract string Name { get; set; }
public abstract T Value { get; set; }
}
Update based on comment:
Not the cleanest solution if you need List<AbstractClass>, but you can have additional class:
public abstract class AbstractClass
{
public abstract string Name { get; set; }
public abstract int GetValue ();
}
Which will then be inherited by AbstractClass<T>:
public abstract class AbstractClass<T> : AbstractClass where T : struct, IConvertible
{
public abstract T Value { get; set; }
}
And InheritancClass:
public class InheritanceClass1 : AbstractClass<FirstEnum>
{
public override string Name { get; set; }
public override FirstEnum Value { get; set; }
public override int GetValue () => (int)Value;
}
And then you can use it in a list:
var list = new List<AbstractClass> { new InheritanceClass1 (), new InheritanceClass2 () };
In this way you can use List<AbstractClass> with GetValue method. If you are using only enums you can always recast it to enum value. Ofcorse, you would not know exactly which enum it is, but you can add additional field for that.
I have the following two classes:
abstract class LogItem {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
class MyLogItem : LogItem
{
//No I want this to have to have the members from the abstract class above, as if it where an interface?
}
So in other words I am wanting a type if interface that can have definitions or variables which all classes that implement it have to have, but they could add more if they required ?
The above example builds, even if i dono add the members from the abstract class.
edit
Forget what I've said before. These are attributes, not methods. For them to be accessible on derived classes, you make them protected or public. The difference is that public members are visible to the world, while protected ones are visible to the class and subclasses.
Any class derived from your LogItem may have other variables.
abstract class LogItem {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
class MyLogItem : LogItem
{
//No I want this to have to have the members from the abstract class above, as if it where an interface?
private void TestMethod(){
String test = payload;
}
}
check out this post for more information
Your MyLogItem class can reference any of the above members directly. They are accessible
You may declare an interface with those
public interface MyInterface {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
and your class
public class MyLogItem : MyInterface
{
String _payload;
public String payload { get{ return _payload; } set {_payload=value;} }
...
}
The abstract keyword can also be applied to methods, as described here.
First I want to say that I am quite new to C# sharp. Is there any way implement a construct like the following? Or is there any other way to archive this?
public interface IClass
{
Dictionary<Enum, ISecondClass> { get; }
}
public abstract class ClassBase : IClass
{
public abstract Dictionary<Enum, ISecondClass> { get; protected set;}
}
public class ConcreteClass : ClassBase
{
public override Dictionary<ConreteEnum, ISecondClass> { get; protected set;}
}
EDIT:
I forgot to say that the concrete instance of the Dictionary needs to implement a custom Enum-comparer that need a concrete enum to get initialized
For all who are interested in the custom enum-comparer, which is needed in this case, take a look at this link: Custom-Enum-Comparer
You can add a generic type argument to the class/interface level
public interface IClass<TEnum>
{
Dictionary<TEnum, ISecondClass> { get; }
}
public abstract class ClassBase<TEnum> : IClass<TEnum>
{
public abstract Dictionary<TEnum, ISecondClass> { get; protected set;}
}
public class ConcreteClass : ClassBase<ConcreteEnum>
{
public override Dictionary<ConcreteEnum, ISecondClass> { get; protected set;}
}
I am fairly new to inheritance and wanted to ask something. I have a base class that has lots of functionality that is shared by a number of derived classes.
The only difference for each derived class is a single method called Name. The functionality is the same for each derived class, but there is a need for the Name distinction.
I have a property in the base class called Name. How do I arrange it so that the derived classes can each override the base class property?
Thanks.
Declare your method as virtual
public class A
{
public virtual string Name(string name)
{
return name;
}
}
public class B : A
{
public override string Name(string name)
{
return base.Name(name); // calling A's method
}
}
public class C : A
{
public override string Name(string name)
{
return "1+1";
}
}
Use a virtual property:
class Base
{
public virtual string Foo
{
get;
set;
}
}
class Derived : Base
{
public override string Foo
{
get {
// Return something else...
}
set {
// Do something else...
}
}
}
You can declare it with a virtual or abstract keyword in the base class, then the derived class can over-ride it
you need to declare your property (in the base clase) as virtual
To enable each derived class to override the property you just need to mark the property as virtual
class Base {
public virtual Property1 {
get { ... }
set { ... }
}
}
Well I'm not sure from your description that inheritance is actually the right solution to the problem but here's how you make it possible for a property to be overridden:
class Base
{
public virtual string Name { get; set; }
}
But do you need it to be writable? A readonly property may make more sense in which case this might work:
class Base
{
public virtual string Name
{
get { return "BaseName"; }
}
}
class Derived : Base
{
public override string Name
{
get { return "Derived"; }
}
}
In the base class:
public virtual string Name { get; set; }
In the derived classes:
public override string Name { get; set; }
However, if the only difference between the classes is that they have different names, I'd argue that instead of inheritance you should just use the base class with the Name set in the constructor:
e.g.
public class MyObject
{
public string Name { get; private set; }
public enum ObjectType { TypeA, TypeB, ... }
public MyObject(ObjectType obType)
{
switch (obType)
{
case ObjectType.TypeA:
Name = "Type A";
// and so on
}
}
}