What is the "C# way" to pass arguments of inherited class constructors to base class constructors? Would this require that I override the base_model string in the base class?
// Base class
class vehicle
{
private string base_model = String.Empty;
vehicle(string model)
{
this.base_model = model;
}
}
// Inherited classes
class tesla : vehicle
{
private readonly string model = "Model S"; // This is unchanging
tesla(string model) : base ( **pass model to base_model** )
{
// Initialize
}
}
class ferrari : vehicle
{
private readonly string model = "458 Spider"; // This is unchanging
ferrari(string model) : base ( **pass model to base_model** )
{
// Initialize
}
}
Edit
#JohnLBevan brought another question to my attention:
This brings to mind another question: is it possible to have no constructor arguments for the tesla class (or the ferrari class for that matter) and automatically pass the model variable (i.e. "Model S") to the base_model?
A far more OO standards compliant way to do this is to use an abstract property. This means the base class has defined the property but the extending classes must implement it. This also means you cannot directly create an instance of vehicle, instead you must create one of the derived types.
abstract class vehicle
{
vehicle() { }
public abstract string Model { get; }
}
// Inherited classes
class tesla : vehicle
{
private readonly string model = "Model S"; // This is unchanging
public override string Model { get { return model; }}
}
class ferrari : vehicle
{
public override string Model { get { return "458 Spider"; }}
}
The only time you really want to be passing values from derived constructors to base constructors is when those values are actively used in the base class. This is a normally when you've overridden a base constructor, or you are using a dependency injection or dependency resolution pattern. The base class should not act as an aggregation of information from the derived class.
Exactly what you've done, only putting the variable name in where you had the asterisks:
// Inherited classes
class tesla : vehicle
{
private readonly string model = "Model S"; // This is unchanging
tesla(string model) : base ( model )
{
// Initialize
}
}
You also need to ensure that the base class's constructor is visible to its subclasses (i.e. is not private)
// Base class
class vehicle
{
private string base_model = String.Empty;
protected vehicle(string model)
{
this.base_model = model;
}
}
Related
class Vehicle // base class (parent)
{
public string brand = "Ford"; // Vehicle field
public void honk() // Vehicle method
{
Console.WriteLine("Tuut, tuut!");
}
}
class Car : Vehicle // derived class (child)
{
public string modelName = "Mustang"; // Car field
brand = "WHY İS NOT ??? "; // Error.
public void honk(); // Error.
}
Can't I do that? Does the class we inherit have its functions, methods, and variables? Did I learn something wrong?
Note; It works within the main function.
I've been dealing with this for a long time. : / (3+ hours)
You can't just write to a field (defined in a base class) from the derived class like:
brand = "WHY İS NOT ??? "; // Error.
...because you aren't definining a new field, rather you are attempting to change brand defined in the the base class Vehicle. Unfortunately the way it is written, the compiler thinks it's an orphaned assignment. It should exist in a in a method or constructor.
Try placing it in a constructor:
class Car : Vehicle // derived class (child)
{
public string modelName = "Mustang"; // Car field
public Car()
{
brand = "Acme";
}
public void honk() {}
}
Honk
public void honk(); // Error.
The problem here is that your method has no body. Whilst you can do that in an interface you can't in a non-abstract method belonging to a class.
Give it a minimal one like so:
public override void honk() { }
...or:
public override void honk()
{
// same thing but formatted differently
}
Notice there is a new override. If you want a new implementation of honk in a derived class it's best to make the method virtual.
i.e.
class Vehicle // base class (parent)
{
// ...
public virtual void honk()
{
Console.WriteLine("Tuut, tuut!");
}
// ...
}
Alternatively you can use new instead of override but there are gotchas.
So I have a Vehicle class without a constructor. I want to make a new class called VehicleExtended which inherits from Vehicle.
The error is:
'Vehicle' does not contain a constructor that takes 0 arguments (CS1729)
Is it possible to inherit without having a constructor?
NOTE: I can't edit the base class because it's only it's metadata that I can see.
public class VehicleData : Vehicle
{
[BsonId]public int _id { get; private set;}
public bool IsCompany { get; private set;}
public int OwnerID { get; private set; }
public string modelName { get; private set;}
}
As we can see from the error message, base class Vehicle doesn't have constructors without arguments:
public class Vehicle {
...
// every Vehicle constructors want some parameters, e.g. id and ownerId
public Vehicle(int id, int ownerId) {...}
...
}
That's the compiler doesn't know how to create instance of VehicleData:
// Since VehicleData is inherited from Vehicle,
// Vehicle cosntructor should be executed.
// What arguments should be passed to it?
var test = new VehicleData();
You have to implement VehicleData constructor manually in which you should specify the arguments:
public class VehicleData : Vehicle
{
// When creating an instace, use -1 and -1 when calling base constructor
public VehicleData() : base(-1, -1) {}
...
}
Now the code above is legal:
// We don't want parameters when creating VehicleData instance
// When creating base class (Vehicle) -1 and -1 are used
var test = new VehicleData();
Edit: If base class (Vehicle) doesn't have any public or protected constructors (but private ones) you can't create base Vehicle instance from VehicleData and thus can't inherit from Vehicle. private constructors only is an old C++ trick; in case of C# in order to prevent from inheriting we should use sealed
It's possible, that the base class has a private constructor which can't be accessed. In this case you can't inherit the class.
Based on the error message I assume that the class VehicleData has an private zero argument constructor.
In this case you can not inherit from VehicleData.
e.g.
public class A
{
private A() {}
}
public class B : A
{
}
this will not compile.
But if there is an public or protected with a non-zeor argument list you can inherit from the class:
public class A
{
private A() {}
public A(int i) {}
}
public class B : A
{
public B() : base(0) {}
}
Also, if it turns out that Vehicle has only private constructores and you only want to add specificy behaivor and not any kinds of properties that are not computable from the ones that are already defined in Vehicle, instead of inheriting you could use extesnions-methodes.
public static VehicleExtesnion
{
public SomeType DoStuff(this Vehicle vehicle)
{
// do stuff with vehicle
}
}
I have two typed interfaces
public interface IComponentAreaModel<T>
public interface IComponentAreaViewModel<T>
The interface for the view model has a property 'Model' defined which is of the type of the interface for the model:
IComponentAreaModel<T> Model { get; }
In my actual implementation I have a model that implements the 'IComponentAreaModel' interface which works fine:
public class ArticleModel : IComponentAreaModel<Article>
Then I implement the view model as follows:
public class ArticleViewModel : IComponentAreaViewModel<Article>
{
public ArticleModel Model { get; }
}
And here the compiler tells me that the member 'Model' does not have the matching return type. To fix this, I would have to implement the view model as follows:
public class ArticleViewModel : IComponentAreaViewModel<Article>
{
public IComponentAreaModel<Article> Model { get; }
}
But this sucks as my ArticleModel class has some additional methods and stuff that are not part of the IComponentAreaModel. So when I wanted to use these methods through the property within my ArticleViewModel, then I would have to cast the interface object to the actual object.
Is there a way to tell the compiler that my ArticleModel implements the IComponentAreaModel and therefore is sufficient as Model for the IComponentAreaViewModel?
It depends on how do you use these interfaces. At least, there are three options.
Option 1. Use field inside implementation:
public class ArticleViewModel : IComponentAreaViewModel<Article>
{
// use this field, when you need ArticleModel
private readonly ArticleModel model;
// TODO: initialize model somehow
public IComponentAreaModel<Article> Model => model;
}
Option 2. Use explicit interface implementation:
public class ArticleViewModel : IComponentAreaViewModel<Article>
{
// use this property, when you need ArticleModel
public ArticleModel Model { get; }
IComponentAreaModel<Article> IComponentAreaViewModel<Article>.Model => Model;
}
Option 3. Add the 2nd type parameter to view model interface. Will add complexity, especially if you want to use IComponentAreaViewModel<> with another generic types:
public interface IComponentAreaViewModel<T, TModel>
where TModel : IComponentAreaModel<T>
{
TModel Model { get; }
}
public class ArticleViewModel : IComponentAreaViewModel<Article, ArticleModel>
{
public ArticleModel Model { get; }
}
I have a parent class
abstract class ClassPlugin
{
public ClassPlugin(eGuiType _guyType)
{
GuiType = _guyType;
}
public eGuiType GuiType;
public void Action() { }
}
I want all derived classes to implement the Action member and to define the guyType field.
To do that I have put it in the constructor, this is the only way that comes to mind.
Therefore an abstract class can be:
class ClassStartWF: ClassPlugin
{
public ClassStartWF(eGuiType _guyType)
{
GuiType = _guyType;
}
public void Action()
{
MessageBox.Show(GetType().Name);
}
}
the problem is that I get the error:
Severity Code Description Project File Line Suppression State
Error CS7036 There is no argument given that corresponds to the
required formal parameter '_guyType' of
'MainWindow.ClassPlugin.ClassPlugin(MainWindow.eGuiType)'
You should call the base class constructor in derived class constructor. Since you have create a constructor then compiler will not generate default constructor for your classes.
public ClassStartWF(eGuiType _guyType)
: base(_guyType)
{
// GuiType = _guyType; //this is not needed since the value is assigned in the base class constructor
}
Two problems...
First, you need to call the base class constructor from the derived type, as the base has no default constructor:
public ClassStartWF(eGuiType _guyType) : base(_guyType)
{
}
Since the base class takes care of setting the field you don't need to do it.
Secondly, you should make Action abstract in the base class and then override it in the derived class:
abstract class ClassPlugin
{
public abstract void Action();
}
class ClassStartWF: ClassPlugin
{
public ClassStartWF(eGuiType _guyType)
{
GuiType = _guyType;
}
public override void Action()
{
MessageBox.Show(GetType().Name);
}
}
At the moment you calls to Action won't dispatch to the derived instances when called through a base reference.
Also, rather than make GuiType a public variable you'd be better off making it a property:
public eGuiType GuiType{get; set;}
This will give you some control over the value. Also, you might want to consider making the setter private if it should only ever be set during construction.
Short version:
I have an abstract class A. It has a method that needs to know the value of a static class property that is specific to each subclass. The name and type is the same, just the value can be unique for each subclass.
Can I define this static property in the base class A to be able to access it with methods defined in A, but keeping the property's values of different subclasses unrelated?
Or how would I implement something like that?
Long version:
Let's say I have an abstract base class for data models. It has a public property Id (Int32).
I would like to implement a constructor in the base class that generates a new ID based on the last assigned ID for objects of a subclass.
The reason is that the real IDs are assigned automatically by the database, but each data model object already has to have a unique ID when it gets constructed without being written to the database yet. As the database assigns only positive integers as ID, my plan is to assign newly created data model objects a temporary, unique negative ID. As soon as the object gets written, the ID will get changed to the real one.
As I have quite a few different data model classes all deriving from my abstract base class, I thought it would be good to include that functionality there to not duplicate it. But each subclass has to have their own counter that points to the next free negative ID, as the different classes' IDs are unrelated.
So I need a static property in each subclass storing this class' last assigned temporary ID, but the mechanism to assign it is always the same and could be implemented into the abstract base class' constructor. However, I can't access a property from the base class that has to be implemented by the subclasses, which means I have to define it in the base class. But will this static property then be global for all subclasses, which is not what I want?
How can I implement this temporary ID counter the most elegant way?
Simplified code example:
public abstract class ModelBase
{
public Int32 Id { get; set; }
protected static Int32 LastTempId { get; set; } = 0;
public ModelBase()
{
Id = --LastTempId;
}
}
public class Model1 : ModelBase
{
public Model1 () : base ()
{
// do something model1-specific
}
}
public class Model2 : ModelBase
{
public Model2() : base()
{
// do something model2-specific
}
}
If I implement it like this, I fear that for both subclasses model1 and model2, the inherited static property LastTempId will be the same instance. But I want a separate counter for each subclass while still using it in the base class constructor.
Short answer
The sub-classes cannot have different values for the static property because the static property is a property of the class, not of it's instances, and it's not inherited.
Long answer
You could implement a single counter on the abstract class as a static property and have one constructor of the abstract class using it.
EDIT: To save different counters for each sub-class you could use a static dictionary mapping a Type (sub-class) to a counter.
public abstract class A<T>
{
public static Dictionary<Type, int> TempIDs = new Dictionary<Type, int>();
public int ID { get; set; }
public A()
{
if (!TempIDs.ContainsKey(typeof(T)))
TempIDs.Add(typeof(T), 0);
this.ID = TempIDs[typeof(T)] - 1;
TempIDs[typeof(T)]--;
}
}
public class B : A<B>
{
public string Foo { get; set; }
public B(string foo)
: base()
{
this.Foo = foo;
}
}
public class C : A<C>
{
public string Bar { get; set; }
public C(string bar)
: base()
{
this.Bar = bar;
}
}
B b1 = new B("foo");
B b2 = new B("bar");
C c1 = new C("foo");
C c2 = new C("foo");
b1.ID would be -1, b2.ID would be -2, c1.ID would be -1 and c2.ID would be -2
First of all, my humble opinion is entities shouldn't be responsible of assigning their own unique identifier. Keep a clear separation of concerns.
There should be another player in that game that should assign those temporary unique identifiers (either if they're negative or positive integers).
Usually, that so-called other player is an implementation of repository design pattern which is responsible of translating the domain (your models) into the definitive representation of your data and vice versa.
Usually a repository has a method to add objects. And this should be the point where you set these temporary identifiers:
public void Add(Some some)
{
some.Id = [call method here to set the whole id];
}
And, most repository implementations are per entity.
CustomerRepository
InvoiceRepository
...
...but this doesn't prevent you from defining a base repository class which could implement what can be in common when handling some entity types:
public interface IRepository<TEntity> where TEntity : EntityBase
{
// Other repository methods should be defined here
// but I just define Add for the convenience of this
// Q&A
void Add(TEntity entity);
}
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : EntityBase
{
public virtual void Add(TEntity entity)
{
entity.Id = [call method here to set the whole id];
}
}
...and now any class deriving Repository<TEntity> will be able to generate a temporary identifier for their specialized entities:
public class CustomerRepository : Repository<Customer> { }
public class InvoiceRepository : Repository<Invoice> { }
How you could implement the unique and temporary entity identifier as part of the abstract repository class and being able to do so for each specific entity type?
Use a dictionary to store per-entity last assigned identifier implementing a property to Repository<TEntity>:
public Dictionary<Type, int> EntityIdentifiers { get; } = new Dictionary<Type, int>();
...and a method to decrease next temporary identifier:
private static readonly object _syncLock = new object();
protected virtual void GetNextId()
{
int nextId;
// With thread-safety to avoid unwanted scenarios.
lock(_syncLock)
{
// Try to get last entity type id. Maybe the id doesn't exist
// and out parameter will set default Int32 value (i.e. 0).
bool init = EntityIdentifiers.TryGetValue(typeof(TEntity), out nextId);
// Now decrease once nextId and set it to EntityIdentifiers
nextId--;
if(!init)
EntityIdentifiers[typeof(TEntity)] = nextId;
else
EntityIdentifiers.Add(typeof(TEntity), nextId);
}
return nextId;
}
Finally, your Add method could look as follows:
public virtual void Add(TEntity entity)
{
entity.Id = GetNextId();
}
One way to go is reflection, but it takes run-time and is prone to runtime errors. As others mentioned: you cannot force inheriting classes to redeclare some static field and be able to use this field in ancestor class. So I think minimal code redundancy is necessary: each inheriting class should provide it's own key generator. This generator can be kept in static field of the class of course.
(Note this is not necessarily thread-safe.)
class KeyGenerator
{
private int _value = 0;
public int NextId()
{
return --this._value;
}
}
abstract class ModelBase
{
private KeyGenerator _generator;
public ModelBase(KeyGenerator _generator)
{
this._generator = _generator;
}
public void SaveObject()
{
int id = this._generator.NextId();
Console.WriteLine("Saving " + id.ToString());
}
}
class Car : ModelBase
{
private static KeyGenerator carKeyGenerator = new KeyGenerator();
public Car()
: base(carKeyGenerator)
{
}
}
class Food : ModelBase
{
private static KeyGenerator foodKeyGenerator = new KeyGenerator();
public Food()
: base(foodKeyGenerator)
{
}
}
class Program
{
static void Main(string[] args)
{
Food food1 = new Food();
Food food2 = new Food();
Car car1 = new Car();
food1.SaveObject();
food2.SaveObject();
car1.SaveObject();
}
}
This produces:
Saving -1
Saving -2
Saving -1
Just generate a GUID for each object before it gets added to your database. You could have an isAdded flag that tells you the object should be referred to be GUID, or clear the GUID once the object is added. With a GUID you never have to worry that two objects will clash. Also it obviates the need for separate IDs per subclass. I would not reuse the same property for two states as you propose.
https://msdn.microsoft.com/en-us/library/system.guid(v=vs.110).aspx
Well, static classes aren't inherited, so that's out,m and you can't force subclasses to implement a static method, so that's out too.
Rather than putting that method in the class itself, why not have a base interface that you can implement. Then you can have an instance method that can be abstract:
public interface IDataModelFactory<T> where T:ModelBase
{
int GetLastTempId();
}
public Model1Factory : IDataModelFactory<Model1>
{
public int GetLastTempId()
{
// logic for Model1
}
}
public Model2Factory : IDataModelFactory<Model2>
{
public int GetLastTempId()
{
// logic for Model2
}
}
Or if the logic is common to all classes, have an abstract base class with (or without) the interface:
public DataModelFactory<T> : IDataModelFactory<T>
{
public virtual int GetLastTempId()
{
// common logic
}
// other common logic
}
You could even make the factories singletons so you don't have to create instances all the time, and they can even be sub-classes of the model classes so they're closely linked.
As a side note, if you're uncertain what the inheritance/interface relationship would be, I often find it's quicker start with copy/paste reuse and refactor your code to introduce base classes and interfaces. That way you know what the common code is and can refactor that into common methods. Otherwise you are tempted to try and put everything in the base class and use switches or other constructs to change logic based on the derived type.