I'm trying to come up with a very neat way to alter an existing class. I'll try to explain what I came up with using this example;
abstract class AbstractX
{
public abstract string X();
protected internal abstract int Y();
}
// Execute all methods on another instance of AbstractX
// This is why the method(s) are 'protected *internal*'
class WrappedX : AbstractX
{
AbstractX _orig;
public WrappedX(AbstractX orig)
{
_orig = orig;
}
public override string X()
{
return _orig.X();
}
protected internal override int Y()
{
return _orig.Y();
}
}
// The AbstractX implementation I start with
class DefaultX : AbstractX
{
public override string X()
{
// do stuff
// call Y, note that this would never call Y in WrappedX
var y = Y();
return y.ToString();
}
protected internal override int Y()
{
return 1;
}
}
// The AbstractX implementation that should be able to alter *any* other AbstractX class
class AlteredX : WrappedX
{
public AlteredX(AbstractX orig)
:base(orig)
{
}
protected internal override int Y()
{
Console.WriteLine("Sweet, this can be added to any AbstractX instance!");
return base.Y();
}
}
Right, so the way I intend to use this is;
AbstractX x = new DefaultX();
x = new AlteredX(x);
Console.WriteLine(x.X()); // Should output 2 lines
Or to step away from the abstract example for a second and make it more concrete (should be self-explanatory);
FileWriterAbstract writer = new FileWriterDefault("path/to/file.ext");
writer = new FileWriterSplit(writer, "100MB");
writer = new FileWriterLogged(writer, "path/to/log.log");
writer.Write("Hello");
But (back to the abstract example) this isn't going to work. The moment AlteredX.X() is called (which isn't overridden) it goes to WrappedX.X(), which of course runs DefaultX.X() which uses it's own Y() method, and not the one I defined in AlteredX. It doesn't even know it exists.
I'm hoping it's obvious why I want this to work, but I'll explain further to make sure;
If I don't use WrappedX to created AlteredX, AlteredX will not be 'applyable' to any AbstractX instance,
thus making something like the FileWriter above impossible. Instead of;
FileWriterAbstract
FileWriterDefault : FileWriterAbstract
FileWriterWrap : FileWriterAbstract
FileWriterSplit : FileWriterWrap
FileWriterLogged : FileWriterWrap
It would become;
FileWriterAbstract
FileWriterDefault : FileWriterAbstract
FileWriterSplit : FileWriterDefault
// Implement Logged twice because we may want to use it with or without Split
FileWriterLogged : FileWriterDefault
FileWriterLoggedSplit : FileWriterSplit
And if I then created a new one, I'd have to implement it 4 times because I'd want it usable with;
Default
Split
Logged
Split+Logged
And so on...
So with that in mind, what's the best way to achieve this? The best I could come up with (untested) is;
class DefaultX : AbstractX
{
protected internal override Func<string> xf { get; set; }
protected internal override Func<int> yf { get; set; }
public DefaultX()
{
xf = XDefault;
yf = YDefault;
}
public override string X()
{
return xf();
}
protected override int Y()
{
return yf();
}
string XDefault()
{
var y = Y();
return y.ToString();
}
int YDefault()
{
return 1;
}
}
class AlteredX : WrappedX
{
Func<int> _yfOrig { get; set; }
public AlteredX()
{
// I'm assuming this class member doesn't get overwritten when I set
// base.yf in the line below.
_yfOrig = base.yf;
base.yf = YAltered;
}
private int YAltered()
{
Console.WriteLine("Sweet, this can be added to any AbstractX instance!");
return yfOrig();
}
}
Even if this does work, it seems really messy... does anyone have any suggestions?
One way to handle this would be to defer all of the internal operations to a separate, perhaps, internal utility class and provide a way for the wrapping classes to replace the implementation of the utility class. Note: this example requires any concrete, non-wrapping class to implement the utility class. A wrapper class may or may not choose to wrap the utility class. The key here is that the getter/setter for the utilities class in the base (abstract) class doesn't allow it to be overridden, thus every inheriting class uses the utility class as defined by it's constructor. If it chooses not to create it's own utilities, it defaults to that of the class it's wrapping - eventually making it all the way back to the concrete, non-wrapped composition root class if need be.
NOTE: this is very complex and I would avoid doing it. If possible use the standard decorator and only rely on public interface methods of the wrapped class. Also, the utility classes need not be inner classes. They could be injected via the constructor which might make it a bit cleaner. Then you would explicitly use the Decorator pattern on the utilities as well.
public interface IFoo
{
string X();
}
public abstract class AbstractFoo : IFoo
{
public abstract string X();
protected internal Footilities Utilities { get; set; }
protected internal abstract class Footilities
{
public abstract int Y();
}
}
public class DefaultFoo : AbstractFoo
{
public DefaultFoo()
{
Utilities = new DefaultFootilities();
}
public override string X()
{
var y = Utilities.Y();
return y.ToString();
}
protected internal class DefaultFootilities : Footilities
{
public override int Y()
{
return 1;
}
}
}
public abstract class AbstractWrappedFoo : AbstractFoo
{
protected readonly AbstractFoo Foo;
public AbstractWrappedFoo(AbstractFoo foo)
{
Foo = foo;
}
public override string X()
{
return Foo.X();
}
}
public class LoggedFoo : AbstractWrappedFoo
{
public LoggedFoo(AbstractFoo foo)
: base(foo)
{
Foo.Utilities = new LoggedUtilities(Foo.Utilities);
}
public override string X()
{
return Foo.X();
}
protected internal class LoggedUtilities : Footilities
{
private readonly Footilities _utilities;
public LoggedUtilities(Footilities utilities)
{
_utilities = utilities;
}
public override int Y()
{
Console.WriteLine("Sweet");
return _utilities.Y();
}
}
}
Now, this program
class Program
{
static void Main(string[] args)
{
AbstractFoo foo = new LoggedFoo(new DefaultFoo());
Console.WriteLine(foo.X());
}
}
Produces
Sweet!
1
I think you mixed up composition with inheritance.
When you call x.X() on an AlteredX object, the object calls X method of it's base object (WrappedX). The base object itself calls an object of type DefaultX which it has already wrapped. Now the Y method is called on an an object of DefaultX (_orig). You expect _orig knows there is something overriden in the caller of the caller! But how?
In this chain of call I don't see any point where overriding the method Y is involved.
Related
I have the following classes
public abstract class BaseViewPresenter { }
public abstract class BaseView<T> : UserControl
where T : BaseViewPresenter { }
public class LoginPresenter : BaseViewPresenter { }
public partial class LoginView : BaseView<LoginPresenter> { }
I have a method that looks like this (simplified)
public BaseView<BaseViewPresenter> Resolve(BaseViewPresenter model)
{
var type = model.GetType();
var viewType = _dataTemplates[type];
// Correctly creates BaseView object
var control = Activator.CreateInstance(viewType);
// Fails to cast as BaseView<BaseViewPresenter> so returns null
return control as BaseView<BaseViewPresenter>;
}
When I call this using an instances of LoginPresenter
var login = new LoginPresenter();
var ctl = Resolve(login);
The line Activator.CreateInstance(viewType) correctly resolves into a new instances of my LoginView, however control as BaseView<BaseViewPresenter> can't do the cast correctly so returns null.
Is there a way to correctly cast the control into BaseView<BaseViewPresenter> without using specific type generics?
Since LoginView inherits from BaseView<LoginPresenter>, and LoginPresenter inherits from BaseViewPresenter, I would assume there's a way to convert LoginView to BaseView<BaseViewPresenter>.
I am stuck with using .Net 3.5
This is a very frequently asked question. Let's rename your types:
abstract class Fruit { } // was BaseViewPresenter
abstract class FruitBowl<T> where T : Fruit // was BaseView
class Apple : Fruit { } // was LoginPresenter
class BowlOfApples : FruitBowl<Apple> { } // was LoginView
Your question now is:
I have a BowlOfApples, which inherits from FruitBowl<Apple>. Why can I not use it as a FruitBowl<Fruit>? An apple is a fruit, so a bowl of apples is a bowl of fruit.
No, it isn't. You can put a banana in a bowl of fruit, but you can't put a banana in a bowl of apples, and therefore a bowl of apples is not a bowl of fruit. (And by similar argument, a bowl of fruit is not a bowl of apples either.) Since the operations you can legally perform on the two types are different, they cannot be compatible.
Here is a photo of StackOverflow legend Jon Skeet demonstrating this fact:
The feature you want is called generic contravariance, and it is supported only on interfaces and delegate types when the compiler can prove that the variance is safe, and when the varying type is a reference type. For example, you can use an IEnumerable<Apple> in a context where IEnumerable<Fruit> is needed because the compiler can verify that there is no way that you can put a Banana into a sequence of fruit.
Do a search on "C# covariance and contravariance" on this site or on the web and you'll find many more details about how this feature works. In particular, my series of articles on how we designed and implemented this feature in C# 4 starts here: http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.aspx
I accepted Eric's answer since it provides a great explanation of why what I wanted wasn't possible, but I also thought I'd share my solution in case anyone else runs into this same problem.
I removed the generic type parameter from my original BaseView class, and created a 2nd version of the BaseView class that included the generic type parameter and specifics for it.
The first version is used by my .Resolve() method or other code that doesn't care about the specific types, and the second version is used by any code that does care, such as the implentation of a BaseView
Here's an example of how my code ended up looking
// base classes
public abstract class BaseViewPresenter { }
public abstract class BaseView : UserControl
{
public BaseViewPresenter Presenter { get; set; }
}
public abstract class BaseView<T> : BaseView
where T : BaseViewPresenter
{
public new T Presenter
{
get { return base.Presenter as T; }
set { base.Presenter = value; }
}
}
// specific classes
public class LoginPresenter : BaseViewPresenter { }
public partial class LoginView : BaseView<LoginPresenter>
{
// Can now call things like Presenter.LoginPresenterMethod()
}
// updated .Resolve method used for obtaining UI object
public BaseView Resolve(BaseViewPresenter presenter)
{
var type = model.GetType();
var viewType = _dataTemplates[type];
BaseView view = Activator.CreateInstance(viewType) as BaseView;
view.Presenter = presenter;
return view;
}
You're expecting to treat the type as being covariant with respect to the generic argument. Classes can never be covariant; you'd need to use an interface rather than (or in addition to) an abstract class to make it covariant with respect to T. You'd also need to be using C# 4.0.
My usual solution to this problem is to create an intermediary class that has access to the type-parametric class's methods through delegates. Fields can also be accessed through getters/setters.
The general pattern goes:
public abstract class Super {}
public abstract class MyAbstractType<T> where T : Super {
public MyGeneralType AsGeneralType() {
return MyGeneralType.Create(this);
}
// Depending on the context, an implicit cast operator might make things
// look nicer, though it might be too subtle to some tastes.
public static implicit operator MyGeneralType(MyAbstractType<T> t) {
return MyGeneralType.Create(t);
}
public int field;
public void MyMethod1() {}
public void MyMethod2(int argument) {}
public abstract bool MyMethod3(string argument);
}
public delegate T Getter<T>();
public delegate void Setter<T>(T value);
public delegate void MyMethod1Del();
public delegate void MyMethod2Del(int argument);
public delegate bool MyMethod3Del(string argument);
public class MyGeneralType {
public Getter<int> FieldGetter;
public Setter<int> FieldSetter;
public MyMethod1Del MyMethod1;
public MyMethod2Del MyMethod2;
public MyMethod3Del MyMethod3;
public static MyGeneralType Create<T>(MyAbstractType<T> t) where T : Super {
var g = new MyGeneralType();
g.FieldGetter = delegate { return t.field; };
g.FieldSetter = value => { t.field = value; };
g.MyMethod1 = t.MyMethod1;
g.MyMethod2 = t.MyMethod2;
g.MyMethod3 = t.MyMethod3;
return g;
}
public int field {
get { return FieldGetter(); }
set { FieldSetter(value); }
}
}
The above exemplifies getting all the methods and fields but normally I only need a few of them. This is a general solution to the problem and one could feasibly write a tool to generate these intermediary classes automatically, which I might at some point.
Try it here: https://dotnetfiddle.net/tLkmgR
Note that this is enough for all my cases, but you can be extra hacky with this:
public abstract class MyAbstractType<T> where T : Super {
// ... Same everything else ...
// data fields must become abstract getters/setters, unfortunate
public abstract int field {
get;
set;
}
public static implicit operator MyAbstractType<Super>(MyAbstractType<T> t) {
return MyGeneralType.Create(t);
}
}
public class MyGeneralType : MyAbstractType<Super> {
// ... same constructors and setter/getter
// fields but only keep method fields
// that contain the method references for
// implementations of abstract classes,
// and rename them not to clash with the
// actual method names ...
public MyMethod3Del myMethod3Ref;
// Implement abstract methods by calling the corresponding
// method references.
public override bool MyMethod3(string argument) {
return myMethod3Ref(argument);
}
// Same getters/setters but with override keyword
public override int field {
get { return FieldGetter(); }
set { FieldSetter(value); }
}
}
And there you go, now you can literally cast a MyAbstractType<Sub> where Sub : Super to a MyAbstractType<Super>, although it's no longer the same object anymore, but it does retain the same methods and data, it's sort of a complex pointer.
public class Sub : Super {}
public class MySubType : MyAbstractType<Sub> {
public int _field;
public override int field {
get { return _field; }
set { _field = value; }
}
public override bool MyMethod3(string argument) {
Console.WriteLine("hello " + argument);
return argument == "world";
}
}
public class MainClass {
public static void Main() {
MyAbstractType<Sub> sub = new MyAbstractType<Sub>();
MyAbstractType<Super> super = sub;
super.MyMethod3("hello"); // calls sub.MyMethod3();
super.field = 10; // sets sub.field
}
}
This isn't as good in my opinion, the other version of MyGeneralType is a more straighforward layer over the concrete types, plus it doesn't require rewriting the data fields, but it does actually answer the question, technically. Try it here: https://dotnetfiddle.net/S3r3ke
Example
Using these abstract classes:
public abstract class Animal {
public string name;
public Animal(string name) {
this.name = name;
}
public abstract string Sound();
}
public abstract class AnimalHouse<T> where T : Animal {
List<T> animals;
public AnimalHouse(T[] animals) {
this.animals = animals.ToList();
}
public static implicit operator GeneralAnimalHouse(AnimalHouse<T> house) {
return GeneralAnimalHouse.Create(house);
}
public List<string> HouseSounds() {
return animals.Select(animal => animal.Sound()).ToList();
}
}
We make this "general" variant:
public delegate List<string> HouseSoundsDel();
public class GeneralAnimalHouse {
public HouseSoundsDel HouseSounds;
public static GeneralAnimalHouse Create<T>(AnimalHouse<T> house) where T : Animal {
var general = new GeneralAnimalHouse();
general.HouseSounds = house.HouseSounds;
return general;
}
}
And finally with these inheritors:
public class Dog : Animal {
public Dog(string name) : base(name) {}
public override string Sound() {
return name + ": woof";
}
}
public class Cat : Animal {
public Cat(string name) : base(name) {}
public override string Sound() {
return name + ": meow";
}
}
public class DogHouse : AnimalHouse<Dog> {
public DogHouse(params Dog[] dogs) : base(dogs) {}
}
public class CatHouse : AnimalHouse<Cat> {
public CatHouse(params Cat[] cats) : base(cats) {}
}
We use it like this:
public class AnimalCity {
List<GeneralAnimalHouse> houses;
public AnimalCity(params GeneralAnimalHouse[] houses) {
this.houses = houses.ToList();
}
public List<string> CitySounds() {
var random = new Random();
return houses.SelectMany(house => house.HouseSounds())
.OrderBy(x => random.Next())
.ToList();
}
}
public class MainClass {
public static void Main() {
var fluffy = new Cat("Fluffy");
var miu = new Cat("Miu");
var snuffles = new Cat("Snuffles");
var snoopy = new Dog("Snoopy");
var marley = new Dog("Marley");
var megan = new Dog("Megan");
var catHouse = new CatHouse(fluffy, miu, snuffles);
var dogHouse = new DogHouse(snoopy, marley, megan);
var animalCity = new AnimalCity(catHouse, dogHouse);
foreach (var sound in animalCity.CitySounds()) {
Console.WriteLine(sound);
}
}
}
Output:
Miu: meow
Snoopy: woof
Snuffles: meow
Fluffy: meow
Marley: woof
Megan: woof
Notes:
I added names so it's clear that the method references carry their owner's data with them, for those unfamiliar with delegates.
The required using statements for this code are System, System.Collections.Generic, and System.Linq.
You can try it here: https://dotnetfiddle.net/6qkHL3#
A version that makes GeneralAnimalHouse a subclass of AnimalHouse<Animal> can be found here: https://dotnetfiddle.net/XS0ljg
Say you have access to a base class 'MyClass' that implements 'IFoo'. 'IFoo' defines the function 'int FooValue()' and 'MyClass' implements it explicitly. Now say you have a subclass of 'MyClass' called 'MySubClass' and you want to override 'FooValue' in that subclass, but you also want the subclass's implementation to be based on the result from the base class's implementation.
Now normally, this would be solved by simply moving the implementation to a protected function in the base class which we'd then simply overide in the subclass. Done and done. But we don't have access to the source code of the base class. We only have it as a reference to a library. So how do you solve this?
Not a Duplicate (update: ...as this one)!
There's this SO question here... C#: Property overriding by specifying the interface explicitly... that shows while you can't override a base class's interface through the normal channels per se, you can explicitly re-implement the same interface on a subclass and that behaves like you're overriding the interface (but in actuality you're re-implementing it, not overriding it.) That said, what I'm trying to figure out is how do I get at the base class's implementation. (That's why IMHO this isn't a duplicate of that question.)
Here's some pseudocode of the base class which again, we don't have access to code-wise...
public interface IFoo
{
int FooValue();
}
public class MyClass : IFoo
{
int IFoo.FooValue() <-- Explicit implementation requiring a cast to access.
{
return 4;
}
}
This is what we're trying to do, but obviously this isn't allowed because you can't use 'base' like this.
public class MySubClass : MyClass
{
int IFoo.FooValue()
{
int baseResult = ((IFoo)base).FooValue(); <-- Can't use 'base' like this
return baseResult * 2;
}
}
So is this possible?
I will be honest, there is no straightforward answer to this. Feels like a limitation of the language. May be there is some sound reason for the lack of it.
However, I can think of some not so clean work arounds.
Reflection. Imho, the simplest option here. One of those rare cases where reflection is really needed.
Your own interface and base class derived from referenced library.
//your interface
public interface IRealFoo : IFoo
{
new int FooValue();
}
//your base class
public class MyRealClass : MyClass, IRealFoo
{
protected virtual int FooValue()
{
return ((IFoo)this).FooValue();
}
int IRealFoo.FooValue()
{
return FooValue();
}
}
//your child class
public class MyRealSubClass : MyRealClass
{
protected override int FooValue()
{
return base.FooValue() * 2;
}
}
And you deal with IRealFoo, MyRealClass and so on instead of IFoo, MyClass etc.
IRealFoo x = new MyRealClass();
IRealFoo y = new MyRealSubClass();
Console.WriteLine(x.FooValue()); //4
Console.WriteLine(y.FooValue()); //8
Same as above but abstract class instead of interface.
Same as above, but you can also have an abstract base class RealFoo instead of interface IFoo. This I think is slightly easier code, but need not be good code. It completely changes the intent of the code.
public abstract class RealFoo : MyClass
{
public virtual int FooValue()
{
return ((IFoo)this).FooValue();
}
}
public class MyRealClass : RealFoo
{
public override int FooValue()
{
return base.FooValue();
}
}
public class MyRealSubClass : MyRealClass
{
public override int FooValue()
{
return base.FooValue() * 2;
}
}
//call it like:
RealFoo x = new MyRealClass();
RealFoo y = new MyRealSubClass();
Console.WriteLine(x.FooValue()); //4
Console.WriteLine(y.FooValue()); //8
Extension method along with dynamic.
public class MyRealClass : MyClass
{
public virtual int FooValue()
{
return ((IFoo)this).FooValue();
}
}
public class MyRealSubClass : MyRealClass
{
public override int FooValue()
{
return base.FooValue() * 2;
}
}
public static int RealFooValue(this IFoo foo)
{
return ((dynamic)foo).FooValue();
}
In this one case you can stick with familiar IFoo interface, but you got to call the extension method RealFooValue instead of FooValue. This will be confusing with potentially wrong result when calling FooValue. I dont advise it.
IFoo x = new MyRealClass();
IFoo y = new MyRealSubClass();
Console.WriteLine(x.RealFooValue()); //4
Console.WriteLine(y.RealFooValue()); //8
Switch on type with if-else logic.
public class MySubClass : MyClass
{
}
public static int RealFooValue(this IFoo foo)
{
var type = foo.GetType();
if (type == typeof(MyClass))
return foo.FooValue();
else if (type == typeof(MySubClass))
return foo.FooValue() * 2; //logic goes here
throw new Exception();
}
This has the same problem as above. Dont recommend it.
IFoo x = new MyClass();
IFoo y = new MySubClass();
Console.WriteLine(x.RealFooValue()); //4
Console.WriteLine(y.RealFooValue()); //8
Explicit interface realization means that IFoo.FooValue() is private
(you can check it by means of reflection):
MethodInfo mi = typeof(MyClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(m => m.Name.EndsWith("IFoo.FooValue")).ToList()[0];
if (mi.IsPrivate) {
// And it is private....
}
and so you can't call the
inherited IFoo.FooValue().
Possible byway
public interface IFoo
{
int FooValue();
}
public class MyClass : IFoo
{
// This (main logic) should be inherited/override
protected virtual int CoreFooValue()
{
return 4;
}
// Just a non-virtual interface method which is immutable
int IFoo.FooValue()
{
return CoreFooValue();
}
}
public class MySubClass : MyClass {
// Logic is changed, interface is not
protected override int CoreFooValue()
{
return base.CoreFooValue() * 2;
}
}
See also Non-virtual interface pattern
http://en.wikipedia.org/wiki/Non-virtual_interface_pattern
I often use the class-factory pattern whereby a class has a private constructor and a static method to create the class. This allows for the situation where the class cannot be constructed for some reason, and a null is returned - very handy.
I would like to be able to extend this to a factory method which creates a particular class from a hierarchy of derived classes depending on conditions. However I can't see a way of then hiding the constructors of the derived classes to force the use of the factory method. If the factory method is in the base class it no longer has access to the private constructors of derived classes. Putting a factory method in every derived class doesn't work as the required type must then be known beforehand. Nested classes might be a way if a class had access to the private members of a nested class, but sadly it seems that the nested classes have access to the private members of the enclosing class, but not the other way round.
Does anyone know of a way of doing this?
There are several possibilities, two of which are:
Put all those classes in one project and make the constructors internal. Other projects won't be able to call those constructors but the code inside that project can.
Make the constructors of those classes protected (instead of private) and create a private derived class in the class containing the factory method. Create an instance of that private class and return it.
Example for the second option:
public static class AnimalFactory
{
public static Animal Create(int parameter)
{
switch(parameter)
{
case 0:
return new DogProxy();
case 1:
return new CatProxy();
default:
throw new ArgumentOutOfRangeException("parameter");
}
}
private class DogProxy : Dog { }
private class CatProxy : Cat { }
}
public abstract class Animal { }
public class Dog : Animal
{
protected Dog() { }
}
public class Cat : Animal
{
protected Cat() { }
}
Here's the sample code I was working on when Daniel posted his answer. It looks like it's doing what he suggested:
public static class BaseFactory
{
public static Base Create(bool condition)
{
if (condition)
{
return Derived1.Create(1, "TEST");
}
else
{
return Derived2.Create(1, DateTime.Now);
}
}
}
public class Base
{
protected Base(int value)
{
}
protected static Base Create(int value)
{
return new Base(value);
}
}
public sealed class Derived1: Base
{
private Derived1(int value, string text): base(value)
{
}
internal static Derived1 Create(int value, string text)
{
return new Derived1(value, text);
}
}
public sealed class Derived2: Base
{
private Derived2(int value, DateTime time): base(value)
{
}
internal static Derived2 Create(int value, DateTime time)
{
return new Derived2(value, time);
}
}
[EDIT] And for Daniel's second suggestion:
public static class BaseFactory
{
public static Base Create(bool condition)
{
if (condition)
{
return new Derived1Creator(1, "TEST");
}
else
{
return new Derived2Creator(1, DateTime.Now);
}
}
private sealed class Derived1Creator: Derived1
{
public Derived1Creator(int value, string text): base(value, text)
{
}
}
private sealed class Derived2Creator: Derived2
{
public Derived2Creator(int value, DateTime time): base(value, time)
{
}
}
}
public class Base
{
protected Base(int value)
{
}
protected static Base Create(int value)
{
return new Base(value);
}
}
public class Derived1: Base
{
protected Derived1(int value, string text): base(value)
{
}
protected static Derived1 Create(int value, string text)
{
return new Derived1(value, text);
}
}
public class Derived2: Base
{
protected Derived2(int value, DateTime time): base(value)
{
}
protected static Derived2 Create(int value, DateTime time)
{
return new Derived2(value, time);
}
}
Note that this second approach means that the classes can't be sealed, unfortunately.
Rather than using methods inside the class itself as a factory implement the Factory pattern by means of a static class ("the factory") that returns the correct instance based on the logic you write.
You can intercept the derived type creation in the base class contructor and check that the caller is your factory using StackFrames:
protected Class1() //base class ctor
{
StackFrame[] stackFrames = new StackTrace().GetFrames();
foreach (var frame in stackFrames)
{
//check caller and throw an exception if not satisfied
}
}
using System;
public class Base
{
public Base()
{
}
public void M1()
{
}
public void M2()
{
}
public void M3()
{
}
}
public class Derived : Base
{
//this class should get only method 1
}
public class SecondDerived : Base
{
//this class should get only method 2 and method3
}
The requirement is : the base class contains the 3 methods M1, M2, M3.
The derived class should inherit only M1 and SecondDerived should inherit only M2 and M3.
How can this be done?
You cannot selectively inherit methods like this. A derived class automatically inherits all public methods of the base class. I suggest you to split the Base class into two classes:
public class Base1
{
public Base1()
{
}
public void M1()
{
}
}
public class Base2
{
public void M2()
{
}
public void M3()
{
}
}
public class First : Base1
public class Second : Base2
You cannot do it in this way. Inheritance implies an "IS A" relationship.
If SecondDerived would not have a M1() then it would not be compatible with a reference to a the class Base.
So maybe you shouldn't be using inheritance for whatever problem you're solving.
It is not possible to do what you want with inheritance.
It seems you have no intention of overriding, you simply want to "inherit" behavior from the base class selectively. You could do this using a "has a" relationship:
public class Base
{
internal Base() {} //mark constructor as internal so it can not be used outside your assembly if necessary
public Foo Mehtod1() {...}
public Foo Mehtod2() {...}
public Foo Mehtod3() {...}
}
Then simply do the following:
class A
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method1() { return this.internalBase.Method1(); }
}
class B
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method2() { return this.internalBase.Method2(); }
public Foo Method3() { return this.internalBase.Method3(); }
}
UPDATE: A possible alternative solution is to make your Base class methods virtual and override them all in your derived classes, throwing NotSupportedExceptions in those methods that you do not want the class to make available. I don't really like this solution but it has the advantage of not loosing the polyphormism inheritance gives you which might be useful if you have some core base functionality which all derived classes will share (in your example you seem to imply they wont).
It is possible by adding Obsolete attribute
public class A
{
public virtual void M1() { }
public void M2() { }
public void M3() { }
}
public class B : A
{
[Obsolete("You can not use this", true)]
public sealed override void M1()
{
}
}
public class C : B
{
public void Test()
{
// Will show error
base.M1();
}
}
I have a base class which has a method for moving files to appropriate folders. There are many different files with many different naming schemes. The moving and folder creation is the same for every file, but determining the date is different because of the differing file names. I am trying to do this:
public class FileBase
{
protected FileInfo _source;
protected string GetMonth()
{
// 2/3 Files have the Month in this location
// So I want this to be used unless a derived class
// redefines this method.
return _source.Name.Substring(Source.Name.Length - 15, 2);
}
public void MoveFileToProcessedFolder()
{
MoveFileToFolder(Properties.Settings.Default.processedFolder + GetMonth);
}
private void MoveFileToFolder(string destination)
{
....
}
}
public class FooFile : FileBase
{
protected new string GetMonth()
{
return _source.Name.Substring(Source.Name.Length - 9, 2);
}
}
public class Program
{
FooFile x = new FooFile("c:\Some\File\Location_20110308.txt");
x.MoveFileToProcessedFolder();
}
The problem is that this code results in the base class version of 'GetMonth' being invoked inside the 'MoveFileToProcessedFolder' method. I thought that with the 'new' keyword, this would hide the original implementation and allow the derived implementation to take over. This is not what is happening. Obviously I'm not understanding the purpose of new in this case, can anyone out there help me understand this?
Thanks.
mark the methods as virtual then override them in your derived classes. New allows you to change the signature of the item so if base class has method named void DoWork() you can declare int DoWork() in your derived class by using new keyword. This solves the implicit calls but you can still explicitly call the base class method.
Use virtual (base) and override (derived)
What you really want is to make the base class's method virtual and then override it in the subclass.
public class BaseClass {
public virtual int Foo() {
return 1;
}
}
public class SubClass : BaseClass {
public override int Foo() {
return 42;
}
}
It will only hide when referenced directly by the type that is hiding the method. But since you are calling the implementation from the base class it is deferring to the method defined there.
In your case it sounds like you want virtual implementations rather then method hiding.
public class FileBase
{
protected FileInfo _source;
protected virtual string GetMonth()
{
// 2/3 Files have the Month in this location
// So I want this to be used unless a derived class
// redefines this method.
return _source.Name.Substring(Source.Name.Length - 15, 2);
}
public void MoveFileToProcessedFolder()
{
MoveFileToFolder(Properties.Settings.Default.processedFolder + GetMonth());
}
private void MoveFileToFolder(string destination)
{
....
}
}
public class FooFile : FileBase
{
protected override string GetMonth()
{
return _source.Name.Substring(Source.Name.Length - 9, 2);
}
}
public class Program
{
FooFile x = new FooFile("c:\Some\File\Location_20110308.txt");
x.MoveFileToProcessedFolder();
}
In this case you need to use Virtual in the base class and Override in the derived class. It works the way you are expecting using `new' if you do as below.
class Program
{
static void Main(string[] args)
{
FileBase fb = new FileBase();
Console.WriteLine(fb.GetMonth());
FooFile ff = new FooFile();
Console.WriteLine(ff.GetMonth());
Console.ReadLine();
}
}
public class FileBase
{
public string GetMonth()
{
return "FileBase::GetMonth()";
}
}
public class FooFile : FileBase
{
public new string GetMonth() // Hides the base method
{
return "FooFile::GetMonth()";
}
}