I have a abstract class 'Building':
public abstract class Building {
abstract public int ID {get;}
abstract public string name {get;}
}
the class (for example) Headquarter : Building has the Variables for these getter and setter methods. The Problem is I have to write in every Subclass
private int _ID = 1;
public int ID {
get {return _ID;}
}
Is there a way to create for example one getter setter method like ahead, in the abstract class and save the code, so that I only have to set the variables?
Thanks for helping.
Instead of making the properties abstract, you could make the setter protected, and/or allow them to be set in the constructor:
public abstract class Building
{
// Optional constructor
protected Building(int id, string name)
{
this.ID = id;
this.Name = name;
}
public int ID { get; protected set; }
public string Name { get; protected set; }
}
This moves the implementation into the base class, but still only allows the subclasses to set those values.
You can try adding a protected setter in base class and set the value in ctor of derived classes:
public class Building
{
public int Id{get;protected set;}
and in derived class:
public class Headquarter: Building
{
public Headquarter()
{
Id = 1;
}
}
Related
How can we restrict the class variable to not to inherit or change the value in derived class?
ex-
Class A
{
public string name="ABC";
}
Class B:A
{
//I don't want here name property of base class should be accessible
or can be changed
}
You could make use of property with private set as follows:
class A
{
public string Name
{
get;
private set;
}
}
class B:A
{
public B()
{
this.Name = "Derived"; // This will not work. If you want to prevent the derived class from accessing the field, just mark the field as private instead of public.
}
}
I'm trying to have an interface which declares that a property must have a get:
public interface IValue {
public int Value { get; }
}
And then have an abstract class also define it, but keep it abstract:
public abstract class BaseClass : IValue {
public abstract int Value { get; }
}
And then I want to allow a subclass to define the getter and add a setter:
public class SubClass : BaseClass {
public int Value { get; set; }
}
I get an error like:
'SubClass.Value' hides inherited member `BaseClass.Value'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword
If I try:
public class SubClass : BaseClass {
public override int Value { get; set; }
}
I get:
`SubClass.Value.set': cannot override because `BaseClass.Value' does not have an overridable set accessor
Is there any way to allow a subclass to optionally add a setter when inheriting from an abstract class that only defines a getter?
Update: Just to clarify, I know of the workarounds I can do. My goal was to see what's the cleanest way I can do this. The reason I don't just throw a public setter on BaseClass is because some subclasses of BaseClass may not have a public setter. The end goal is basically just provide a common Value getter for the times they're used commonly.
You can't override getter, and add new setter.
This is what your code is, when properties are compiled into get_Value and set_Value methods:
public interface IValue
{
int get_Value();
}
public abstract class BaseClass : IValue
{
public abstract int get_Value();
}
public class SubClass : BaseClass
{
public override int get_Value() { /* ... */ }
// there's no set_Value method to override in base class
public override void set_Value(int value) { /* ... */ }
}
There are at least three ways:
define new int Value property in SubClass (note, then there's a difference);
override Value property and add SetValue method in SubClass;
define setter in BaseClass and override property.
'SubClass.Value' hides inherited member 'BaseClass.Value'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword
Is a warning not an error. It just says that you have public int Value in both abstract and concrete classes. Your abstract class has implementation of this property so when you declare it again in concrete class you just replace it with new property. So compiler advice you to use 'new' word for that purpose.
To use public override int Value { get; set; } you have to mark it 'virtual' in base class. Only virtual members can be overriden.
Class A { public virtual int Value { get; set; } }
Class B : A { public override int Value { get; set; } }
P.S. Interface members are public and abstract by default. So if you declare getter and setter in interface - you have to implement it in a concrete class.
Try to use this code:
public interface IValue
{
int Value { get; set; }
}
public abstract class BaseClass
{
int value;
int Value { get { return value; } }
}
public class SubClass : BaseClass, IValue
{
public int Value { get { return Value; } set { this.Value = value; } }
}
It appears there simply isn't a way to add the set with an abstract class in the middle without declaring a setter up-front. I've tried a ton of different combinations, and no luck.
Finally, I ended up doing this, which isn't ideal, but at least lets me not have a setter everywhere.
public interface IValue {
public int Value { get; }
}
public abstract class BaseClass : IValue {
public abstract int Value { get; }
}
public class SubClass : BaseClass {
protected int val;
public int Value { get { return val; } }
public int SetValue (int value) { val = value; }
}
public class SubClassWithoutSetter : BaseClass {
public int Value { get { return 50; } }
}
Basically, just do a "classic" setter, since there doesn't seem to be a syntax that supports letting me add a setter property after the fact.
It'd be nice if C# would implement something like:
public int Value { override get; set; } // note: this does not work
I've tried to learn the short version of get & set in C#, but I don't know how to use them.
This is what I tried:
namespace SomeNamespace {
class SomeClass {
private int field1 { get; set;}
private int field2 { public get; public set; }
}
class OtherClass {
SomeClass sc = new SomeClass();
int field1 = sc.field1; //it doesn't work
int field2 = sc.field2; //it also doesn't work
sc.field1 = 1; //same here
sc.field2 = 2; //and here
}
}
In my SomeClass object I don't have access to any field nor "special" method to do this.
I obviously don't get it, so please help me to understand.
You need to use the accessors the other way around on your properties if you want to only allow read access on your property from outside classes:
public int field2 { get; private set; }
// setting only allowed from SomeClass, not from OtherClass or inheritors
To allow inheritors, you need to set private to protected.
If you want to allow both read and write from outside classes:
public int field2 { get; set; }
// setting allowed from any class
You need to declare them as public. Like following.
namespace SomeNamespace {
class SomeClass {
public int field1 { get; set;}
public int field2 { get; set;}
}
class OtherClass {
SomeClass sc = new SomeClass();
// frist set the values
sc.field1 = 1;
sc.field2 = 2;
// then read them
int field1 = sc.field1;
int field2 = sc.field2;
}
}
In C# 3.0 and later, auto-implemented properties make
property-declaration more concise when no additional logic is required
in the property accessors. They also enable client code to create
objects. When you declare a property as shown in the following
example, the compiler creates a private, anonymous backing field that
can only be accessed through the property's get and set accessors.
There are advantage of having getter/setter ( in comparison to just public variables).
Set accessibility via private set; etc..
You can add validation while setting the value or format while getting the value.
You can use them as part of an interface definition or an abstract class.
SOUREC - http://msdn.microsoft.com/en-us/library/bb384054.aspx
public class SomeClass
{
//Will be accessible by instance of this class
public int Field1 { get; set; }
//Accessible within class methods only
private int Field2 { get; set; }
public void SomeMethod()
{
//You can use private property in any of method within class only
Console.WriteLine(Field2);
}
//Accessible from derived class
protected int Field3 { get; set; }
}
public class SomeDerived : SomeClass
{
public void SomeDerivedFunction()
{
//Accessing baseclass Property
Console.WriteLine(Field3);
}
}
public class SomeThirdPartyClass
{
private SomeClass sc;
public SomeThirdPartyClass()
{
sc = new SomeClass();
//Field one as public accessible in other classes by instance
Console.WriteLine(sc.Field1);
}
}
At MSDN an example to write a custom attribute shows the following strange behavior
[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
public virtual string Name
{
get {return name;}
}
// Define Level property.
// This is a read-only attribute.
public virtual string Level
{
get {return level;}
}
// Define Reviewed property.
// This is a read/write attribute.
public virtual bool Reviewed
{
get {return reviewed;}
set {reviewed = value;}
}
}
Why all properties are virtual?
There's section on the particular MSDN article that the OP mentioned that is about attribute "inheritance", i.e. if you have a class with a method that is virtual and is annotated with an attribute, and you add a subclass and override that method, will the subclass method have the attribute applied to it? That's what [AttributeUsage(AttributeTargets.Method, Inherited = false)] is about in the Inherited Property section.
Specifically:
public class MyClass
{
[MyAttribute]
[YourAttribute]
public virtual void MyMethod()
{
//...
}
}
Where YourAttribute is configured with AttributeUsage(AttributeTargets.Method, Inherited = false)] and MyAttribute has the default configuration.
public class MyClass
{
[MyAttribute]
[YourAttribute]
public virtual void MyMethod()
{
//...
}
}
public class YourClass : MyClass
{
// MyMethod will have MyAttribute but not YourAttribute.
public override void MyMethod()
{
//...
}
}
The default value for Inherited is true.
So in short, those properties are virtual in the article to describe this feature.
I doubt that there is any specific reason to do so, because Attributes work well with or without virtual specifiers on their properties or other members.
public string Name
{
get {return name;}
}
// Define Level property.
// This is a read-only attribute.
public string Level
{
get {return level;}
}
// Define Reviewed property.
// This is a read/write attribute.
public bool Reviewed
{
get {return reviewed;}
set {reviewed = value;}
}
Will work just as fine.
But you won't be able to override these methods in derived attribute classes.
For example, this will work:
public class WithVirtualPropAttribute : Attribute
{
public virtual String Prop {get; set;}
}
public class DerivedFromWithVirtualPropAttribute : WithVirtualPropAttribute
{
// Compiles ok
public virtual String Prop {get{return "0"} set{}}
}
This won't:
public class WithoutVirtualPropAttribute : Attribute
{
public virtual String Prop {get; set;}
}
public class DerivedFromWithoutVirtualPropAttribute : WithoutVirtualPropAttribute
{
// Compilation error !!!!!!!!!!!!!!!!!!!!!!!!!!
public virtual String Prop {get{return "0";} set{}}
}
It can be a design decision for some specific scenarios, but as overall there is no need do so.
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
}
}
}