I have the following objects :
Formula
Stock
Counter
etc ...
all these objects are called indicators and have common properties (Id, Name, Value...).
Each entity has its own properties:
Formula: FormulaExpression, FormulaCode, OperandsList ...
Stock: StockValue, StockLimit...
Counter: CounterIndex...
etc ...
So logically, i have to make indicator class containing the common properties, and for each entity i have to create a class that inherits from indicator.
Formula is a special indicator that can contain any type of indicators. The formula's indicators are named operands.
the operand object has the following properties:
operandId, operandCode, operandIndex
when i want to list the formula operands, i want to get objects which inherit from indicator, operand and entity type (create an object that have indicators properties, operand properties and stock properties for example)
which design pattern or which architecture allows me to have this behaviour?
To explain more the problem
The entities (Formula, stock, Counter..) are Indicators and not necessary Operands, Operands are Indicators too. Object Indicator is the primitive type of entities, we can create an Indicator and then decorate it to become a Formula for example and than decorate it to become an Operand when it is added to another Formula.
The best way to do it would be to use an expando object that is filled by each operand using polymorphic dispatch. The expando object lets you add custom properties, and the polymorphic dispatch lets you close your code against operands change.
You would start by using a base class for the Operand that contains your basic elements
public abstract class Operand
{
public int Id { get; set; }
public string Name { get; set; }
public dynamic BuildObject()
{
dynamic o = new ExpandoObject();
o.Id = Id;
o.Name = Name;
AddPropertiesToObject(o);
return o;
}
protected internal abstract void AddPropertiesToObject(dynamic o);
}
Then adding a new Operand type is very easy since you can control what you will add to it independently:
public class Stock : Operand
{
public double StockValue { get; set; }
protected internal override void AddPropertiesToObject(dynamic o)
{
// I decided to ignore the base class Id and Name
// adding them would be trivial, but may not be what you need since
// it would overwrite the base values...
// To add them you would have to wrap this virtual method call with
// a call to a function doing the insertion in the base class
o.StockValue = StockValue;
}
}
The Formula object would simply iterate on the contained operands and call their AddPropertiesToObject in turn (of course it can also add its own data but for the example I didn't include any)
public class Formula : Operand
{
public List<Operand> InnerOperands { get; set; }
protected internal override void AddPropertiesToObject(dynamic o)
{
foreach (var op in InnerOperands)
{
op.AddPropertiesToObject(o);
}
}
}
What I posted here may looks like a lot of code but it's actually very straightforward.
Most of the properties and constructors are there to simplify the script in the main function.
The base concept is to create a Generic Class for the operands that contains a reference to the base Indicator object it's created from.
Test this code in an empty project and it'll be very easy to understand from the output.
class Indicator{
// Common properties
}
class Counter : Indicator{
public int CounterIndex;
public Counter(int cI){
CounterIndex = cI;
}
public void Print()
{
Console.WriteLine("CounterIndex: {0}", CounterIndex);
}
}
class Operand{
// Common operand properties
}
class Operand<T> : Operand{
public T BaseIndicator;
public Operand(T bI){
BaseIndicator = bI;
}
}
class Formula : Indicator{
public string FormulaExpression;
public int FormulaCode;
public List<Operand> OperandsList = new List<Operand>();
public Formula(string fE, int fC){
FormulaExpression = fE;
FormulaCode = fC;
}
public void Print ()
{
Console.WriteLine ("FormulaExpression: {0}; FormulaCode: {1}",
FormulaExpression, FormulaCode);
if (OperandsList.Count == 0) {
return;
}
Console.WriteLine("Begin Operands: ");
foreach(Operand o in OperandsList){
if(o is Operand<Counter>){
Operand<Counter> cO = o as Operand<Counter>;
cO.BaseIndicator.Print();
}else if(o is Operand<Formula>){
Operand<Formula> fO = o as Operand<Formula>;
fO.BaseIndicator.Print();
}else{
// I'ts a simple Indicator
}
}
Console.WriteLine("End Operands");
}
}
class MainClass
{
public static void Main (string[] args)
{
Counter c1 = new Counter(2);
Counter c2 = new Counter(3);
Formula f1 = new Formula("a + b", 7);
Formula f2 = new Formula("a * b", 10);
Formula f = new Formula("a ^ b", 32);
f.OperandsList.Add(new Operand<Counter>(c1));
f.OperandsList.Add(new Operand<Formula>(f1));
f.OperandsList.Add(new Operand<Counter>(c2));
f.OperandsList.Add(new Operand<Formula>(f2));
f.Print();
Console.ReadLine();
}
}
Related
I have 2 classes which are inherited in this manner
public class PartsParent
{
}
public class PartsCar : PartsParent
{
public int WheelRadius { get; set; }
public int Price { get; set; }
}
public class PartsBike : PartsParent
{
public int Length { get; set; }
public int Weight { get; set; }
public int Price { get; set; }
}
And i have a function that accepts the class PartsParent as parameter and how can i convert this as partsCar / as PartsBike inside the function and access properties like Price WheelRadius etc?
private int PriceCollection(PartsParent mainObject)
{
int _price=0;
mainObject.OfType(PartsCar).Price;// something similar??
return _price;
}
Well, you are trying to cast a parent type to a child type, that is not really possible, why ?
The answer is that the parent P you are trying to cast to child C1 can be actually and originally of type C2, so the cast would be invalid.
The best way to explain this is a phrase that I read somewhere here on stackoverflow
You can't cast a mammal into a dog - it might be a cat.
You can't cast a food into a sandwich - it might be a cheeseburger.
What you can do though to turn around this situation is something like this :
(mainObject is PartsCar) ? (PartsCar)mainObject : mainObject
Which is equivalent to :
mainObject as PartsCar
Then access mainObject's cast result using the null coalescing operator (because if as fails, the cast result will be null instead of throwing an Exception).
The generic method OfType<T> that you tried to use is an extension method that can be used with objects of type IEnumerable<T'> , which I guess is not your case.
The idea of inheritance is to group up what is common in a super class, and leave other specific details to sub-classes. So if a property, say Price, is excepted from all sub-classes, then it should be declared in the super class.
However, if you still want to use it this way, then what are you looking for is:
int _price = ((PartsCar)mainObject).Price;
However, what if the object was of some other class, say PartsGift that inherits from PartsParent, but does not have a price? Then it will crash.
You almost really need to check your design.
BTW, if you want to check if an object is really of a specific class, then you can use is.
int number = 1;
object numberObject = number;
bool isValid = numberObject is int; // true
isValid = numberObject is string; // false
You can use is keyword to check the type and as keyword to convert to the target child type as following.
if (mainObject is PartsCar)
{
var partscar = mainObject as PartsCar;
// Do logic related to car parts
}
else if (mainObject is PartsBike)
{
var partsbike = mainObject as PartsBike;
// Do logic related to bike parts.
}
It's possible if you separate uncommon properties your code into block:
if (mainObject is PartsCar)
{
//Seprated code for PartsCar
// WheelRadius...
//Price...
}
else if (mainObject.GetType() == typeof(PartsBike))
{
//Seprated code for PartsBike
//Length
//Weight
//Price
}
I'd like to compare two custom class objects of the same type. The custom class being compared has a List property which is filled with items of another custom type. Is this possible by inheriting IEquatable?
I couldn't figure out how to make this work by modifying MSDN's code to compare class objects containing List properties of a custom type.
I did successfully derive from the EqualityComparer class to make a separate comparison class (code below), but I'd like to implement the comparison ability in the actual classes being compared. Here's what I have so far:
EDIT: This doesn't work after all. My apologies - I've been working on this awhile and I may have pasted incorrect example code. I'm working on trying to find my working solution...
class Program
{
static void Main(string[] args)
{
// Test the ContractComparer.
Contract a = new Contract("Contract X", new List<Commission>() { new Commission(1), new Commission(2), new Commission(3) });
Contract b = new Contract("Contract X", new List<Commission>() { new Commission(1), new Commission(2), new Commission(3) });
ContractComparer comparer = new ContractComparer();
Console.WriteLine(comparer.Equals(a, b));
// Output returns True. I can't get this to return
// True when I inherit IEquatable in my custom classes
// if I include the list property ("Commissions") in my
// comparison.
Console.ReadLine();
}
}
public class Contract
{
public string Name { get; set; }
public List<Commission> Commissions { get; set; }
public Contract(string name, List<Commission> commissions)
{
this.Name = name;
this.Commissions = commissions;
}
}
public class Commission
{
public int ID;
public Commission(int id)
{
this.ID = id;
}
}
public class ContractComparer : IEqualityComparer<Contract>
{
public bool Equals(Contract a, Contract b)
{
//Check whether the objects are the same object.
if (Object.ReferenceEquals(a, b)) return true;
//Check whether the contracts' properties are equal.
return a != null && b != null && a.Name.Equals(b.Name) && a.Commissions.Equals(b.Commissions);
}
public int GetHashCode(Contract obj)
{
int hashName = obj.Name.GetHashCode();
int hashCommissions = obj.Commissions.GetHashCode();
return hashName ^ hashCommissions;
}
}
You have to implement some kind of comparer for Commission, e.g. by implementing Commission : IEquatable<Commission>, then use it:
... && a.Commissions.SequenceEqual(b.Commissions)
I have an object having the following structure:
public class StockData
{
public string Name { get; set; }
public double Change { get; set; }
public DateTime LastUpdate { get; set; }
public WorkflowStatus Status { get; set; }
}
The Workflow status enum is defined as following:
public enum WorkflowStatus
{
PendingCoverage,
PendingCompliance,
Approved,
Rejected
}
Issue:
I have a grid (wpf) which binds all StockData to it and I have set a grouping on the Status field. I want the groups to be appearing in the grid as it's defined in the order of WorkflowStatus enum. This works absolutely fine and data is grouped in the order as it's defined inside the enum i.e first group is Pendingcoverage and the last is Rejected.
Now I want to remove this enum and introduce an object graph instead of the enum..which means there will be a base class called WorkflowStatus and 4 derived class called PendingCoverage, PendingCompliance, Approved and Rejected. Each derived class will be overiding the ToString property and returning an appropriate string.
Now, this does't work. For some reason it's not able to establish which group should come first and which should come subsequently. Question is how will I implement IComparable in this scenario. Should I implement IComparable (or something else) on StockData or on each individual WorkflowStatus object, and yes then how? Also why does this work in the case of enum and not in the case of an object?
Create your base class and add an abstract Order property to it that all sub classes must implement. Basically an integer which specifies their ordering.
You can also implement IComparable on your abstract class so that if compares objects based on their order property.
public abstract class WorkStatus : IComparable<WorkStatus> {
public abstract int Order { get; }
public int CompareTo(WorkStatus w)
{
if(w.Order < this.Order)
return 1;
if(w.Order > this.Order)
return -1;
return 0;
}
}
For each implementation, give them a different Order value.
public class FirstStatus : WorkStatus {
public override int Order {get { return 1; } }
}
public class SecondStatus : WorkStatus {
public override int Order { get { return 2; } }
}
Assuming your WPF grid is just applying a standard OrderBy query, then if should work as follows.
//LINQPAD SNIPPET
void Main()
{
List<WorkStatus> list = new List<WorkStatus>();
list.Add(new SecondStatus()); //out of order initially.
list.Add(new FirstStatus());
Console.WriteLine(list.OrderBy(x => x));
}
I'm confused as to why IComparable is required here. You have two problems. One is getting a sorted list, the other is getting the appropriate graph:
// Takes a work status and returns the appropriate graph.
static GenericBaseGraphClass GetGraph(WorkStatus input)
{
select(input.Status)
{
// Concrete derived classes go here.
}
}
// Test data.
var someWork = new List<WorkStatus>()
{
new SecondStatus(),
new FirstStatus()
};
// Sort it.
var sortedWork = someWork.Sort((x,y) => x.Status > y.Status);
// Get your object graphs.
var objectGraphs = sortedWork.Select(x => GetGraph(x.Status))
I'm learning C# and currently we're looking into OOP concepts. We've been given this question and I'm struggling to understand some parts of it.
The gist of the question is this.
Define a class named Operator.
That class should implement following methods.
IsPositive - Receives an integer type value and returns true if it
is positive, false otherwise.
IsDayOfWeek - Receives a date time value and a week day name (E.g.
Saturday) and returns true if the value represents the given week day
name, false otherwise.
GetWords - Receives a text containing words (say paragraphs) and
returns a single dimension string array with all words. An empty
string array if there is no word available in the text.
It should be able to derive from Operator class and then create objects from the derived class.
Developers are allowed to use these methods from derived class for a given type. In other words, 1st method could be used when type = ‘N’ (number), 2nd methods could be used when type is ‘D’ (date) and 3rd method could be used when type is ‘S’ (string) given. Hence, the type should be provided when instantiating the object and it should be available throughout the class operations.
I have sufficient knowledge to write the methods but what I don't understand is the part I have bold-ed. What does it mean by some method can be used when some type is given and the type should be provided when instantiating the object and it should be available throughout the class? Are they talking about Properties?
I have given it a go. Below is my code.
public class Operator
{
private int _n;
private DateTime _d;
private string _s;
public DataProcessor(int n, DateTime d, string s)
{
this.N = n;
this.D = d;
this.S = s;
}
public int N
{
set { _n = value; }
}
public DateTime D
{
set { _d = value; }
}
public string S
{
set { _s = value; }
}
public bool IsPositive()
{
//method code goes here
return false;
}
public bool IsDayOfWeek()
{
//method code goes here
return false;
}
}
I'm not sure if I'm going the right way. Can somebody please shed some light on this?
This is how I read it:
public class Operator
{
public char TypeChar { get; set; }
public Operator(char operatorType) { this.TypeChar = operatorType; }
public bool IsPositive(int N)
{
if (TypeChar != 'N')
throw new Exception("Cannot call this method for this type of Operator");
// method implementation code
}
// same for the other methods
}
public NumericOperator : Operator
{
public NumericOperator() : base('N') {}
}
Given the following code;
public class CustomControl {
private object _dataItem;
public object DataItem {
get { return _dataItem; }
set { _dataItem = value; }
}
public void Update(ref string t) {
t = "test";
}
}
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
ctrl.DataItem = anyObject.anyProperty;
string prop = anyObject.anyProperty;
ctrl.Update(ref prop);
anyObject.anyProperty = prop;
}
}
How can I change it so that the DataItem property is itself a reference, allowing you to pre-emptively set it to point to a variable thus allowing you to call Update() without any parameters.
So the Consume class would then look similar to;
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
ctrl.DataItem = anyObject.anyProperty;
ctrl.Update();
// anyObject.anyProperty has been updated to "test"
}
}
So the assigment of anyObject.anyProperty is then handled internally within CustomControl
You need to store the act of setting something to a string, so store an Action<string>:
public class CustomControl {
public Action<string> SetData { get; set; }
public void Update() {
// TODO nullity check
SetData("test");
}
}
Then Consume would look like:
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
// store {the act of setting this property of this object to a string}
ctrl.SetData = s => anyObject.anyProperty = s;
ctrl.Update();
}
}
The Update call will set anyObject.anyProperty to test. Note that you are storing specifically the act of setting this property of the particular anyObject you refer to in the assignment to SetData.
To expand on the lambda: we want to create a value of type Action<string>, that is, a thing which takes a string and returns no result. Such a thing is going to be executable code. Prior to C# 3, to create a 'value' that was executable code, we would have had to do something like:
ctrl.SetData = delegate(string s) { someObject.SomeProperty = s; };
With this syntax it's more obvious that we're creating a method - it has a { } delimited body, it has statements in it, and it's clear there is a string parameter that is used by the body.
One thing achieved by lambda expressions in C# 3 is the ability to condense this down; loosely, the whole of
// not compilable code
delegate(parameters) { body; }
can be replaced with
// not compilable code
(parameters) => body;
and in the case where there's only one parameter
// not compilable code
parameter => body;
which is what we have here: the expression assigned to ctrl.SetData is a piece of behaviour that accepts a string (s) and sets anyObject.anyProperty to that string. The real power is in the way the C# compiler can work out the types to it know we're creating an Action<string>.
At first I didn't understand what you're trying to do. What you're looking for is the Adapter or Facade pattern. That is, you have an object with a particular interface, but you need to adapt it to a different interface or provide a simpler interface.
One way to implement these patterns is to use composition and delegate the new interface to methods on the existing interface.
public interface IUpdatable<U>
{
void Update( U newValue );
}
public abstract class CustomControl<T,U> : IUpdatable<U>
where T : Control
{
private T Control { get; set; }
protected CustomControl( T control )
{
this.Control = control;
}
public abstract void Update( U newValue );
}
public class TextBoxFacade : CustomControl<TextBox,string>, IUpdatable<string>
{
public TextBoxFacade( TextBox textbox ) : base(textbox) { }
public override void Update( string newValue )
{
this.Control.Value = newValue;
}
}