I know the feature doesn't exist in C#, but PHP recently added a feature called Traits which I thought was a bit silly at first until I started thinking about it.
Say I have a base class called Client. Client has a single property called Name.
Now I'm developing a re-usable application that will be used by many different customers. All customers agree that a client should have a name, hence it being in the base-class.
Now Customer A comes along and says he also need to track the client's Weight. Customer B doesn't need the Weight, but he wants to track Height. Customer C wants to track both Weight and Height.
With traits, we could make the both the Weight and the Height features traits:
class ClientA extends Client use TClientWeight
class ClientB extends Client use TClientHeight
class ClientC extends Client use TClientWeight, TClientHeight
Now I can meet all my customers' needs without adding any extra fluff to the class. If my customer comes back later and says "Oh, I really like that feature, can I have it too?", I just update the class definition to include the extra trait.
How would you accomplish this in C#?
Interfaces don't work here because I want concrete definitions for the properties and any associated methods, and I don't want to re-implement them for each version of the class.
(By "customer", I mean a literal person who has employed me as a developer, whereas by "client" I'm referring a programming class; each of my customers has clients that they want to record information about)
You can get the syntax by using marker interfaces and extension methods.
Prerequisite: the interfaces need to define the contract which is later used by the extension method. Basically the interface defines the contract for being able to "implement" a trait; ideally the class where you add the interface should already have all members of the interface present so that no additional implementation is required.
public class Client {
public double Weight { get; }
public double Height { get; }
}
public interface TClientWeight {
double Weight { get; }
}
public interface TClientHeight {
double Height { get; }
}
public class ClientA: Client, TClientWeight { }
public class ClientB: Client, TClientHeight { }
public class ClientC: Client, TClientWeight, TClientHeight { }
public static class TClientWeightMethods {
public static bool IsHeavierThan(this TClientWeight client, double weight) {
return client.Weight > weight;
}
// add more methods as you see fit
}
public static class TClientHeightMethods {
public static bool IsTallerThan(this TClientHeight client, double height) {
return client.Height > height;
}
// add more methods as you see fit
}
Use like this:
var ca = new ClientA();
ca.IsHeavierThan(10); // OK
ca.IsTallerThan(10); // compiler error
Edit: The question was raised how additional data could be stored. This can also be addressed by doing some extra coding:
public interface IDynamicObject {
bool TryGetAttribute(string key, out object value);
void SetAttribute(string key, object value);
// void RemoveAttribute(string key)
}
public class DynamicObject: IDynamicObject {
private readonly Dictionary<string, object> data = new Dictionary<string, object>(StringComparer.Ordinal);
bool IDynamicObject.TryGetAttribute(string key, out object value) {
return data.TryGet(key, out value);
}
void IDynamicObject.SetAttribute(string key, object value) {
data[key] = value;
}
}
And then, the trait methods can add and retrieve data if the "trait interface" inherits from IDynamicObject:
public class Client: DynamicObject { /* implementation see above */ }
public interface TClientWeight, IDynamicObject {
double Weight { get; }
}
public class ClientA: Client, TClientWeight { }
public static class TClientWeightMethods {
public static bool HasWeightChanged(this TClientWeight client) {
object oldWeight;
bool result = client.TryGetAttribute("oldWeight", out oldWeight) && client.Weight.Equals(oldWeight);
client.SetAttribute("oldWeight", client.Weight);
return result;
}
// add more methods as you see fit
}
Note: by implementing IDynamicMetaObjectProvider as well the object would even allow to expose the dynamic data through the DLR, making the access to the additional properties transparent when used with the dynamic keyword.
Traits can be implemented in C# 8 by using default interface methods. Java 8 introduced default interface methods for this reason too.
Using C# 8, you can write almost exactly what you proposed in the question. The traits are implemented by the IClientWeight, IClientHeight interfaces that provide a default implementation for their methods. In this case, they just return 0:
public interface IClientWeight
{
int getWeight()=>0;
}
public interface IClientHeight
{
int getHeight()=>0;
}
public class Client
{
public String Name {get;set;}
}
ClientA and ClientB have the traits but don't implement them. ClientC implements only IClientHeight and returns a different number, in this case 16 :
class ClientA : Client, IClientWeight{}
class ClientB : Client, IClientHeight{}
class ClientC : Client, IClientWeight, IClientHeight
{
public int getHeight()=>16;
}
When getHeight() is called in ClientB through the interface, the default implementation is called. getHeight() can only be called through the interface.
ClientC implements the IClientHeight interface so its own method is called. The method is available through the class itself.
public class C {
public void M() {
//Accessed through the interface
IClientHeight clientB = new ClientB();
clientB.getHeight();
//Accessed directly or through the class
var clientC = new ClientC();
clientC.getHeight();
}
}
This SharpLab.io example shows the code produced from this example
Many of the traits features described in the PHP overview on traits can be implemented easily with default interface methods. Traits (interfaces) can be combined. It's also possible to define abstract methods to force classes to implement certain requirements.
Let's say we want our traits to have sayHeight() and sayWeight() methods that return a string with the height or weight. They'd need some way to force exhibiting classes (term stolen from the PHP guide) to implement a method that returns the height and weight :
public interface IClientWeight
{
abstract int getWeight();
String sayWeight()=>getWeight().ToString();
}
public interface IClientHeight
{
abstract int getHeight();
String sayHeight()=>getHeight().ToString();
}
//Combines both traits
public interface IClientBoth:IClientHeight,IClientWeight{}
The clients now have to implement thet getHeight() or getWeight() method but don't need to know anything about the say methods.
This offers a cleaner way to decorate
SharpLab.io link for this sample.
C# language (at least to version 5) does not have support for Traits.
However, Scala has Traits and Scala runs on the JVM (and CLR). Therefore, it's not a matter of run-time, but simply that of the language.
Consider that Traits, at least at the Scala sense, can be thought of as "pretty magic to compile in proxy methods" (they do not affect the MRO, which is different from Mixins in Ruby). In C# the way to get this behavior would be to use interfaces and "lots of manual proxy methods" (e.g. composition).
This tedious process could be done with a hypothetical processor (perhaps automatic code generation for a partial class via templates?), but that's not C#.
Happy coding.
I'd like to point to NRoles, an experiment with roles in C#, where roles are similar to traits.
NRoles uses a post-compiler to rewrite the IL and inject the methods into a class. This allows you to write code like that:
public class RSwitchable : Role
{
private bool on = false;
public void TurnOn() { on = true; }
public void TurnOff() { on = false; }
public bool IsOn { get { return on; } }
public bool IsOff { get { return !on; } }
}
public class RTunable : Role
{
public int Channel { get; private set; }
public void Seek(int step) { Channel += step; }
}
public class Radio : Does<RSwitchable>, Does<RTunable> { }
where class Radio implements RSwitchable and RTunable. Behind the scenes, Does<R> is an interface with no members, so basically Radio compiles to an empty class. The post-compilation IL rewriting injects the methods of RSwitchable and RTunable into Radio, which can then be used as if it really derived from the two roles (from another assembly):
var radio = new Radio();
radio.TurnOn();
radio.Seek(42);
To use radio directly before rewriting happened (that is, in the same assembly as where the Radio type is declared), you have to resort to extensions methods As<R>():
radio.As<RSwitchable>().TurnOn();
radio.As<RTunable>().Seek(42);
since the compiler would not allow to call TurnOn or Seek directly on the Radio class.
There is an academic project, developed by Stefan Reichart from the Software Composition Group at the University of Bern (Switzerland), which provides a true implementation of traits to the C# language.
Have a look at the paper (PDF) on CSharpT for the full description of what he has done, based on the mono compiler.
Here is a sample of what can be written:
trait TCircle
{
public int Radius { get; set; }
public int Surface { get { ... } }
}
trait TColor { ... }
class MyCircle
{
uses { TCircle; TColor }
}
Building on what Lucero suggested, I came up with this:
internal class Program
{
private static void Main(string[] args)
{
var a = new ClientA("Adam", 68);
var b = new ClientB("Bob", 1.75);
var c = new ClientC("Cheryl", 54.4, 1.65);
Console.WriteLine("{0} is {1:0.0} lbs.", a.Name, a.WeightPounds());
Console.WriteLine("{0} is {1:0.0} inches tall.", b.Name, b.HeightInches());
Console.WriteLine("{0} is {1:0.0} lbs and {2:0.0} inches.", c.Name, c.WeightPounds(), c.HeightInches());
Console.ReadLine();
}
}
public class Client
{
public string Name { get; set; }
public Client(string name)
{
Name = name;
}
}
public interface IWeight
{
double Weight { get; set; }
}
public interface IHeight
{
double Height { get; set; }
}
public class ClientA : Client, IWeight
{
public double Weight { get; set; }
public ClientA(string name, double weight) : base(name)
{
Weight = weight;
}
}
public class ClientB : Client, IHeight
{
public double Height { get; set; }
public ClientB(string name, double height) : base(name)
{
Height = height;
}
}
public class ClientC : Client, IWeight, IHeight
{
public double Weight { get; set; }
public double Height { get; set; }
public ClientC(string name, double weight, double height) : base(name)
{
Weight = weight;
Height = height;
}
}
public static class ClientExt
{
public static double HeightInches(this IHeight client)
{
return client.Height * 39.3700787;
}
public static double WeightPounds(this IWeight client)
{
return client.Weight * 2.20462262;
}
}
Output:
Adam is 149.9 lbs.
Bob is 68.9 inches tall.
Cheryl is 119.9 lbs and 65.0 inches.
It isn't quite as nice as I'd like, but it's not too bad either.
This is really an suggested extension to Lucero's answer where all the storage was in the base class.
How about using dependency properties for this?
This would have the effect of making the client classes light weight at run time when you have many properties that are not always set by every descendant. This is because the values are stored in a static member.
using System.Windows;
public class Client : DependencyObject
{
public string Name { get; set; }
public Client(string name)
{
Name = name;
}
//add to descendant to use
//public double Weight
//{
// get { return (double)GetValue(WeightProperty); }
// set { SetValue(WeightProperty, value); }
//}
public static readonly DependencyProperty WeightProperty =
DependencyProperty.Register("Weight", typeof(double), typeof(Client), new PropertyMetadata());
//add to descendant to use
//public double Height
//{
// get { return (double)GetValue(HeightProperty); }
// set { SetValue(HeightProperty, value); }
//}
public static readonly DependencyProperty HeightProperty =
DependencyProperty.Register("Height", typeof(double), typeof(Client), new PropertyMetadata());
}
public interface IWeight
{
double Weight { get; set; }
}
public interface IHeight
{
double Height { get; set; }
}
public class ClientA : Client, IWeight
{
public double Weight
{
get { return (double)GetValue(WeightProperty); }
set { SetValue(WeightProperty, value); }
}
public ClientA(string name, double weight)
: base(name)
{
Weight = weight;
}
}
public class ClientB : Client, IHeight
{
public double Height
{
get { return (double)GetValue(HeightProperty); }
set { SetValue(HeightProperty, value); }
}
public ClientB(string name, double height)
: base(name)
{
Height = height;
}
}
public class ClientC : Client, IHeight, IWeight
{
public double Height
{
get { return (double)GetValue(HeightProperty); }
set { SetValue(HeightProperty, value); }
}
public double Weight
{
get { return (double)GetValue(WeightProperty); }
set { SetValue(WeightProperty, value); }
}
public ClientC(string name, double weight, double height)
: base(name)
{
Weight = weight;
Height = height;
}
}
public static class ClientExt
{
public static double HeightInches(this IHeight client)
{
return client.Height * 39.3700787;
}
public static double WeightPounds(this IWeight client)
{
return client.Weight * 2.20462262;
}
}
This sounds like PHP's version of Aspect Oriented Programming. There are tools to help like PostSharp or MS Unity in some cases. If you want to roll-your-own, code-injection using C# Attributes is one approach, or as suggested extension methods for limited cases.
Really depends how complicated you want to get. If you are trying to build something complex I'd be looking at some of these tools to help.
Related
I have a class Foo, which is a base class for a lot other classes such as Bar and Baz, and I want to do some calculation within Foo using the static members in Bar and Baz, as shown below:
public class Foo{
public result1 {
get{
return field1;
}
}
}
public class Bar : Foo{
public const int field1 = 5;
}
public class Baz : Foo{
public const int field1 = 10;
}
The only solution I can think of is wrap all the fields in a container, add an extra identifier for each object, and use a function to return the fields, like so
Bar : Foo{
public readonly int id = 0;
public static Wrapper wrapper;
}
public Wrapper GetWrapper(int id){
switch(id){
case 0:
return Bar.wrapper;
}
}
However, as you can see, I need to maintain one additional class and function, and I'd rather not to fragment my code. Is there any alternative?
Edit
What you are asking for, i.e. accessing a static or const value in a subclass from a base class is technically possible, but doing so will violate the principals of good SOLID OO design. Also, since you will need an instance of a specific subclass in order to be able to 'reason over' the type of the subclass in order to obtain the appropriate field1, there's little point approaching this problem statically.
Instead, the common, cleaner, approach here is to use subtype polymorphicism which will allow a calling method in the base class, or a method in an external class altogether, to access the appropriate value for 'field1' based on the subclass. This allows control over the value returned to remain inside the appropriate subclasses (i.e. as per your words, the code won't become "fragmented").
Alternative solution using subclass polymorphicism (recommended)
A subclass polymorphic approach (i.e. with the virtual/abstract and override keywords) will allow you to encapsulate the retrieval of a value (or object) which is customizable for each subclass. Here, the abstraction remains conceptually at "give me an integer value", and then the sub-class-specific implementations of 'how' to return the value can be abstracted (hidden) from the caller. Also, by marking the base property as abstract, you will force all subclasses to implement the property, so that the requirement to provide a value isn't forgotten about.
i.e. I would recommend a polymorphic approach like this:
public abstract class Foo
{
public abstract int Result { get; }
}
public class Bar : Foo
{
// This is implementation specific. Hide it.
private const int field1 = 5;
public override int Result
{
get { return field1; }
}
}
public class Baz : Foo
{
public override int Result
{
// No need for this implementation to be a constant ...
get { return TheResultOfAReallyComplexCalculationHere(); }
}
}
If there are no other reusable concrete methods on the base class Foo, then you could also model the abstraction as an interface, with the same effect:
public interface IFoo
{
int Result { get; }
}
Approaching this problem without polymorphicism (Not recommended)
Any compile-time attempt to access static fields on subclasses will typically require code somewhere to switch (or map) on the actually type of the subclass instance, e.g.:
public class Foo
{
public int result1
{
get
{
switch(this.GetType().Name)
{
case "Bar":
return Bar.field1;
case "Baz":
return Baz.field1;
default:
return 0;
}
}
}
public void MethodRequiringValueFromSubclass()
{
Console.WriteLine(result1);
}
}
public class Bar : Foo
{
public const int field1 = 5;
}
public class Baz : Foo
{
public const int field1 = 10;
}
The problem here is that the Open and Closed principal is violated, as each time a new sub class is added, the result1 method would need to be changed to accomodate the new class.
I'd suggest to use abstract function rather that using static member.
public abstract class Foo{
public result1 {
get{
return get_field1();
}
}
protected abstract int get_field1();
}
public class Bar : Foo{
public const int field1 = 5;
protected override int get_field1() { return field1;}
}
public class Baz : Foo{
public const int field1 = 10;
protected override int get_field1() { return field1;}
}
You either add constructor parameter to your Foo class which can be passed from inheritors, thus you don't need extra classes also you'll have less coupling
public class Foo
{
private readonly int _field1;
public Foo(int field1)
{
_field1 = field1;
}
}
or you can use it exactly from inheritors type as static/const members are members of class type
public class Foo
{
public result1
{
get
{
return Bar.field1;
}
}
}
but this gives your code less flexibility and more coupling.
Also you have an option by using virtual properties which you can implement in derrived classes and use in base:
public class Foo
{
public virtual int Field { get { return 0; } }
}
Instead of making Foo abstract as other answers suggested you can use virtual and override result1 in each child class
public class Foo
{
public virtual int result1 { get; }
}
public class Bar : Foo
{
public const int field1 = 5;
public override int result1
{
get { return field1; }
}
}
public class Baz : Foo
{
public const int field1 = 10;
public override int result1
{
get { return field1; }
}
}
If you want default result1 to return something else than 0 you can give it another value
public class Foo
{
public virtual int result1 { get; } = -1;
}
I always feel like a jerk when I answer my own question... Yet didn't see what I was expecting so I might as well just share what I've got after a night of mind boggling.
The reason I don't want to make the calculation abstract/virtual is because there are many subclasses and the formula is the same for all of them. I just refuse to type the same code 10-20 times repeatedly.
Couldn't make the static fields non static either, as they should be accessible at a class level plus they can get big, and they are the same for all instances.
The only solution I can come up that minimizes code fragment is something like this
public class Foo {
public class Wrapper {
Fields...
}
public Wrapper wrapper; // reference
public int result1 { get; }
}
public class Bar : Foo {
public static Wrapper subclassWrapper; // put in the implementation
public Bar() : base(){
wrapper = subclassWrapper;
}
}
So each instance now needs to hold an extra reference, however I don't need to keep a function. The wrapper is kept within the base class so it is less fragmented.
I am designing a system that works with multiple data sources. These data sources have identifiers that can have certain checks done on them when they are created. It permits getting historical and real time data. My current abstraction involves three base classes.
The DataSource class is responsible for connections to services and maintaining esoteric things for that data source including how to open and close connections and thread safety concerns on a case by case basis.
The DataContext class is responsible for which values to get, be they realtime or historic and on what date etc, there may be other contexts where you could desire mixed historic dates (parameterized) among other things which is why I want to use polymorphism to accomplish this.
The Identifier class is responsible for parsing strings and validation against regular expressions to make sure that the string identifier that gets passed in is at least valid to some degree. It is also used for the type safety, because an identifier for one data source is not allowed to be passed into another data source.
See example code below;
public class DataSource
{
// base class for all data sources
// maintains connections opening and closing plus
// thread safety concerns
}
public class FooDataSource : DataSource { }
public class BarDataSource : DataSource { }
public abstract class Identifier
{
public string Value { get; internal set; }
public Identifier(string value)
{
Value = value;
}
}
public class FooIdentifier : Identifier
{
public FooIdentifier(string value) : base(value)
{
// checks go here on the string that comes in
// specific to the foo data source
}
}
public class BarIdentifier : Identifier
{
public BarIdentifier(string value) : base(value)
{
// checks on the string values that come in for the Bar
// source
}
}
public abstract class DataContext<TIdentifier> where TIdentifier : Identifier
{
public abstract double GetValue(TIdentifier id);
}
public abstract class FooDataContext : DataContext<FooIdentifier> { }
public abstract class BarDataContext : DataContext<BarIdentifier> { }
public class FooRealTimeDataContext : FooDataContext
{
public override double GetValue(FooIdentifier id)
{
// real implementation here
return -1;
}
}
public class BarRealTimeDataContext : BarDataContext
{
public override double GetValue(BarIdentifier id)
{
// real implementation here
return -10;
}
}
[TestFixture]
public static class TestMe
{
[Test]
public static void MyTest()
{
// create the data context (to get data from)
var ctx = new FooRealTimeDataContext();
ctx.GetValue(new FooIdentifier("onetuhoenthuo")); // compiles (good)
// ctx.GetValue(new BarIdentifier("noetuhneoth")); // does not compile (also good)
}
}
The question (finally) is how do I create a class that actually follows OOP principals to fill in the following class shell?
public class UniversalRealTimeDataSource : DataSource<Identifier> {
public double GetValue(Identifier id) {
// there would have to be code in here that says "if(id is FooIdentifier) ... else ...
// which is (IMO) an anti-pattern so, how to avoid this?
}
}
Edit: I have been trying to keep the compile time type safety guarantees as much as possible. This would be fairly straightforward with some if(!(id is FooIdentifier)) throw exception type of code but I want to make it impossible for this to occur at compile time.
My final solution is a bit of a compromise in terms of compile time type safety. The Identifier selects its own data source from a menu of data sources (the universal data source). This prevents run-time errors unless the programmer uses the code incorrectly. Many things will probably be made private, the public layer will include all DataContext and Identifier subclasses.
public abstract class DataSource
{
// base class for all data sources
// maintains connections opening and closing plus
// thread safety concerns
// these classes will most likely be private
// maybe even within the universal data source class as inner classes
// THE TWO METHODS BELOW ARE ONLY TO BE CALLED FROM WITHIN THE UniversalDataSource CLASS
public abstract double GetRealTimeValue(Identifier id);
public abstract double GetHistoricalValue(Identifier id, DateTime asof);
}
public class FooDataSource : DataSource {
public override double GetRealTimeValue(Identifier id)
{
return -1;
// real implementation here, must be identifier type upcasting with runtime check
}
public override double GetHistoricalValue(Identifier id, DateTime asof)
{
return -2;
// real implementation here, must be identifier type upcasting with runtime check
}
}
public class BarDataSource : DataSource {
public override double GetRealTimeValue(Identifier id)
{
return -3;
// real implementation here, must be identifier type upcasting with runtime check
}
public override double GetHistoricalValue(Identifier id, DateTime asof)
{
return -4;
// real implementation here, must be identifier type upcasting with runtime check
}
}
/// <summary>
/// holds initialized references to all possible data sources
/// </summary>
public class UniversalDataSource
{
public FooDataSource FooDS { get; internal set; }
public BarDataSource BarDS { get; internal set; }
public UniversalDataSource(FooDataSource fooDs, BarDataSource barDs)
{
this.FooDS = fooDs;
this.BarDS = barDs;
}
public double GetRealTimeValue(Identifier id)
{
var specificDS = id.GetDataSource(this);
return specificDS.GetRealTimeValue(id);
}
public double GetHistoricalValue(Identifier id, DateTime asof)
{
var specificDS = id.GetDataSource(this);
return specificDS.GetHistoricalValue(id, asof);
}
}
public abstract class Identifier
{
public string Value { get; internal set; }
public Identifier(string value)
{
Value = value;
}
/// <summary>
/// returns the appropriate data source for THIS kind of identifier (abstractly)
/// </summary>
/// <param name="universalDataSource"></param>
/// <returns></returns>
public abstract DataSource GetDataSource(UniversalDataSource universalDataSource);
}
public class FooIdentifier : Identifier
{
public FooIdentifier(string value) : base(value)
{
// checks go here on the string that comes in
// specific to the foo data source
}
public override DataSource GetDataSource(UniversalDataSource universalDataSource)
{
return universalDataSource.FooDS;
}
}
public class BarIdentifier : Identifier
{
public BarIdentifier(string value) : base(value)
{
// checks on the string values that come in for the Bar
// source
}
public override DataSource GetDataSource(UniversalDataSource universalDataSource)
{
return universalDataSource.BarDS;
}
}
public abstract class DataContext
{
public UniversalDataSource DataSource { get; internal set; }
protected DataContext(UniversalDataSource dataSource)
{
DataSource = dataSource;
}
public abstract double GetValue(Identifier id);
}
public class RealTimeDataContext : DataContext {
public RealTimeDataContext(UniversalDataSource dataSource) : base(dataSource)
{
}
public override double GetValue(Identifier id)
{
return DataSource.GetRealTimeValue(id);
}
}
public class HistoricalDataContext : DataContext {
public DateTime AsOf { get; internal set; }
public HistoricalDataContext(UniversalDataSource dataSource, DateTime asof) : base(dataSource)
{
AsOf = asof;
}
public override double GetValue(Identifier id)
{
return DataSource.GetHistoricalValue(id, AsOf);
}
}
[TestFixture]
public static class TestMe
{
[Test]
public static void MyTest()
{
// create the data context (to get data from)
var ds = new UniversalDataSource(
new FooDataSource(),
new BarDataSource()
);
var realTimeDataContext = new RealTimeDataContext(ds);
var historicalDataContext = new HistoricalDataContext(ds, DateTime.MinValue);
var fooId = new FooIdentifier("onetuhoenthuo");
var barId = new BarIdentifier("onetuhoenthuo");
// testing dispatch
Assert.AreEqual(-1, realTimeDataContext.GetValue(fooId));
Assert.AreEqual(-2, historicalDataContext.GetValue(fooId));
Assert.AreEqual(-3, realTimeDataContext.GetValue(barId));
Assert.AreEqual(-4, historicalDataContext.GetValue(barId));
}
}
Perhaps this solution will clear up what I have been trying to do from the start. The reason for the data context class to even exist is due to working with financial data, weekends and holidays can cause NA values and shuffling dates for different identifiers may make sense in a historical data request setting. These strategies will be implemented polymorphically by overriding the GetValue methods.
I have a series of objects, lets call them buildings, that each share certain properties that are static for that building, but different for each building, such as price. I assumed that the best way to implement this was to create an abstract superclass with the shared price attribute and set the values in each subclass, but I cannot figure out how to get this to work. Here is an example of something I have tried:
using System;
public abstract class Buildings
{
internal static int price;
internal static int turnsToMake;
}
using System;
public class Walls : Buildings
{
public Walls()
{
price = 200;
turnsToMake = 5;
}
}
This works fine for construction, but if I want to check the price before creating it (to check if the player has enough money) then it just returns a null value. I'm sure that it is is a super simple fix, but I can't figure it out. Any help?
There is a "patchy" yet simple solution that's worth to consider. If you define your base class as a Generic class, and in deriving classes set T as the class itself, It will work.
This happens because .NET statically defines a new type for each new definition.
For example:
class Base<T>
{
public static int Counter { get; set; }
public Base()
{
}
}
class DerivedA : Base<DerivedA>
{
public DerivedA()
{
}
}
class DerivedB : Base<DerivedB>
{
public DerivedB()
{
}
}
class Program
{
static void Main(string[] args)
{
DerivedA.Counter = 4;
DerivedB.Counter = 7;
Console.WriteLine(DerivedA.Counter.ToString()); // Prints 4
Console.WriteLine(DerivedB.Counter.ToString()); // Prints 7
Console.ReadLine();
}
}
Don't use static. Static says that all instances of Building have the same value. A derived class will not inherit its own copy of the statics; but would always modify the base class statics. In your design there would only be one value for price and turnsToMake.
This should work for you:
public abstract class Buildings
{
internal int price;
internal int turnsToMake;
}
However, most people don't like using fields these days and prefer properties.
public abstract class Buildings
{
internal int Price { get; set; }
internal int TurnsToMake { get; set; }
}
I want to check the price before creating it […]
I suppose that's how you got to static fields; however, static and virtual behaviour cannot be combined. That is, you would have to re-declare your static fields for each subclass. Otherwise, all your subclasses share the exact same fields and overwrite each others' values.
Another solution would be to use the Lazy<T, TMetadata> type from the .NET (4 or higher) framework class library:
public class Cost
{
public int Price { get; set; }
public int TurnsToMake { get; set; }
}
var lazyBuildings = new Lazy<Buildings, Cost>(
valueFactory: () => new Walls(),
metadata: new Cost { Price = 200, TurnsToMake = 5 });
if (lazyBuildings.Metadata.Price < …)
{
var buildings = lazyBuildings.Value;
}
That is, the metadata (.Metadata) now resides outside of the actual types (Buildings, Walls) and can be used to decide whether you actually want to build an instance ( .Value) of it.
(Thanks to polymorphism, you can have a whole collection of such "lazy factories" and find a building type to instantiate based on the metadata of each factory.)
Building on Uri Abramson's answer above:
If you need to access the static property from within the Base class, use reflection to get the value from T. Also, you can enforce that Base must be inherited using T of the derived type.
e.g.
class Base<T> where T : Base <T> {
static int GetPropertyValueFromDerivedClass<PropertyType>(BindingFlags Flags = BindingFlags.Public | BindingFlags.Static, [CallerMemberName] string PropertyName = "")
{
return typeof(T).GetProperty(PropertyName, Flags)?.GetValue(null);
}
static int Counter{ get => GetPropertyValueFromDerivedClass(); }
}
static int DoubleCounter{ return Counter*2; } //returns 8 for DerivedA and 14 for DerivedB
}
If you have a better way to do this, please post.
Not as easy for the inheritor, but workable...
public abstract class BaseType
{
public abstract contentType Data { get; set; }
}
public class InheritedType : BaseType
{
protected static contentType _inheritedTypeContent;
public override contentType Data { get => _inheritedTypeContent; set => _inheritedTypeContent = value; }
}
I have a class Voucher:
public abstract class Voucher
{
public int Id { get; set; }
public decimal Value { get; protected set; }
public const string SuccessMessage = "Applied";
}
and a subclass GiftVoucher
public class GiftVoucher : Voucher
{
}
and another subclass DiscountVoucher
public class DiscountVoucher : Voucher
{
public decimal Threshold { get; private set; }
public string FailureMessage { get { return "Please spend £{0} to use this discount"; } }
}
You can see that DiscountVoucher has a couple of specific properties Threshold and FailureMessage that respectively represent the amount of money you need to spend to get the discount and the failure message to display if the user has not spent that money.
My question is this. I have a collection of Voucher objects and what I don't want to do in my code is something like this
if (voucher is DiscountVoucher)
{
// cast voucher to a DiscountVoucher and then call the specific methods on it
}
because this is not at all maintainable. At the same time I did not want to put those specific methods in the Voucher abstract class because they are not applicable to all types of Vouchers. Does anyone know how to design this functionality?
In the general case: No!
Handling specialized scenarios in a general code flow without any code handling the special cases does not work.
However in some cases you can cheat a little bit. You can implement virtual methods in the abstract base class that provides a default "nothing" implementation.
Could be a method that returns null, 0 or just does nothing.
In this case
public virtual string FailureMessage { get { return string.Empty; } }
might be a reasonable implementation.
I guess that your implementation looks a lot like the template method pattern. Then it is perfectly normal to have void implementations for steps not applicable to certain implementations.
Well what you've got here is a version of the strategy pattern. I don't think there's any getting away from eventually having to decide if you have one type of voucher or another but you can limit the number of variations - voucher categories if you will - using interfaces.
For instance you might end up with five vouchers which implement interfaces called 'StandardVoucher' and three called 'DiscountVoucher' but instead of having to handle eight cases you now just have two.
The interfaces can cover a range of vouchers showing the available methods without worrying about the details of each vouchers implementation.
No, you cannot, because iterating over more general objects and then calling specific methods would require using polymorphism to have dedicated functionality in each subclass. Without a method in the superclass to override, you have no way to obtain what you want.
I think you're right to be suspicious of the code you describe.
My first thought is that if members of DiscountVoucher aren't broad enough to exist as virtual or abstract in Voucher, then a function that takes a Voucher as a parameter should not touch them.
So, to solve the problem, I'd say you could do one of two things:
First, you could add virtual methods or properties to Voucher, e.g.
public abstract class Voucher
{
public int Id { get; set; }
public decimal Value { get; protected set; }
public const string SuccessMessage = "Applied";
public decimal Threshold { get { return 0.0; } }
public string FailureMessage { get { return ""; } }
}
Second, you can add methods that do what you expect for each Voucher. You've grouped them together as vouchers, so think about what they have in common. If, say, GiftVoucher and DiscountVoucher are both doing their own calculations to determine if they apply to the current ShoppingCart, then you could have a Voucher method called isValid() to detect this. For example,
public abstract class Voucher
{
public bool isValid(ShoppingCart sc);
public string FailureMessage { get { return "This voucher does not apply"; } }
// ...
}
public class DiscountVoucher : Voucher
{
private decimal Threshold;
public override bool isValid(ShoppingCart sc)
{
return (sc.total >= Threshold);
}
public override string FailureMessage
{
get { return FormatString("Please spend £{0} to use this discount", Threshold); }
}
There are just cases where you will have to cast. Here I would implement a general error checking mechanism:
public abstract class Voucher
{
public int Id { get; set; }
public decimal Value { get; protected set; }
public virtual string SuccessMessage { get { return "Applied"; } }
public virtual string FailureMessage { get { return String.Empty; } }
public virtual bool Ok { get { return true; } }
}
public class GiftVoucher : Voucher { }
public class DiscountVoucher : Voucher
{
public decimal Threshold { get; private set; }
public override string FailureMessage { get { return "Please spend £{0} to use this discount"; } }
public override bool Ok { get { return Value >= Threshold; } }
}
You can then test the integrity of a voucher of any type without casting:
if (voucher.Ok) {
Console.WriteLine(voucher.SuccessMessage);
} else {
Console.WriteLine(voucher.FailureMessage);
}
As a general rule, try to let objects do their own stuff (here to test if they are OK) instead of doing it from the "outside". Even the fact, that no error can occur in a GiftVoucher needs not to be known by the "outer world".
I have a 3rd party badly designed library that I must use.
It has all sorts of types it works with, we'll call them SomeType1, SomeType2 etc.
None of those types share a common base class but all have a property named Value with a different return type.
All I want to do is to be able to Mixin this class so I'll be able to call someType1Instance.Value and someType2Instance.Value without caring what the concreate type it is and without caring what the return type is (I can use object).
So my code is currently:
public interface ISomeType<V>
{
V Value {get; set;}
}
public interface ISomeTypeWrapper
{
object Value { get; set; }
}
public class SomeTypeWrapper<T> : ISomeTypeWrapper
where T : ISomeType<???>
{
T someType;
public SomeTypeWrapper(T wrappedSomeType)
{
someType = wrappedSomeType
}
public object Value
{
get { return someType.Value; }
set { someType.Value = value != null ? value : default(T); }
}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
The problem is that I don't know what T might be until runtime due to the fact that I get a dictionary of objects.
I can iterate the dictionary and use reflection to create a SomeWrapperType on runtime but I would like to avoid it.
How can I mixin the concreate type of SomeType to ISomeType?
How can I know what V type parameter is? (wish I had typedefs and decltype like in c++)
How can I, with the minimum of use of reflection possible Mixin those classes with the interface/base class?
You could try the Duck Typing Extensions for Windsor. It means you will need to register each of your types.
container
.Register(Component.For(typeof(SomeType1)).Duck<ISomeType>())
.Register(Component.For(typeof(SomeType2)).Duck<ISomeType>());
You could probably use linq and the register AllTypes syntax to reduce code if the names are similar.
Alternatively in the short term create a factory which can return you the objects you need, implement a concrete object for each type. No you are using the interface you can remove the factory at a later date and replace it with something else with minimal impact:
public class SomeTypeWrapperFactory
{
public ISomeType<int> CreateWrapper(SomeType1 someType1)
{
return new SomeType1Wrapper(someType1);
}
public ISomeType<string> CreateWrapper(SomeType2 someType2)
{
return new SomeType2Wrapper(someType2);
}
}
public class SomeType1Wrapper : ISomeType<int> { ... }
public class SomeType2Wrapper : ISomeType<int> { ... }
Regardless of how you implement the wrapper, be the individually or using a god like class you have the ability to change how the wrapping is done and keep the rest of your code clean.
Why SomeTypeWrapper but not SomeObjectWrapper?
public class SomeObjectWrapper : ISomeType
{
Object _someObject;
PropertyInfo _valuePropertyInfo;
public SomeObjectWrapper(Object wrappedSomeObject)
{
_someObject = wrappedSomeObject;
_valuePropertyInfo = _someObject.GetType().GetProperty("Value", System.Reflection.BindingFlags.Public);
}
public object Value
{
get { return _valuePropertyInfo.GetValue(_someObject, null); }
set { _valuePropertyInfo.SetValue(_someObject, value, null); }
}
}
Edited With .NET 3.5 using LinFu
You may use LinFu instead of Castle. However, you would be using reflection anyway, both with Castle's and with Linfu's DynamicProxy, only hidden in the guts of the libraries instead of being exposed in your code. So if your requirement to avoid the use of reflection is out of performance concerns, you wouldn't really avoid it with this solution.
In that case I would personally choose Orsol's solution.
However: here's an example with LinFu's ducktyping.
public interface ISomeType {
object Value{get; set;}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeWrapperFactory
{
public static ISomeType CreateSomeTypeWrapper(object aSomeType)
{
return aSomeType.CreateDuck<ISomeType>();
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
foreach(var o in someTypes)
{
Console.WriteLine(SomeTypeWrapperFactory.CreateSomeTypeWrapper(o).Value);
}
Console.ReadLine();
}
}
Since you don't know the type of the SomeType's until runtime, I would not use mixins, but the visitor pattern (I know this doesn't answer the question on how to use mixins for this, but I just thought I'd throw in my 2 cents).
With .NET 4 using dynamic
See Bradley Grainger's post here on using c#4's dynamic keyword to implement the visitor pattern.
In your case, reading all the "Value" properties from your dictionary of SomeType's could work like this:
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeVisitor
{
public void VisitAll(object[] someTypes)
{
foreach(var o in someTypes) {
// this should be in a try-catch block
Console.WriteLine(((dynamic) o).Value);
}
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
var vis = new SomeTypeVisitor();
vis.VisitAll(someTypes);
}
}