Are class initializers possible in C#? - c#

In C# you have object initializers to initialize fields of objects at creation time without using a constructor.
Now I'm wondering if there is an equivalent to classes which means that you can 'initialize' properties of classes when defining subclasses without actually using an override syntax but simply declaring what the value of a known property is.
Example:
public abstract class Car {
public abstract string Name { get; }
}
// usual approach
public class Mustang : Car {
public overwrite string Name { get { return "Ford Mustang"; } }
}
// my idea of avoiding boilerplate code
public class Mustang : Car { Name = "Ford Mustang" }
Is there a way to accomplish this? If there is none, could T4 templates be of any help?

To make rekire's example clearer, you'd write something like:
public abstract class Car
{
public string Name { get; private set; }
protected Car(string name)
{
this.Name = name;
}
}
public class Mustang : Car
{
public Mustang() : base("Mustang")
{
}
}
EDIT: Another option is to use attributes, where you'd write:
[CarName("Mustang")]
public class Mustang : Car
... having written appropriate reflection code in Car. I would strongly recommend that you don't though. Of course, attributes may be useful in your real context.

You could do this via a construtor, where you need to call the base class constructor.
class car {
Public string Name {public get; protected set}
}
That should basically work too.

Related

How to copy an instance of base class to derived class base using c#.net

I am encounter with a situation where I need to copy the members of base class to derived class.
I have an Instance of Base class which are returning by some other service, the same class we have used as a base class for further classes.
When we crates an object of derived class I want to assign the already created instance of base class to derived class, I know we can not assign the base class object to derived class but I am still searching any other solution.
Any one has any Idea?
Example :
public class VBase
{
public string Type {get;set;}
public string Colour {get;set;}
}
public class Car : VBase
{
public string Name {get;set;}
public int Year {get;set;}
}
// This class instance I am getting from some other source
VBase mBase= new VBase();
mBase.Type = "SUV";
mBase.Colour = "Black";
//-------------------------------------------------------
Car myCar= new Car();
myCar.Name = "AUDI";
mBase.Year = "2016";
//here I want to copy the instance of base class to derived class some thing like this or any other possible way.
myCar.base=mBase;
It is not possible in naïve way.
I'd like to recommend to define constructor or static method. I personally do not recommend to use additional libraries like AutoMapper for this job as they could require some conversion and make code cumbersome.
public class Car : VBase
{
// Method 1: define constructor.
public class Car(VBase v) {
this.Type = v.Type;
this.Colour = v.Colour;
}
// Method 2: static method.
public static Car FromVBase(VBase v){
return new Car()
{
this.Type = v.Type;
this.Colour = v.Colour;
};
}
public string Name {get;set;}
public int Year {get;set;}
}
Without using reflection, if your classes are lightweight, and wont change overtime, then you could create a public property of Base in Car:
public class Car : VBase
{
public string Name
{
get;
set;
}
public int Year
{
get;
set;
}
public VBase Base
{
set
{
base.Type = value.Type;
base.Colour = value.Colour;
}
}
}
You can then easily pass through your base class like so:
myCar.Base = mBase;
I have created a dotnetfiddle here:
dotnetfiddle for this question

C# calling parent property while the child property is being called

I wanna see if there is anyway that when the child property method is being called, it will call the parent property as well.
Note that the child is generated by a code generator from edmx. So I can't change anything except adding a partial class for the child class. (It might be too trouble to change the generator.)
The situation I am having :
I have a class "MyClass" that is automatically generated from the database. I can't change anything on it except adding a partial class or change the code generator.
Now, I need to "do something" whenever the property Name is being called. I am thinking if I can put a parent there and make it call the parent to do "something" when the child property is "Name" is being called.
What I want :
public class ClassBase
{
public string Name
{
get
{
CallMethod();
return Name;
}
}
}
public class MyClass : ClassBase
{
public string Name { get; set; }
}
MyClass myClass = new MyClass();
myClass.Name; < -- this will call the parent as well.
Is there anyway to do it?
Thanks in advance
Not really related but since you're not strictly using automatic properties in ClassBase, you should create a private string variable for Name. Something like _name or whatever your internal coding standards dictate.
public class ClassBase
{
private string _name;
public virtual string Name
{
get
{
CallMethod();
return _name;
}
set
{
_name = value;
}
}
}
public class MyClass : ClassBase
{
//Pretty pointless really since you're not doing anything with MyClass.Name.
public new string Name
{
get
{
return base.Name;
}
set
{
base.Name = value;
}
}
MyClass myClass = new MyClass();
myClass.Name; <-- this will call the parent as well.
Based on "can't change base class" comment there is pretty much nothing you can do to make some code to be executed instead/before/after base class because your property/method will not be called when your new class used as base class (see sample in details part).
Potential solution : if you need to extend specially designed parital class's and it provides extension poinst like CallMethod is marked as partial - it is expected for implemnting portion of the class to implement it :
partial public class ClassBase
{
partial void CallMethod();
public string Name {get {CallMethod(); return "";}}
}
// in generated portion of "ClassBase"
partial public class ClassBase
{
partial void CallMethod() { /* do something here */ }
}
Answer to exact "how to call base class property" is to use base, but hiding property/method this way is confusing (see below):
new public string Name { get { return base.Name;} }
Note that you can't use automatic property in derived class case as you explicitly want some additional code to be executed. If you need set in derived class you need own backing field like:
private string derivedName;
new public string Name {
get { return base.Name + derivedName;}
set { derivedName = value;}
}
Details:
As said in comments hiding base class' properties/methods leads to very confusing behavior. For you case (slightly updated base class with baking field as original sample had infinite recursion):
public class ClassBase
{
private string name;
public string Name
{
get
{
CallMethod();
return name;
}
}
}
You can try to hide Name property in derived class:
public class MyClass : ClassBase
{
// notice "new" to show comiler you know what you doing
// otherwise you'll get warning (but behavior will be the same)
new public string Name { get; set; }
}
The issue with hiding is that base class' method is still easily callable and likely be called by mistake if using derived class as base class:
MyClass myDerved = new MyClass();
ClassBase myDervedAsBase = myDerved;
var name = myDerived.Name; // calls MyClass.Name
var name = myDerivedAsBase.Name; // calls ClassBase.Name
This can be solved by making base class' method/property virtual - but it requires change in base class:
public class ClassBase
{
virtual public string Name { get {... } }
}
public class MyClass : ClassBase
{
override public string Name { get { ... } }
}
If you need to call base class' method/property from derived class usebase.MethodName() like:
override public string Name { get
{
// do some new stuff here
var baseName = base.Name;
// maybe even change result
return baseName;
}
}
If you expect most derived classes to need such behavior it could be better to design base class explicitly to enforce such behavior. For example you can have property to call virtual method before/after computing the value to return like:
public class ClassBase
{
virtual protected string AboutToReturnName(string result)
{
return name;
}
public string Name
{
get
{
var result = "MyName";
return AboutToReturnName(result);
}
}
}
More ideas:
Alternative to virtual is partial methods which works when instead of deriving class is combined from many "partial" parts like ASP.Net pages - see Partial Classes and Methods
If you need notifications around change of property - consider implementing INotifyPropertyChange
if you need to know when properties/method are called in general - consider using interfaces and automatically generate wrapper classes that have pre/post callback. I.e. mocking frameworks (like EasyMoq or RhinoMock) and DI containers (like Unity) provide and use such functionality.
You cannot do it without modifying the code generator. The modification would have to generate a call base.Name.
You can override the property in your subclass with the new operator.
public class MyClass : ClassBase
{
public new string Name { get; set; }
}

c# property override Set method

I have a class like the below, I want to override the set value of "School,Country..etc.." property when some one sets a value , i don't want to change the student class but i need to do it in the base class and use it as a generic method
public class Student : BaseClass
{
public String School { get; set; }
public String Country{ get; set; }
}
ie:
When some one sets
Student.School="Harvard",
I need to store it as
Student.School="Harvard my custom value";
Note:
Basically calling OnPropertyChanged in base class rather than the main class.
If you want to do it with aspects, then try Postsharp
Basically you cannot override a non-virtual property. You can hide it by other property with the same name in the derived class, but this won't give you the desired effect if some other code accesses your object by the reference to the base class.
public class Student : BaseClass
{
private string _school
public string School
{
get { return _school; }
set
{
if(value == "Harvard")
value = "Harvard custom";
_school = value;
}
}
public String Country{ get; set; }
}
is that what you mean?
If the School property is in the BaseClass then you can either use the new keyword, or if you control the BaseClass, then you can add the virtual keyword to the School property there, and override it in the Student class.
This is just not doable by solely modifying BaseClass. Think about it this way: If it were possible to "annotate" automatic properties that easily, then we wouldn't need all those <rant>useless tons of</rant> manual property implementations for data model classes that implement INotifyPropertyChanged (same for DependencyProperties).
You need to provide hooks in your subclasses that your base class can use. Implementing PropertyChanged, which you already mentioned, is one possible solution, another one would be a simple method call:
public class Student : BaseClass
{
private string _school;
public String School
{
get { return _school; }
set {
_school = value;
DoMoreChanges(ref _school); // DoMoreChanges is defined in BaseClass
}
}
public String Country{ get; set; }
}
If you have lots of subclasses that need this, you can either use Visual Studio Code Snippets to create the code or T4 templates.
Since your base class does not have those properties you will not be able to modify them from within the base class using standard OOD patterns or principles.
Now if you move the properties to your base class either as normal properties or virtual properties you can modify what you do in the set block of the properties to do extra work.
However if you cannot move these to the base class, and you cannot modify the Student class, as you seem to imply in you question, then you could encapsulate the student class within a new class like StudentProxy or something and then have it expose similar properties that will then call into the real student class how you want.
For example:
public class StudentProxy
{
private Student _student;
public StudentProxy(Student student)
{
this._student = student;
}
public String School
{
get { return _student.School; }
set
{
_student.School = value + " my custom value";
}
}
public String Country
{
get { return _student.Country; }
set
{
_student.Country = value + " my custom value";
}
}
}

Setting value to a field in the derived class

using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new B("MyName").Name);
}
}
abstract class A
{
public A(string name)
{
this.GetType().GetField("Name").SetValue(this, name);
}
}
class B : A
{
public B(string name)
: base(name)
{
}
public string Name
{
set;
get;
}
}
}
Is it possible to do something like that?
I can't stress how very, very, very bad this is. You are creating an inverse coupling that is convoluted, confusing and contrived, severely lacking in clarity, failing best practices and object oriented principals, which is going to create a maintenance and management nightmare for people implementing derivatives of your abstract class. Do the right thing!!
abstract class A
{
protected A(string name)
{
Name = name;
}
public abstract string Name
{
get;
protected set;
}
}
class B: A
{
public B(string name) : base(name)
{
}
private string m_name;
public override string Name
{
get { return "B Name: " + m_name; }
protected set
{
m_name = value;
}
}
}
It is possible, but i wouldn´t recommend to do that. The problem is that your base class knows to much about the class that are derived from it.
When you derive a class from your abstract base class that does not define the property Name you get an Exception on runtime.
If you expect that each class, that is derived from your base class, has a property Name, then it would be easier to define the Property Name in your abstract base class and set the property with you constructor.
It's really bad form to do that. Generally you should just call a method like 'SetPossibleData()', and force all children to implement it in a fashion they decide.
Why do you need to do this?
Use GetProperty() Method,
public A(string name)
{
this.GetType().GetProperty("Name").SetValue(this,name,null);
}
It would be really straight forward if every class initializes the fields and properties it defines. Why does B expect the base class initialize its Name?
abstract class A
{
public A()
{
}
}
class B : A
{
// I know, its trivial, but it does the same ...
public B(string name) : base()
{
Name = name;
}
public string Name { set; get; }
}
The only thing I could think of why you wrote this code is that the base class has some logic to initialize the field. Straight forward would be to let the derived class call the logic, but initialize the field itself:
abstract class A
{
public A()
{
}
protected string GenerateName(string someArg)
{
// complicated logic to generate the name
}
}
class B : A
{
public B(string someArg) : base()
{
Name = base.GenerateName(someArg);
}
public string Name { set; get; }
}

What is the best way to inherit an array that needs to store subclass specific data?

I'm trying to set up an inheritance hierarchy similar to the following:
abstract class Vehicle
{
public string Name;
public List<Axle> Axles;
}
class Motorcycle : Vehicle
{
}
class Car : Vehicle
{
}
abstract class Axle
{
public int Length;
public void Turn(int numTurns) { ... }
}
class MotorcycleAxle : Axle
{
public bool WheelAttached;
}
class CarAxle : Axle
{
public bool LeftWheelAttached;
public bool RightWheelAttached;
}
I would like to only store MotorcycleAxle objects in a Motorcycle object's Axles array, and CarAxle objects in a Car object's Axles array. The problem is there is no way to override the array in the subclass to force one or the other. Ideally something like the following would be valid for the Motorcycle class:
class Motorcycle : Vehicle
{
public override List<MotorcycleAxle> Axles;
}
but the types have to match when overriding. How can I support this architecture? Will I just have to do a lot of run-time type checking and casting wherever the Axles member is accessed? I don't like adding run-time type checks because you start to lose the benefits of strong typing and polymorphism. There have to be at least some run-time checks in this scenario since the WheelAttached and Left/RightWheelAttached properties depend on the type, but I would like to minimize them.
Use more generics
abstract class Vehicle<T> where T : Axle
{
public string Name;
public List<T> Axles;
}
class Motorcycle : Vehicle<MotorcycleAxle>
{
}
class Car : Vehicle<CarAxle>
{
}
abstract class Axle
{
public int Length;
public void Turn(int numTurns) { ... }
}
class MotorcycleAxle : Axle
{
public bool WheelAttached;
}
class CarAxle : Axle
{
public bool LeftWheelAttached;
public bool RightWheelAttached;
}
2 options spring to mind. 1 is using generics:
abstract class Vehicle<TAxle> where TAxle : Axle {
public List<TAxle> Axles;
}
The second uses shadowing - and this assumes you have properties:
abstract class Vehicle {
public IList<Axle> Axles { get; set; }
}
class Motorcyle : Vehicle {
public new IList<MotorcycleAxle> Axles { get; set; }
}
class Car : Vehicle {
public new IList<CarAxle> Axles { get; set; }
}
void Main() {
Vehicle v = new Car();
// v.Axles is IList<Axle>
Car c = (Car) v;
// c.Axles is IList<CarAxle>
// ((Vehicle)c).Axles is IList<Axle>
The problem with shadowing is that you have a generic List. Unfortunately, you can't constrain the list to only contain CarAxle. Also, you can't cast a List<Axle> into List<CarAxle> - even though there's an inheritance chain there. You have to cast each object into a new List (though that becomes much easier with LINQ).
I'd go for generics myself.
I asked a similar question and got a better answer, the problem is related to C#'s support for covariance and contravariance. See that discussion for a little more information.

Categories

Resources