I'm creating a program that allow user define formulas with on 4 basic operation: add, subtract, divide, multiple using XML. Let's take an example: User want to define formula like (a + b) x (c + d). The format of the xml as following:
EDIT I had implement this
EDIT Solve. Many thanks to Yaniv's suggestion. My solution as follow:
<xPlugins>
<xPlugin>
<Multiple>
<Add>
<Operator>
<value>1</value>
</Operator>
<Operator>
<value>2</value>
</Operator>
</Add>
<Add>
<Operator>
<value>3</value>
</Operator>
<Operator>
<value>4</value>
</Operator>
</Add>
</Multiple>
</xPlugin>
</xPlugins>
classes
//root element
public class xPlugins
{
[XmlElement("xPlugin", typeof(xPlugin))]
public xPlugin[] Plugin { get; set; }
}
public class xPlugin
{
[XmlElement("Multiple", typeof(Multiple))]
[XmlElement("Add", typeof(Add))]
[XmlElement("Subtract", typeof(Divide))]
[XmlElement("Divide", typeof(Divide))]
[XmlElement("Operator", typeof(Operand))]
public Calculator calculator { get; set; }
}
//Deseirialize ultility
static class readXML
{
public static void getObject(ref xPlugins plugins)
{
try
{
List<Type> type = new List<Type>();
type.Add(typeof(Add));
type.Add(typeof(Minus));
type.Add(typeof(Multiple));
type.Add(typeof(Subtract));
type.Add(typeof(Operator));
XmlSerializer xml = new XmlSerializer(typeof(xPlugin), type.ToArray());
FileStream fs = new FileStream("test.xml", FileMode.Open);
plugins = (xPlugins)xml.Deserialize(fs);
}
catch (Exception ex)
{
throw;
}
}
}
public abstract class Calculator
{
[XmlElement("Multiple", typeof(Multiple))]
[XmlElement("Add", typeof(Add))]
[XmlElement("Subtract", typeof(Subtract))]
[XmlElement("Divide", typeof(Divide))]
[XmlElement("Operator", typeof(Operand))]
public List<Calculator> calculators{ get; set; }
public virtual int Calculate()
{
return 0;
}
}
public class Operator : Calculator
{
public int value { get; set; }
public Operator() { }
public override int Calculate()
{
return value;
}
}
public class Add : Calculator
{
public Add() { }
public override int Calculate()
{
List<int> value = new List<int>();
foreach (Calculator calculator in calculators)
{
value.Add(calculator.Calculate());
}
return value.Sum();
}
}
public class Minus : Calculator
{
public Minus() { }
public override int Calculate()
{
int value = calculators[0].Calculate();
for (int i = 1; i < calculators.Count; i++)
{
value -= calculators[i].Calculate();
}
return value;
}
}
public class Divide: Calculator
{
public Divide() { }
public override int Calculate()
{
int value = calculators[0].Calculate();
for (int i = 1; i < calculators.Count; i++)
{
value /= calculators[i].Calculate();
}
return value;
}
}
public class Multiple : Calculator
{
public Multiple() { }
public override int Calculate()
{
int value = calculators[0].Calculate();
for (int i = 1; i < calculators.Count; i++)
{
value *= calculators[i].Calculate();
}
return value;
}
}
//running test
private void button1_Click(object sender, EventArgs e)
{
readXML.getObject(ref this.plugins);
foreach (Calculator plugin in plugins.calculators)
{
plugin.Calculate();
}
}
I just have to decorate Calculator property with:
[XmlElement("Multiple", typeof(Multiple))]
[XmlElement("Add", typeof(Add))]
[XmlElement("Subtract", typeof(Divide))]
[XmlElement("Divide", typeof(Divide))]
[XmlElement("Operator", typeof(Operand))]
I am guessing you want to use XmlSerializer.
If you need a "polymorphic" deserialization you can pass a list of types that the serializer should know about (this works if they all inherit from the same base class but not from interface).
Example:
List<Type> extraTypes = new List<Type>();
extraTypes.Add(typeof(multiple));
extraTypes.Add(typeof(add));
extraTypes.Add(typeof(substract));
extraTypes.Add(typeof(divide));
var ser = new XmlSerializer(typeof(Foo), extraTypes.ToArray());
It's explained here:
Serializing and restoring an unknown class
But there is another problem that in your XML your operand can hold two different types: an operation or an parameter (a, b, c, d) and you cannot represent it in your class.
Something that I usually see is this (I implemented only the add operation, and I am assuming the expression is numeric):
public class Expression
{
public virtual int Evaluate()
{
}
}
public class Add : Expression
{
Expression _left;
Expression _right;
public Add(Expression left, Expression right)
{
_left = left;
_right = right;
}
override int Evalute()
{
return _left.Evalute() + _right.Evalute();
}
}
public class Parameter : Expression
{
public int Value{get;set;}
public Parameter(string name)
{
// Use the name however you need.
}
override int Evalute()
{
return Value;
}
}
This way you have only one base class so everything is simpler. If that make sense I guess it won't be hard to deserialize it.
EDIT:
If the base class is Calculator (instead of Expression) the XML will look like this:
<Calculator xsi:type="Multiple">
<calculators>
<Calculator xsi:type="Add">
<calculators>
<Calculator xsi:type="Operator">
<value>12</value>
</Calculator>
</calculators>
</Calculator>
</calculators>
</Calculator>
I have created a simple calculator object and serialized it and that's what I got. If you will deserialize it you will get a calculator that will return 12.
Maybe you can use XmlAttributes to change the names of the elements in the XML or in the worst case write your own deserializer.
Related
I have created an interface that in theory should be able to return multiple generic lists of different types to provide the client with various information. When I attempt to loop through the results of the list it is only able to return first collection, can you help me to understand how I should be returning results from the following:
Interface class:
public interface IExampleInterface{}
public class ExampleType : IExampleInterface
{
public int First;
public int Last;
}
public class ExampleAmount : IExampleInterface
{
public decimal Amount;
public decimal TotalFee;
}
public class ExampleFacts : IExampleInterface
{
public bool TooLow;
public bool TooHigh;
}
Interface provider:
public class ExampleInterfaceProvider
{
private static readonly string conn = ConfigurationManager.ConnectionStrings["conn"].ConnectionString;
public static List<IExampleInterface> ExampleResults(int id)
{
//declare variables, read from database query using ExecuteReader...
var sT = new ExampleType
{
First = first;
Last = last;
}
var sA = new ExampleAmount
{
Amount = amount;
TotalFee = totalFee;
}
var sF = new ExampleFacts
{
TooHigh = tooHigh;
TooLow = tooLow;
}
var exampleResults = new List<IExampleInterface> {sT, sA, sF};
return exampleResults;
}
}
On the page I need to return the data:
foreach (dynamic item in ExampleResults(0))
{
Response.Write(item.First.ToString())
Response.Write(item.Last.ToString())
//The first two for 'sT' read fine, it breaks here
Response.Write(item.Amount.ToString())
//... And so on
}
Any help would be much appreciated,
Thanks
I think, there is no another solution except comparing implementations;
foreach (IExampleInterface item in ExampleResults(0))
{
if (item is ExampleType)
{
var exampleType = (ExampleType)item;
Response.Write(exampleType.First.ToString())
Response.Write(exampleType.Last.ToString())
}
else if (item is ExampleAmount)
{
var exampleAmount = (ExampleAmount)item;
Response.Write(exampleAmount.Amount.ToString())
}
//... And so on
}
If you are using C# 7, you can perform it as switch case
foreach (IExampleInterface item in ExampleResults(0))
{
switch (item)
{
case ExampleType c:
Response.Write(c.First.ToString());
Response.Write(c.Last.ToString());
break;
case ExampleAmount c:
Response.Write(c.Amount.ToString());
break;
default:
break;
}
//... And so on
}
You can find the documentation.
So basically, the items implementing IExampleInterface should all be written to a Response in a way that is somewhat specific to the actual type implementing the interface?
Then how about this:
public interface IExampleInterface
{
void WriteTo(Response response);
}
public class ExampleType : IExampleInterface
{
public int First;
public int Last;
public void WriteTo(Response response)
{
response.Write(First.ToString());
response.Write(Last.ToString());
}
}
public class ExampleAmount : IExampleInterface
{
public decimal Amount;
public decimal TotalFee;
public void WriteTo(Response response)
{
response.Write(Amount.ToString());
response.Write(TotalFee.ToString());
}
}
public class ExampleFacts : IExampleInterface
{
public bool TooLow;
public bool TooHigh;
public void WriteTo(Response response)
{
response.Write(TooLow.ToString());
response.Write(TooHigh.ToString());
}
}
And then:
foreach (IExampleInterface item in ExampleResults(0))
{
item.WriteTo(Response);
}
Assuming that Response is a variable holding an instance of the response rather than a static class.
I have interface that defines value and few operations:
public interface IValue<T>
{
T Value { get; }
void InteractionA(IValue<T> target);
void InteractionB(IValue<T> target);
bool Check(IValue<T> target);
}
Then i implement class based on that interface
public class DoubleValue : IValue<double>
{
public double Value { get; private set; }
public bool Check(IValue<double> target)
{
// ...
return false;
}
public void InteractionA(IValue<double> target)
{
// ...
}
public void InteractionB(IValue<double> target)
{
// ...
}
}
Now i want to make universal manipulator that operates on pool of values and uses generics (so i only write it once). Because of the way i want to use this class in the future it cannot be declared static. Moving generic type into methods also doesn't do any good.
The closest i could get is:
public class ValueManipulator<T>
{
public IEnumerable<IValue<T>> Pool { get; private set; }
public ValueManipulator(IEnumerable<IValue<T>> pool)
{
Pool = pool;
}
public void ManipulateA()
{
foreach (int i in Enumerable.Range(0, Pool.Count()))
{
IValue<T> firstValue = Pool.ElementAt(i);
foreach (IValue<T> secondValue in Pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
public void ManipulateB()
{
// ...
}
}
Main problem with this ValueManipulator class is that i need to know T of IValue used in DoubleValue (in this case double). So it looks like this:
static void Main(string[] args)
{
ValueManipulator<double> doubleManipulator = new ValueManipulator<double>();
doubleManipulator.Manipulate(ProvideDoubles());
}
private static IEnumerable<DoubleValue> ProvideDoubles()
{
yield return new DoubleValue();
yield return new DoubleValue();
yield return new DoubleValue();
}
How do i make ValueManipulator so user does not need to know what type was used in value implementation?
Well, if your ValueManipulator<T> has no state, as appears to be your case according to your code snippets, then simply make the methods generic instead of the class, that way you can leverage type inference.
public class ValueManipulator
{
public void Manipulate<T>(IEnumerable<IValue<T>> pool)
{
foreach (int i in Enumerable.Range(0, pool.Count()))
{
IValue<T> firstValue = pool.ElementAt(i);
foreach (IValue<T> secondValue in pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
}
Now you can simply do:
ValueManipulator myManipulator = new ValueManipulator();
myManipulator.Manipulate(ProvideDoubles()); //type inference will figure out T is double
If this is a valid solution then consider making ValueManipulator a static class:
ValueManipulator.Manipulate(ProvideDoubles());
P.D. Please follow advice in commentaries and change ValueType to some other name thats less confusing.
UPDATE After your latest edit to your question, where you clearly state that ValueManipulator<T> does have state, the solution seems to be implementing a static factory class:
public static class ValueManipulator
{
public static ValueManipulator<T> Create<T>(IEnumerable<IValue<T>> pool)
=> new ValueManipulator<T>(pool);
}
public class ValueManipulator<T> { ... }
And again you let type inference do its job:
var doubleManipulator = ValueManipulator.Create(ProvideDoubles());
As part of a testing library, I would like to define an interface which says 'this object knows how to initialize itself randomly'. If members of the randomly filled object are references, the random initialization should be capable of assigning null to these members.
If I was doing this for one class, the code could look like this
public class QWorker
{
double mxVal = 0;
public void fillRandomly(System.Random xRng)
{
mxVal = xRng.NextDouble();
}
}
public class QBoss
{
public QWorker mxWorker;
void fillRandomly(System.Random xRng)
{
if (xRng.Next() % 2 == 1)
x1 = null;
else
{
x1 = new QWorker();
x1.fillRandomly(xRng);
}
}
}
Now if QBoss had mulitple reference-type members, if/else would have to be done for every member. It would look ugly and could be cumbersome to maintain. To cimrcumvent, I came up with the following sample code:
public interface QIRandomizable<T> where T : new()
{
static void fillRandomly(this System.Random xThis, ref T xRef); // XXX
}
class QWorker : QIRandomizable<QWorker>
{
public double mxDouble;
}
public static class QWorkerExtensions
{
public static void fillRandomly(this System.Random xThis, ref QWorker xRef)
{
if ((xThis.Next() % 2) == 1)
xRef = null;
else
{
xRef = new QWorker();
xRef.mxDouble = xThis.NextDouble();
}
}
}
public class QBoss : QIRandomizable<QBoss>
{
public QWorker mx1;
public QWorker mx2;
public static void fillRandomly(this System.Random xThis, ref QBoss xRef)
{
xRef = new QBoss();
xThis.fillRandomly(ref xRef.mxMember1); // can be null
xThis.fillRandomly(ref xRef.mxMember2); // can be null
}
}
However this does not compile and the first problem is on line marked XXX - the static keyword does not belong there.
As a result, I would like to ask the following:
Is it possible to declare an interface with an extension inside?
If yes, what should I change?
If not, is there a different way how to accomplish what I want?
Any help is much appreciated,
Daniel
No, you cannot. That's because you can only declare instance-methods on an interface, and extension methods must be static.
You can try something like this:
public interface IDoesSomething
{
void fillRandomly(Random r);
}
public class QBoss
{
public double mx1 { get; set; }
public double mx2 { get; set; }
public int mx3 { get; set; }
public object refType { get; set; }
public void fillRandomly(Random r)
{
FillRandom(GetProps(this), this, r);
}
}
public static IEnumerable<PropertyInfo> GetProps(object blah)
{
return blah.GetType().GetProperties();
}
public static void FillRandom(IEnumerable<PropertyInfo> obj, object onObj, Random r)
{
Action<PropertyInfo, object> setVal = (prop, val) => { prop.SetValue(onObj, val); };
foreach (var o in obj)
{
if (!o.PropertyType.IsValueType)
{
if (r.Next() % 2 != 1)
{
var v = Activator.CreateInstance(o.PropertyType);
setVal(o, v);
var id = v as IDoesSomething;
if (id != null)
id.fillRandomly(r);
}
}
if (o.PropertyType == typeof(double))
setVal(o, r.NextDouble());
if (o.PropertyType == typeof(int))
setVal(o, (int)(r.NextDouble() * 100));
//etc, etc
}
}
Here, you decide what to do once, and set the properties. This currently only works for properties, not fields, so you might want to refactor it a little to take both FieldInfo and PropertyInfo
Testing it yields:
mx1 0.786868741170908
mx2 0.434705327001729
mx3 51
refType Object
In the below example, I want to replace part of a calculation without having to re-implement the entire calculation in the derived sub classes.
class DummyCalcBase
{
public int changeable_part()
{
return 5;
}
public int common_calculation()
{
return 5 * changeable_part();
}
}
class DummyCalc : DummyCalcBase
{
public new int changeable_part()
{
return 10;
}
}
class Program
{
static void Main(string[] args)
{
int c = new DummyCalcBase().common_calculation();
Console.WriteLine("Base gives " + c.ToString());
int c2 = new DummyCalc().common_calculation();
Console.WriteLine("Calc gives " + c2.ToString());
}
}
This then gives output:
Base gives 25
Calc gives 25
What I would like is to get DummyCalc().common_calculation() to call the new changeable_part (and give the answer 50).
This would mean I don't have to copy and paste the same method into sub classes.
you can override method if it is virtual
class DummyCalcBase
{
public virtual int changeable_part()
{
return 5;
}
public int common_calculation()
{
return 5 * changeable_part();
}
}
class DummyCalc : DummyCalcBase
{
public override int changeable_part()
{
return 10;
}
}
methods with new keyword only hide methods of base class
if method is virtual, the following code will compute 50:
DummyCalcBase dummy = new DummyCalc();
int calc = dummy.common_calculation();
SO: new vs override difference
Mark the method in the base class as either virtual if you want to provide a default implementation that derived types can override, or abstract if you want to leave the implementation up to derived types.
Then simply override those methods in your derived types, and provide functionality as needed.
If your scenario is as simple as you describe here, go for the virtual method, with an override method in the sub-class. If your calculation is more complex, you should take a look at the strategy pattern: http://en.wikipedia.org/wiki/Strategy_pattern
Your code will than look something like this:
public interface IStrategy
{
int getValue();
}
public class Context
{
private readonly IStrategy strategy;
public Context(IStrategy strategy)
{
this.strategy = strategy;
}
public int common_calculation()
{
return 5 * strategy.getValue();
}
}
public class FiveStrategy : IStrategy
{
public int getValue()
{
return 5;
}
}
public class TenStrategy : IStrategy
{
public int getValue()
{
return 10;
}
}
internal class Program
{
public static void Main(string[] args)
{
var context5 = new Context(new FiveStrategy());
Console.WriteLine(context5.common_calculation());
var context10 = new Context(new TenStrategy());
Console.WriteLine(context10.common_calculation());
Console.ReadLine();
}
}
I want to create a global accessible struct/class (in C#) to access my stock prices from the callback handler.
I know only C and it's easy there
Example in C
struct _Sample
{
int SomeValue;
};
struct _Sample Sample[10];
That's what I have so far in C# after 2 hours of trying.
public static class GlobalVar
{
private static double _StockPrice;
public static double SetStockPrice
{
set
{
_StockPrice = value;
}
}
public static double GetStockPrice
{
get
{
return _StockPrice;
}
}
}
The above example can be used as GlobalVar.SetStockPrice = 10.254; I know I have to use the <List> to make _StockPrice available as an array, but all my attempts to compile a working solution failed.
I would like to access it as GlobalVar[1].SetStockPrice = 1.0; and GlobalVar[1].SetStockPrice = 1.0;
I have to use C# because the SDK I'm using is only available in C#.
You would have to add a StockPrice class and keep an internal dictionary inside of GlobalVar to make this work, but you could use this:
public StockPrice this[int index]
{
get
{
StockPrice stockPrice = null;
if (index > -1)
{
InternalDictionary.TryGetValue(index, out stockPrice);
}
return stockPrice;
}
}
Then you can do GlobalVar[index] to get a certain StockPrice object from that internal dictionary of GlobalVar.
Also note that this will not work on a static class because static indexers are not allowed in C#. You might want to change your class to be a singleton instead of a static.
EDIT: A more complete example (still needs work though) with a singleton implementation:
public class GlobalVars
{
static StockPrices _stockPrices = new StockPrices();
public static StockPrices StockPrices
{
get
{
return _stockPrices ;
}
}
}
public class StockPrices
{
Dictionary<int, StockPrice> InternalDictionary = new Dictionary<int, StockPrice>();
public StockPrice this[int index]
{
get
{
StockPrice stockPrice = null;
if (index > -1)
{
InternalDictionary.TryGetValue(index, out stockPrice);
}
return stockPrice;
}
}
public void Add(StockPrice stockPrice)
{
int index = InternalDictionary.Keys.Max() + 1;
InternalDictionary.Add(index, stockPrice);
}
}
Then you could call your code like this:
GlobalVars.StockPrices[1].DoSomething
The C example you gave, is creating an array with 10 instances of the struct.
The equivalent C# code is this:
struct _Sample
{
public int SomeValue;
public static _Sample[] Sample = new _Sample[10];
};
That is not very C#-ish however. Using C# style I would write something like
struct Sample
{
public int SomeValue { get; set; }
public static Sample[] Values = new Sample[10];
}
You can do something like this to have the same behaviour like in c. Notice that you don't need to make SetField and GetField using { get; set; } you get this behaviour by default (it's a property).
public struct Sample
{
public double StockPrice { get; set; }
}
public static class GlobalVar
{
public static Sample[] Samples = new Sample[10];
}
And to acces use
GlobalVar.Samples[1].StockPrice = 1.0;