Covariance with derived classes in C# - c#

I have the following code (ready to paste into linqpad). Basically there is a base 'model' class with a 'treemembermodel' class deriving from it.
class MemberModel
{
public List<Member> Team = new List<Member>();
public void IncreaseAge()
{
// Would like this to modify the Treemember
Team[0].Age++;
}
}
class TreeMemberModel : MemberModel
{
public new List<TreeMember> Team = new List<TreeMember>();
public void UpdateName(string newName)
{
}
}
Same for a Member class with a 'TreeMember' deriving from it.
public class Member
{
public string Name;
public int Age;
}
public class TreeMember: Member
{
public string ParentName;
}
The idea is that the base member model stores a list of normal members, while the 'tree' model (and member) classes ensure a 'tree' structure by maintaining integrity between parent and subordinate fields.
This all seemed a good idea (the below example is stylised) - I figured any 'common' methods applying to both object types (eg 'increaseage' below) would modify the treeMember in the TreeModel when called from that model. However, calling 'increaseage' in my main method instead tries to access the 'Team' collection from the base 'MemberModel' instead, which of course doesn't exist.
void Main()
{
TreeMemberModel t = new TreeMemberModel();
t.Team.Add(new TreeMember() { Name = "original", Age = 10 });
// Call method within derived class
t.UpdateName("changed");
Console.WriteLine (t.Team[0].Name);
// Call method which drops down to base class method, and would like it to modify the TreeMemberModel's Team collection, not MemberModel's.
t.IncreaseAge();
Console.WriteLine (t.Team[0].Age);
}
I figure this is a covariance issue, and have tried a few things around making classes generic and so forth. Can I configure this so it drops back to the base class's methods while manipulating the elements of the TreeModel collection?

You should try following:
class MemberModel<TMember> where TMember : Member
{
public List<TMember> Team = new List<TMember>();
public void IncreaseAge()
{
// Would like this to modify the Treemember
Team[0].Age++;
}
}
class TreeMemberModel : MemberModel<TreeMember>
{
public void UpdateName(string newName)
{
}
}

Related

Cannot access inherited property if class has nested class of same name

I want to access a property of some class of mine, but get compiler error "CS0572 - Cannot reference a type through an expression".
I have the following setup
public interface IHelper {
void DoHelp();
}
public abstract class ClassWithHelperBase<THelper> where THelper : IHelper {
public THelper Helper { get; }
}
public class ClassWithHelper : ClassWithHelperBase<ClassWithHelper.Helper> {
// use a nested class, since there will be n classes deriving from ClassWithHelper and giving each helper a readable name (in this example ClassWithHelperHelper) is ugly
public class Helper : IHelper {
public static void SomeStaticMethod() { }
public void DoHelp() { }
}
}
public class Test {
private ClassWithHelper myClass;
public void DoTest() {
((ClassWithHelperBase<ClassWithHelper.Helper>) myClass).Helper.DoHelp(); // this works, but is ugly
myClass.Helper.DoHelp(); // what I want, but it's not working
//myClass.Helper.SomeStaticMethod(); // funnily IDE supposes static methods here even though the resulting code is invalid, since I am (obviously) not referencing the class type
}
}
The interface is unnecessary for reproduction, I added it for clarity.
Note: I do not want to call a static method, I just added it, to show the IDE mixes up the member and the class qualifier.
Is there a way to access the property Helper of myClass, without casting myClass or renaming the nested class?
Aka: Why can't the compiler distinguish the member and the nested class?
The problems is due to name collision between Helper class (type) and Helper property. Try this
public interface IHelper
{
void DoHelp();
}
public abstract class ClassWithHelperBase<THelper> where THelper : IHelper
{
public THelper Helper { get; set; }
}
public class ClassWithHelper : ClassWithHelperBase<ClassWithHelper.CHelper>
{
// use a nested class, since there will be n classes deriving from ClassWithHelper and giving each helper a readable name (in this example ClassWithHelperHelper) is ugly
public class CHelper : IHelper
{
public static void SomeStaticMethod() {}
public void DoHelp() { }
}
}
public class Test
{
private ClassWithHelper myClass;
public void DoTest() {
myClass.Helper.DoHelp();
ClassWithHelper.CHelper.SomeStaticMethod();
}
}
Here I renamed Helper class to the CHelper, so compiler can now distinguish class and property and thus the line myClass.Helper.DoHelp(); now works without cast.
If a "do not rename nested class" requirement is absolutely mandatory, then the problem may be also solved by renaming the Helper property in the base class to avoid name collision. However, I can't imagine better name for the property.
Unfortunately, for the static method, you can't reference myClass instance. So, you will need reference the whole type.

Interface how do I get any Customer?

we have an interface with a Generic Customer (gold/silver), now lets say i stored the last created cutomer somewhere (Cache/DB/etc).
how do i create a GetCustomer method that returns the type of customer.
Should i add GetCustomer to the base class or interface or elsewhere ? and how do we use GetCustomer ?
Hope that makes sense.
interface ICstomerInterface<T>
{
T MakeCustomer();
}
public abstract class BaseCustomer<T>: ICstomerInterface<T>
{
public string Type { get; set; }
public string Name { get; set; }
// methods
public abstract T MakeCustomer();
}
public class Gold : BaseCustomer<Gold>
{
public override Gold MakeCustomer()
{
var customer = new Gold
{
Type= "Gold",
Name = "Jack"
};
return customer;
}
}
public class Silver : BaseCustomer<Silver>
{
public override Silver MakeCustomer()
{
var customer = new Silver();
customer.Name = "Jones";
customer.Type = "Silver";
return customer;
}
}
The problem with you design is that MakeCustomer is an instance method of the customers. This means, that you must create a customer to be able to call MakeCustomer. In other words, this design will not work!
You have two options: Either simply initialize the customers in their respective constructors, or create a customer factory. This must be a separate class (static or not).
The generic type parameter is superfluous.
public abstract class CustomerBase
{
public CustomerBase(string name)
{
Name = name;
}
public abstract string Type { get; }
public string Name { get; }
}
public class GoldCustomer : CustomerBase
{
public GoldCustomer(string name)
: base(name)
{
}
public override string Type => "Gold";
}
public class SilverCustomer : CustomerBase
{
public SilverCustomer(string name)
: base(name)
{
}
public override string Type => "Silver";
}
The Type property can be a getter only property. It can be abstract in the base class to force concrete customer classes to implement it.
The name must be passed to the constructor to be able to assign different names to different customers.
See also Abstract factory pattern on Wikipedia.
Example:
var customers = new List<CustomerBase> {
new GoldCustomer("Frank"),
new SilverCustomer("Jack")
};
foreach (CustomerBase c in customers) {
Console.WriteLine($"{c.Name} is {c.Type}");
}
Prints:
Frank is Gold
Jack is Silver
See working example: https://dotnetfiddle.net/BiAskT
You could have an extension method to get the customer type (on a static class):
public static Type GetCustomerType<T>(this ICstomerInterface<T> _customer)
{
return typeof(T);
}
All with the intention that you don't have to make redundant code each time you create a new Customer class that implements that interface.
Your sample code doesn't contain a base type that can contain all your customers, i.e. there is no strongly-typed variable that could hold either a BaseCustomer<Gold> or a BaseCustomer<Silver>. There is no type compatibility between those two at all, no more than a Dictionary<int> can be stored as a Dictionary<string> (in fact, even worse, because there isn't covariance in your object model). Given that fact, your question makes little sense, because you'll always have to declare the type parameter to store a customer somewhere, therefore there is no need to learn the type at run time.
But let's say you want a cache that works for both. You'd introduce a non-generic base interface:
public interface ICustomer
{
Guid CustomerGuid { get; }
}
public abstract class BaseCustomer<T>: ICstomerInterface<T>, ICustomer
{
///etc....
Now you can define a cache that could hold all customers:
var cache = new Dictionary<Guid,ICustomer>();
var gold = new Gold();
cache.Add( gold.CustomerGuid, gold );
var silver = new Silver();
cache.Add( silver.CustomerGuid, silver );
Now you can retrieve any customer by its Guid:
var customer = cache[guid];
And to determine its type, just use
bool isGold = customer is Gold;
bool isSilver = customer is Silver;
Or to get a string that tells you the type:
string type = customer.GetType().Name;
It appears that you are trying to use the classic Factory Method.
Personally for simple classes, like the one you are asking about, I would add a static method on the base class, like so:
public abstract class BaseCustomer<T>: ICstomerInterface<T>
{
public static BaseCustomer<T> GetLastCustomer()
{
// Get from storage, the last customer.
}
}
That way your Create customer method is separate from your get customer method but still accessible from anywhere.

How to get the name of class where an object is initialized c#

I have a few classes. Lets say:
public class A
{
public void SomeAction()
{
Debug.Write("I was declared in class: and my name is:");
}
}
And
public class B
{
public static A myClass = new A();
}
public class C
{
public static A myClass = new A();
}
public class D
{
public static A myClass = new A();
}
What I want "SomeAction" in class A to do is to print out which class it was initialized in.
So that for example in another class I called C.myClass.SomeAction(); it would print out "I was declared in class C my name is myClass"
I hope this makes sense.
The reasons im doing this is for debugging within automated testing. I understand its not the best way to do things but its a requirement of the business.
This requirement can be satisfied without inheritance or passing the object; we can get the name of the class that calls the constructor from within the body of the constructor by examining the stack.
public class A
{
private string _createdBy;
public void SomeAction()
{
Console.WriteLine("I was declared in class [{0}]", _createdBy);
}
public A()
{
var stackFrame = new StackFrame(1);
var method = stackFrame.GetMethod();
_createdBy = method.DeclaringType.Name;
}
}
In terms of performance, I am assuming that you are not creating many instances of these objects. You could also predicate this on whether you are doing a DEBUG build or on some other setting, so that this stuff is skipped entirely in your production executables.
Since you only reference an instance of class A in your other classes, I think there is no other way then setting a reference to the type which created class A, like eddie_cat already mentioned. You could do something like this:
public class B
{
public static A myClass = new A(typeof(B));
}
And then your class A would look like:
public class A
{
// store the parent type
private Type mParentClass;
// provide parent type during construction of A
public A(Type parentClass)
{
mParentClass = parentClass;
}
// note that method cannot be static anymore, since every instance of A might
// have a different parent
public void SomeAction()
{
// access field where parent type is stored.
Debug.Write("I was declared in class: {0} and my name is:",mParentClass.Name);
}
}
I think you have two choices. Either set a property in A, or inherit from A. Personally, I prefer inheriting from A, because then A could just use GetType().
public class A
{
public void SomeMethod()
{
Debug.Write(string.Format("I was declared in class: {0}",this.GetType()));
}
}
public class B : A
{
}
var instanceOfB = new B();
instanceOfB.SomeMethod();

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; }
}

What is the best way to design this class hierarchy?

I have a database table which contains an ID column and a Name column. I am tasked with designing a program that accepts one of the IDs as an argument to Main().
Bold is edit 2
I need to use that ID which must exist in the database, to correspond to some code to run. Each row in the table corresponds to slightly different code, but a lot of them share a lot of code. I need a design that will minimize code duplication.
So far what I've developed is an abstract base class that has an abstract Int32 field ID to enforce derived classes having their corresponding ID in the database. That way I can reflect over the derived classes to find the one whose ID matches the Main() argument and instantiate that class. Then I just call the virtual methods from Main() which runs the most derived code that has been defined.
public abstract class Base {
public abstract Int32 Id { get; }
public void Foo() {
// Do something
}
}
public class Derived {
public override Int32 Id { get { return 42; } }
public void Foo() {
// Do something more specific
}
}
Does anyone have any better ideas how to achieve what I want? I like the idea of keeping the ID right in the class definition, but I'm open to changing that if it makes sense.
Thanks!
EDIT:
One thing I don't like about this is that I have to reflect over each derived type and instantiate that type to check the ID. Does anyone have a better idea on how to do that?
Instead of using a property to define the ID of the class, use a custom attribute. That way, you don't have to instantiate the object to check what its ID is.
When your program runs, it can scan the assembly for all classes with that attribute tag, and find the one with the matching ID, instantiate that class, and then run it's Foo method. If you perform this kind of lookup multiple times per application run, you could instatiate all the classes with your custom attribute and then put them into a Dictionary to provide quick lookups by ID.
Your code might look something like this:
[AttributeUsage(AttributeTargets.Class)]
public class CommandAttribute {
public CommandAttribute(int id) {
ID = id;
}
public int ID { get; private set; }
}
public abstract class Command {
public abstract void Execute();
}
[Command(2)]
public class MyCommand : Command {
public override void Execute() {
//Do something useful
}
}
The other advantage of using a custom attribute is that you have to explicitly tag everything that is a candidate for being instantiated and executed by ID, rather than assuming than anything derived from your base class is a candidate. If you are sharing code between the classes, you might want to make a common base class for them that derives from your base class, but should not be instantiated or executed on its own.
One thing I don't understand is, what is the point of the "Name" field if the class you want to run is identified by the ID? If you can decide what the name of each ID is, then you could use the name field as the fully qualified type name of the class you want to execute, which then avoid having to scan through all the types in your assembly (or application domain, depending upon the scope of your search). That setup is a bit more prone to typos, however.
It sounds like you need to implement a factory pattern.
I would define an interface:
public interface IWidget
{
void Foo();
}
Then the base class:
public abstract class WidgetBase : IWidget
{
public void Foo()
{
this.Bar()
}
protected virtual void Bar()
{
// Base implementation
}
}
The factory:
public static WidgetFactory
{
public static IWidget Create(int id)
{
// Get class name from id, probably use the name in your database.
// Get Type from class name
// Get constructor for Type
// Create instance using constructor and return it.
}
}
A derived class:
public class DerivedWidget : WidgetBase
{
protected override void Bar()
{
// call base implementation
base.Bar();
// derived implementation
}
}
In your main:
public void Main(int id)
{
var widget = WidgetBase.Create(id);
widget.Foo();
}
I like #Xint0's idea of using a Factory for this kind of task, but I thought I'd still contribute another answer.
A better way to implement your original design would be to pass the ID to the base constructor as follows:
public abstract class Base {
public Int32 Id { get; private set; }
protected Base(Int32 id) {
this.Id = id;
}
public void Foo() {
// Do something
}
}
public class Derived : Base {
public Derived : base(42) {}
public void Foo() {
// Do something more specific
}
}

Categories

Resources