Constructing custom expression trees while using operators in C# - c#

This question is about constructing custom expression trees in .NET using the operators found in C# (or any other language). I provide the question along with some the background information.
For my managed 2-phase 64-bit assembler I need support for expressions. For example, one might want to assemble:
mystring: DB 'hello, world'
TIMES 64-$+mystring DB ' '
The expression 64-$+mystring must not be a string but an actual valid expression with the benefits of syntax and type checking and IntelliSense in VS, something along the lines of:
64 - Reference.CurrentOffset + new Reference("mystring");
This expression is not evaluated when it is constructed. Instead, it is evaluated later in my assembler's context (when it determines the symbol offsets and such). The .NET framework (since .NET 3.5) provides support for expressions trees, and it seems to me that it is ideal for this kind of expressions which are evaluated later or somewhere else.
But I don't know how to ensure that I can use the C# syntax (using +, <<, %, etc..) for constructing the expression tree. I want to prevent things like:
var expression = AssemblerExpression.Subtract(64,
AssemblerExpression.Add(AssemblerExpression.CurrentOffset(),
AssemblerExpression.Reference("mystring")))
How would you go about this?
Note: I need an expression tree to be able to convert the expression into an acceptable custom string representation, and at the same time be able to evaluate it at a point in time other than at its definition.
An explanation of my example: 64-$+mystring. The $ is the current offset, so it is a specific number that is unknown in advance (but known at evaluation time). The mystring is a symbol which may or may not be known at evaluation time (for example when it has not yet been defined). Subtracting a constant C from a symbol S is the same as S + -C. Subtracting two symbols S0 and S1 (S1 - S0) gives the integer difference between the two symbol's values.
However, this question is not really about how to evaluate assembler expressions, but more about how to evaluate any expression that has custom classes in them (for things like the symbols and $ in the example) and how to still ensure that it can be pretty-printed using some visitor (thus keeping the tree). And since the .NET framework has its expression trees and visitors, it would be nice to use those, if possible.

I don't know what exactly you are aiming for, but the following is some sketchy approach that I think would work.
Note I
demonstrate only indexed reference expressions (thus ignoring indirect addressing via registers for now; you could add a RegisterInderectReference analogous to the SymbolicReference class). This also goes for you suggested $ (current offset) feature. It would probably be sure a register (?)
doesn't explicitely show the unary/binary operator- at work either. However, the mechanics are largely the same. I stopped short of adding it because I couldn't work out the semantics of the sample expressions in your question (I'd think that subtracting the address of a known string is not useful, for example)
the approach does not place (semantic) limits: you can offset any ReferenceBase derived IReference. In practice, you might only want to allow one level of indexing, and defining the operator+ directly on SymbolicReference would be more appropriate.
Has sacrificed coding style for demo purposes (in general, you'll not want to repeatedly Compile() your expression trees, and direct evaluation with .Compile()() looks ugly and confusing. It's left up to the OP to integrate it in a more legible fashion
The demonstration of the explicit conversion operator is really off-topic. I got carried away slighlty (?)
You can observe the code running live on IdeOne.com
.
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Linq;
namespace Assembler
{
internal class State
{
public readonly IDictionary<string, ulong> SymbolTable = new Dictionary<string, ulong>();
public void Clear()
{
SymbolTable.Clear();
}
}
internal interface IReference
{
ulong EvalAddress(State s); // evaluate reference to address
}
internal abstract class ReferenceBase : IReference
{
public static IndexedReference operator+(long directOffset, ReferenceBase baseRef) { return new IndexedReference(baseRef, directOffset); }
public static IndexedReference operator+(ReferenceBase baseRef, long directOffset) { return new IndexedReference(baseRef, directOffset); }
public abstract ulong EvalAddress(State s);
}
internal class SymbolicReference : ReferenceBase
{
public static explicit operator SymbolicReference(string symbol) { return new SymbolicReference(symbol); }
public SymbolicReference(string symbol) { _symbol = symbol; }
private readonly string _symbol;
public override ulong EvalAddress(State s)
{
return s.SymbolTable[_symbol];
}
public override string ToString() { return string.Format("Sym({0})", _symbol); }
}
internal class IndexedReference : ReferenceBase
{
public IndexedReference(IReference baseRef, long directOffset)
{
_baseRef = baseRef;
_directOffset = directOffset;
}
private readonly IReference _baseRef;
private readonly long _directOffset;
public override ulong EvalAddress(State s)
{
return (_directOffset<0)
? _baseRef.EvalAddress(s) - (ulong) Math.Abs(_directOffset)
: _baseRef.EvalAddress(s) + (ulong) Math.Abs(_directOffset);
}
public override string ToString() { return string.Format("{0} + {1}", _directOffset, _baseRef); }
}
}
namespace Program
{
using Assembler;
public static class Program
{
public static void Main(string[] args)
{
var myBaseRef1 = new SymbolicReference("mystring1");
Expression<Func<IReference>> anyRefExpr = () => 64 + myBaseRef1;
Console.WriteLine(anyRefExpr);
var myBaseRef2 = (SymbolicReference) "mystring2"; // uses explicit conversion operator
Expression<Func<IndexedReference>> indexedRefExpr = () => 64 + myBaseRef2;
Console.WriteLine(indexedRefExpr);
Console.WriteLine(Console.Out.NewLine + "=== show compiletime types of returned values:");
Console.WriteLine("myBaseRef1 -> {0}", myBaseRef1);
Console.WriteLine("myBaseRef2 -> {0}", myBaseRef2);
Console.WriteLine("anyRefExpr -> {0}", anyRefExpr.Compile().Method.ReturnType);
Console.WriteLine("indexedRefExpr -> {0}", indexedRefExpr.Compile().Method.ReturnType);
Console.WriteLine(Console.Out.NewLine + "=== show runtime types of returned values:");
Console.WriteLine("myBaseRef1 -> {0}", myBaseRef1);
Console.WriteLine("myBaseRef2 -> {0}", myBaseRef2);
Console.WriteLine("anyRefExpr -> {0}", anyRefExpr.Compile()()); // compile() returns Func<...>
Console.WriteLine("indexedRefExpr -> {0}", indexedRefExpr.Compile()());
Console.WriteLine(Console.Out.NewLine + "=== observe how you could add an evaluation model using some kind of symbol table:");
var compilerState = new State();
compilerState.SymbolTable.Add("mystring1", 0xdeadbeef); // raw addresses
compilerState.SymbolTable.Add("mystring2", 0xfeedface);
Console.WriteLine("myBaseRef1 evaluates to 0x{0:x8}", myBaseRef1.EvalAddress(compilerState));
Console.WriteLine("myBaseRef2 evaluates to 0x{0:x8}", myBaseRef2.EvalAddress(compilerState));
Console.WriteLine("anyRefExpr displays as {0:x8}", anyRefExpr.Compile()());
Console.WriteLine("indexedRefExpr displays as {0:x8}", indexedRefExpr.Compile()());
Console.WriteLine("anyRefExpr evaluates to 0x{0:x8}", anyRefExpr.Compile()().EvalAddress(compilerState));
Console.WriteLine("indexedRefExpr evaluates to 0x{0:x8}", indexedRefExpr.Compile()().EvalAddress(compilerState));
}
}
}

C# supports assigning a lambda expression to an Expression<TDelegate>, which will cause the compiler to emit code to create an expression tree representing the lambda expression, which you can then manipulate. E.g.:
Expression<Func<int, int, int>> times = (a, b) => a * b;
You could then potentially take the generated expression tree and convert it into your assembler's syntax tree, but this doesn't seem to be quite what you're looking for, and I don't think you're going to be able to leverage the C# compiler to do this for arbitrary input.
You're probably going to end up having to build your own parser for your assembly language, as I don't think the C# compiler is going to do what you want in this case.

Again, not quite sure if this is exactly what you're looking for, but from the starting point of wanting to create some kind of expression tree using C# syntax, I've come up with...
public abstract class BaseExpression
{
// Maybe a Compile() method here?
}
public class NumericExpression : BaseExpression
{
public static NumericExpression operator +(NumericExpression lhs, NumericExpression rhs)
{
return new NumericAddExpression(lhs, rhs);
}
public static NumericExpression operator -(NumericExpression lhs, NumericExpression rhs)
{
return new NumericSubtractExpression(lhs, rhs);
}
public static NumericExpression operator *(NumericExpression lhs, NumericExpression rhs)
{
return new NumericMultiplyExpression(lhs, rhs);
}
public static NumericExpression operator /(NumericExpression lhs, NumericExpression rhs)
{
return new NumericDivideExpression(lhs, rhs);
}
public static implicit operator NumericExpression(int value)
{
return new NumericConstantExpression(value);
}
public abstract int Evaluate(Dictionary<string,int> symbolTable);
public abstract override string ToString();
}
public abstract class NumericBinaryExpression : NumericExpression
{
protected NumericExpression LHS { get; private set; }
protected NumericExpression RHS { get; private set; }
protected NumericBinaryExpression(NumericExpression lhs, NumericExpression rhs)
{
LHS = lhs;
RHS = rhs;
}
public override string ToString()
{
return string.Format("{0} {1} {2}", LHS, Operator, RHS);
}
}
public class NumericAddExpression : NumericBinaryExpression
{
protected override string Operator { get { return "+"; } }
public NumericAddExpression(NumericExpression lhs, NumericExpression rhs)
: base(lhs, rhs)
{
}
public override int Evaluate(Dictionary<string,int> symbolTable)
{
return LHS.Evaluate(symbolTable) + RHS.Evaluate(symbolTable);
}
}
public class NumericSubtractExpression : NumericBinaryExpression
{
protected override string Operator { get { return "-"; } }
public NumericSubtractExpression(NumericExpression lhs, NumericExpression rhs)
: base(lhs, rhs)
{
}
public override int Evaluate(Dictionary<string, int> symbolTable)
{
return LHS.Evaluate(symbolTable) - RHS.Evaluate(symbolTable);
}
}
public class NumericMultiplyExpression : NumericBinaryExpression
{
protected override string Operator { get { return "*"; } }
public NumericMultiplyExpression(NumericExpression lhs, NumericExpression rhs)
: base(lhs, rhs)
{
}
public override int Evaluate(Dictionary<string, int> symbolTable)
{
return LHS.Evaluate(symbolTable) * RHS.Evaluate(symbolTable);
}
}
public class NumericDivideExpression : NumericBinaryExpression
{
protected override string Operator { get { return "/"; } }
public NumericDivideExpression(NumericExpression lhs, NumericExpression rhs)
: base(lhs, rhs)
{
}
public override int Evaluate(Dictionary<string, int> symbolTable)
{
return LHS.Evaluate(symbolTable) / RHS.Evaluate(symbolTable);
}
}
public class NumericReferenceExpression : NumericExpression
{
public string Symbol { get; private set; }
public NumericReferenceExpression(string symbol)
{
Symbol = symbol;
}
public override int Evaluate(Dictionary<string, int> symbolTable)
{
return symbolTable[Symbol];
}
public override string ToString()
{
return string.Format("Ref({0})", Symbol);
}
}
public class StringConstantExpression : BaseExpression
{
public string Value { get; private set; }
public StringConstantExpression(string value)
{
Value = value;
}
public static implicit operator StringConstantExpression(string value)
{
return new StringConstantExpression(value);
}
}
public class NumericConstantExpression : NumericExpression
{
public int Value { get; private set; }
public NumericConstantExpression(int value)
{
Value = value;
}
public override int Evaluate(Dictionary<string, int> symbolTable)
{
return Value;
}
public override string ToString()
{
return Value.ToString();
}
}
Now, obviously none of these classes actually do anything (you'd probably want a Compile() method on there amongst others) and not all the operators are implemented, and you can obviously shorten the class names to make it more concise etc... but it does allow you to do things like:
var result = 100 * new NumericReferenceExpression("Test") + 50;
After which, result will be:
NumericAddExpression
- LHS = NumericMultiplyExpression
- LHS = NumericConstantExpression(100)
- RHS = NumericReferenceExpression(Test)
- RHS = NumericConstantExpression(50)
It's not quite perfect - if you use the implicit conversions of numeric values to NumericConstantExpression (instead of explicitly casting/constructing them), then depending on the ordering of your terms, some of the calculations may be performed by the built-in operators, and you'll only get the resulting number (you could just call this a "compile-time optimization"!)
To show what I mean, if you were to instead run this:
var result = 25 * 4 * new NumericReferenceExpression("Test") + 50;
in this case, the 25 * 4 is evaluated using built-in integer operators, so the result is actually identical to the above, rather than building an additional NumericMultiplyExpression with two NumericConstantExpressions (25 and 4) on the LHS and RHS.
These expressions can be printed using ToString() and evaluated, if you provide a symbol table (here just a simple Dictionary<string, int>):
var result = 100 * new NumericReferenceExpression("Test") + 50;
var symbolTable = new Dictionary<string, int>
{
{ "Test", 30 }
};
Console.WriteLine("Pretty printed: {0}", result);
Console.WriteLine("Evaluated: {0}", result.Evaluate(symbolTable));
Results in:
Pretty printed: 100 * Ref(Test) + 50
Evaluated: 3050
Hopefully despite the drawback(s) mentioned, this is something approaching what you were looking fo (or I've just wasted the last half hour!)

You are implementing a two phase (pass?) assembler? The purpose of a two pass assembler
is to handle forward references (e.g., symbol that are undefined when first encountered).
Then you pretty much don't need to build an expression tree.
In phase (pass 1), you parse the source text (by any means you like: ad hoc parser, recursive descent, parser generator) and collect values of symbols (in particular, the relative values of labels with respect to the code or data section in which they are contained. If you encounter an expression, you attempt to evaluate it using on-the-fly expression evalution, typically involving a push down stack for subexpressions, and producing a final result. If you encounter a symbol whose value is undefined, you propagate the undefinedess as the expression result. If the assembly operator/command needs the expression value to define a symbol (eg., X EQU A+2) or to determine offsets into a code/data section (e.g, DS X+23), then the value must be defined or the assembler throws an error. This allows ORG A+B-C to work. Other assembly operators that don't need the value during pass one simply ignore the undefined result (e.g., LOAD ABC doesn't care what ABC is, but can determine the length of the LOAD instruction).
In phase (pass II), you re-parse the code the same way. This time all the symbols have values, so all expressions should evaluate. Those that had to have a value in Phase I are checked against the values produced in Phase II to ensure they are identical (otherwise you get a PHASE error). Other assembly operators/instructions now have enough information to generate the actual machine instructions or data initializations.
The point is, you never have to build an expression tree. You simply evaluate the expression as you encounter it.
If you built a one pass assembler, you might need to model the expression to allow re-evaluation later. I found it easier to produce reverse polish as sequence of "PUSH value" and arithop, and store the sequence (equivalent to the expression tree), because it is dense (trees are not) and trivial to evaluate by doing a linear scan using (as above) a small pushdown stack.
In fact what I did was to produce reverse polish that in fact acted as the expression stack itself; during a linear scan, if operands could be evaluated they were replaced by a "PUSH value" command, and the remaining reverse polish is squeezed to remove the bubble. This isnt expensive because most expressions are actually tiny. And it meant that any expression that had to saved for later evaluation was as small as possible. If you threaded the PUSH identifier commands through the symbol table, then when as symbol becomes defined, you can fill in all the partially evaluated expressions and reevaluate them; the ones that produce a single value are then processed and their space recycled. This allowed me to assemble giant programs in a 4K word, 16 bit machine, back in 1974, because most forward references don't really reach very far.

Related

What does '=>' mean (in functions / property context)?

I got an auto generated code using Lambdas while developing a Xamarin application:
public override string this[int position] => throw new NotImplementedException();
public override int Count => throw new NotImplementedException();
What does the => operator mean in this context?
Thanks
R
These are not lambdas, they are Expression-bodied Members!
In the context of a property, these are basically the getters of a property simplified to become a single expression (as opposed to a whole statement).
This:
public override int Count => throw new NotImplementedException();
Is equivalent to:
public override int Count {
get { throw new NotImplementedException(); }
}
As #sweeper says in your example they do not relate to lambda expressions as they are expression body operators (which were introduced in C# 6 and expanded on in 7). It is also used to indicate a lambda expression though, so it's usage is two fold.
Further information on each usage of the => operator can be found here; https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-operator
First, let's clarify that the =>operator is currently used in two different contexts:
Lambda expressions.
Often you will see them in Linq, e.g.
var query = Customers.OrderBy(x => x.CompanyName);
Expression bodied functions. This is what we have here.
In order to understand what => means, please take a look at the following simple example:
using System;
public class Program
{
public void Main()
{
var obj = new Test();
obj.Count.Dump();
obj[7].Dump();
}
class Test
{
public int Count => 1;
public string this[int position] => $"2 x {position} = {(2*position)}";
}
}
Dumping object(Int32)
1
Dumping object(String)
2 x 7 = 14
Try it in DotNetFiddle
Here, the NotImplementedException code, which is just there to tell you (the developer) that the property and indexer is not implemented but should be, is replaced by some function:
Count is a readonly property returning always 1
whenever you apply [ ... ] to the object, the doubled index is returned
Note that in earlier versions of C# you had to write:
class Test
{
public int Count { get { return 1; } }
public string this[int position] {
get { return String.Format("2 x {0} = {1}",
position, (2*position).ToString()); }}
}
which is equivalent to the code above. So in essence in C#7 you have to type much less to achieve the same result.

Mathematics and generics

Ok, I need to implement, among others, these two particular types: ComplexNumber<T> and Matrix<T>. T can be one of the following: a rational number, a real number or integers.
In the System namespace I have a good representation for real numbers (decimal), integer numbers (int or long). Numerics.ComplexNumber does not cut it becuase internally RealPart and ImaginaryPart are double and I can't afford, in this particular case, the representation error of this type.
Now, the probem is of course that there is no way to constraint the generic parameter T to mathematical "valid" types. That is, I can't do the following:
public struct ComplexNumber<T>
{
readonly T realPart;
readonly T imaginaryPart;
public static ComplexNumber<T> Add(ComplexNumber<T> left, ComplexNumber<T> right)
{
return new ComplexNumber<T>(left.realPart + right.realPart, left.imaginaryPart + right.imaginaryPart); //Compile time error. No operator defined for T
}
}
So I need a workaround. Although performance is not a goal in itself, I'd like the code to work reasonably well, but above all, I'd like it to be the most elegant solution possible. Right now I've come up with two possibilities:
A Numeric abstract base class similar to:
public abstract class Numeric
{
protected abstract Numeric _Add(Numeric right);
protected abstract Numeric _Subtract(Numeric right);
public static Numeric Add(Numeric left, Numeric right) { return _Add(this, right); }
public static Numeric Subtract(Numeric left, Numeric right) { return _Subtract(this, right);
}
Now I could do:
public sealed class RationalNumber: Numeric
{
readonly long numerator, denominator;
protected override Numeric _Add(Numeric right) { //Rational addition implementation }
}
And then Matrix<RationalNumber> or Matrix<ComplexNumber> would work.
The other option is to do it through an interface:
public INumeric
{
INumeric Add(INumeric right);
INumeric Subtract(INumeric right);
}
public struct RationalNumber: INumeric
{
readonly long numerator, denominator;
public static RationalNumber Add(RationalNumber left, RationalNumber right) { //Rationa add implementation }
INumeric INumeric.Add(INumeric right) //explicit to not clog up the type and to convey the idea of a framework mechanism.
{
if (!(right is RationalNumber))
throw new ArgumentException();
Add(this, (RationalNumber)right);
}
The interface option lets me implement RationalNumber as a struct wich is, IMHO, more consistent with how numeric types are implemented in the framework. Also the types themselves are pretty lightweight and will typically have short lives. The Numeric base class solution seems like a whole lot more heavyweight, but I'm not really an expert to exactly quantify the advantages of one over the other when it comes to:
Code qualitiy and future extensibility and maintenance
Performance and memory consumption (curiosity more than anything else)
A better solution?
If anyone can shed a little bit of light, I'd appreciate it.
You can use extensions method to solve this problem:
public struct ComplexNumber<T>
{
private readonly T _realPart;
private readonly T _imaginaryPart;
public ComplexNumber(T realPart, T imaginaryPart)
{
_realPart = realPart;
_imaginaryPart = imaginaryPart;
}
public T RealPart
{
get
{
return _realPart;
}
}
public T ImaginaryPart
{
get
{
return _imaginaryPart;
}
}
public override string ToString()
{
return string.Format("({0}, {1})", RealPart, ImaginaryPart);
}
}
public static class ComplexNumberExtensions
{
public static ComplexNumber<int> Add(this ComplexNumber<int> self, ComplexNumber<int> other)
{
return new ComplexNumber<int>(self.RealPart + other.RealPart, self.ImaginaryPart + other.ImaginaryPart);
}
public static ComplexNumber<double> Add(this ComplexNumber<double> self, ComplexNumber<double> other)
{
return new ComplexNumber<double>(self.RealPart + other.RealPart, self.ImaginaryPart + other.ImaginaryPart);
}
// Add similar extension methods for each numeric type you need
}
Use it like this:
var first = new ComplexNumber<int>(1, 2);
var second = new ComplexNumber<int>(3, 4);
var result = first.Add(second);
Console.WriteLine(result);

Properly implement comparison of two objects with different type but semantically equivalent

I've found a similar question
How to compare two distinctly different objects with similar properties
that may implicitly and/or in part reply to my question.
Suppose I want compare (without a lot of nested conditions) this object:
class ObjectA {
public string PropertyX { get; set; }
public char PropertyY { get; set; }
public long PropertyZ { get; set; }
}
to a System.String. I'm interested only in equality or inequality (not a range of values about identity).
Implementing IEquatable<string> in ObjectA is a proper choice? I don't care of what simply works, I want to identify the proper pattern for such case.
As other information, please consider that ObjectA will often be supplied as sequence of IEnumerable<ObjectA>.
I don't need to know if "string" == or != objectA instance; sorting is not involved.
Edit to clarify (and help)
Sorry but writing a good question is sometime difficult...
Suppose I can't represent ObjectA as string for the purpose of comparison (violating encapsulation is not an option).
In context-1 I've to match it against PropertyY.
In context-2 I've to match it against an algorithm applied to PropertyY/PropertyZ.
#Oliver solution in the end of the question helps me again (and +1 again).
I can simply define a custom interface:
interface IContextConverter {
string ToEquatableStringForContext1();
string ToEquatableStringForContext2();
}
Since I've also an ObjectB with same logic but different properties, both will implement IContextConverter (or maybe I find a better name) avoiding to violate RAP.
I would strongly recommend to not implement IEquatable<string>, cause especially when working with collections, dictionaries, LINQ, etc. you don't really know when one of these methods will be called somewhere deep inside which leads maybe to subtle bugs.
Due to the fact that you like to compare two objects of different types a simple Comparer<T> wouldn't work also.
So either write a TypeConverter which converts your object into the desired type (in your case a string) or add a method to your object like .ToEquatableString() and use their output to compare your object with the other string.
Here is an example on you could get all elements, that match one of a string in another collection:
IEnumerable<String> otherElements = new[] {"abc", "def", "ghi" };
IEnumerable<ObjectA> myObjects = GetObjects();
var matchesFound = otherElements.Join( // Take the first collection.
myObjects, // Take the second collection.
s => s, // Use the elements in the first collection as key (the string).
obj => obj.ToEquatableString(), // Create a string from each object for comparison.
(s, obj) => obj, // From the matching pairs take simply the objects found.
StringComparer.OrdinalIgnoreCase); // Use a special string comparer if desired.
There are many possibilities.
If you feel an ObjectA is a kind of System.String, you could write a user-defined conversion (implicit or explicit) from ObjectA to System.String, or from System.String to ObjectA, or both directions.
You could also overload the == and != operators with a signature like operator ==(ObjectA oa, string s). Beware that there is difference between oa == s and s == oa.
Either of these two possibilities may lead to confusion. It would also be confusing to override the virtual Equals(object), or to introduce an overload Equals(string). Therefore I don't recommend implementing IEquatable<string>.
Why not simply write a method with an unused name, like public bool EqualsString(string s)? Then you will have to call this method explicitly, of course, but that will lead to less confusion. Another idea would be to use a constructor of signature public ObjectA(string s) and then implement "homogeneous" equality of ObjectA and ObjectA.
NOTE: I do not particulary recommend this solution for this particular case, but I have often used this framework to implement Value Equality for structs. Difficult trade-offs are common in our field, and answers that address those, accompanied by appropriate caveats, seem in order.
I take it that you wish to design Value Equality semamtics on your class in the same fashion as the .NET framework does this for the string class. At a minimum, the following is necessary:
public override bool Equals(object obj) {
return (obj is ObjectA) && this == (ObjectA)obj;
}
bool IEquatable<ObjectA>.Equals(ObjectA rhs) {
return this == rhs;
}
public static bool operator != (ObjectA lhs, ObjectA rhs) {
return ! (lhs == rhs);
}
public static bool operator == (ObjectA lhs, ObjectA rhs) {
return (lhs.PropertyX == rhs.PropertyX);
}
public override int GetHashCode() {
return PropertyX.GetHashCode()
}
Expanding to allow Value comparisons beween ObjectA and string:
bool IEquatable<ObjectA>.Equals(string rhs) {
return this == rhs;
}
public static bool operator != (ObjectA lhs, string rhs) {
return ! (lhs == rhs);
}
public static bool operator != (string lhs, ObjectA rhs) {
return ! (lhs == rhs);
}
public static bool operator == (ObjectA lhs, string rhs) {
return (lhs.PropertyX == rhs);
}
public static bool operator == (string lhs, ObjectA rhs) {
return (lhs == rhs.PropertyX);
}

Operators and inheritance

My brain has turned to jelly, or I'm having an out of mind experience, or something. I'm tinkering with a class hierarchy that looks a bit like this:
My Money class looks like this:
public abstract class Money
{
public int Amount { get; set; }
public static bool operator ==(Money leftSide, Money rightSide)
{
// Money can only be equal if it is in the same currency.
if (leftSide.GetType() != rightSide.GetType()) return false;
return leftSide.Amount == rightSide.Amount;
}
public static bool operator !=(Money leftSide, Money rightSide)
{
// If the currencies are different, the amounts are always considered unequal.
if (leftSide.GetType() != rightSide.GetType()) return true;
return leftSide.Amount != rightSide.Amount;
}
public static Money operator *(Money multiplicand, int multiplier)
{
var result = multiplicand * multiplier;
return result;
}
public static Dollar Dollar(int amount)
{
return new Dollar(amount);
}
public static Franc Franc(int amount)
{
return new Franc(amount);
}
}
My Dollar operator * looks like this:
public static Dollar operator *(Dollar multiplicand, int multiplier)
{
var result = multiplicand.Amount * multiplier;
return new Dollar(result);
}
Now, if I run this test code, I get a Stack overflow (wahoo!)
{
Money fiveDollars = Money.Dollar(5);
Money timesTwo = fiveDollars*2;
}
I had expected that this would recursively call the subclass (Dollar) operator *, which would return a definite result since (Dollar * int) is defined non-recursively. Since this doesn't work, the alternative is that I have done something dumb. Why doesn't this work? What would be the right way to get this behaviour?
You seem to have left out .Amount
public static Money operator *(Money multiplicand, int multiplier)
{
var result = multiplicand.Amount * multiplier;
return result;
}
The problem is that you expect that you can override operators in derived classes and expect dynamic binding. This is not the way it works in C#. Operators are overloaded and the actual overload is chosen compile-time. This means that the following code is recursive and calls itself:
public static Money operator *(Money multiplicand, int multiplier)
{
var result = multiplicand * multiplier;
return result;
}
Another example where you can see the difference between operator overloading and method overriding is this:
int a = 5;
int b = 5;
Console.WriteLine(a == b); // true
Console.WriteLine(a.Equals(b)); // true
Console.WriteLine((object)a == (object)b); // false
Console.WriteLine(((object)a).Equals((object)b)); // true
In the third case, C# treats a and b as objects instead of integers, so it uses the default == operator that is used for objects: comparing references (in this case the references of boxed integers).
This can make it awkward to define operators on a class hierarchy where you want to redefine the operators in derived classes. It is especially awkward when the behavior depends on the combination of both operands, since C# (and most other OOP languages) lacks support for multiple dispatch. You can solve this by using the visitor pattern, but I think in this case you should reconsider if using subclasses for each currency is the best solution.

Confirming Greenspun's 10th Law in C#

I am trying to implement an infrastructure in C# that would allow me to make arbitrary mathematical expressions. For example, I want to be able to take an expression like
asin(sqrt(z - sin(x+y)^2))
and turn it into an object that will allow me to evaluate it in terms of x,y, and z, get derivatives, and possibly do some kind of symbolic algebra on it. What are people's thoughts on a good model for this in C#?
I have my own take, which I am afraid is heading off into architecture astronautics, so I want to make sure that is not the case.
Basically, the functions like sin, +, sqrt, etc. have classes based off a base class:
Function
Function<TOut> : Function
TOut Value
Function<Tin, TOut> : Function
TOut Evaluate(TIn value)
Function Derivative
Function<TOut, TIn> INverse
Function<TInA, TInB, TOut> : Function
TOut Evaluate(TInA valueA, TInB valueB)
Function PartialDerivativeA
Function PartialDerivativeB
So far, so simple. The trick is how to compose the functions. Here I believe I want something like a currying approach so that I can evaluate the function for a single parameter, and have the other ones remain. So I am thinking of having a factory class like this:
Function<TInA, TInB, TOut> ->
Function<TInA, Function<TInB, TOut>>
(Function<TInA, TInB, TOut>, Function<TInX, TInA>, null) ->
Function<TInX, Function<TInB, TOut>>
(Function<TInA, TInB, TOut>, Function<TInA>, Function<TInX, TInY, TInB>) ->
Function<TInX, Function<TInY, TInB>>
and so on. My main concerns are that the generic types might make the system unusable (if the user is required to know the full generic types just to evaluate), and that I might not be able to construct all of the generic types from the input arguments.
Thanks for your input!
Note that it is possible to use the C# compiler to evaluate expressions.
Evaluating Mathematical Expressions by Compiling C# Code at Runtime
http://www.codeproject.com/KB/recipes/matheval.aspx
What about using Expression Trees? Note that on the linked page, there's even an example for building sort of a curried function (building a "less than five" function from a generic "less than" operator and a fixed constant)
I'm not entirely sure what currying is, but the usual approach to parsing expressions is to build an abstract syntax tree.
From this it shouldn't be difficult to evalute the expression, find the derivative, or whatever it is you want to do.
[Edit] I'm afraid your comments make no sense. From the sounds of it, you want to parse an expression and build an AST, from which you can do whatever you want with it. Yes, you will build classes for each type of node; something like this
public class PlusNode : BinaryNode
{
public PlusNode(Node left, Node right) { base(left, right); }
public virtual double Evaluate() { return Left.Evaluate() + Right.Evaluate(); }
public virtual Node BuildDerivative()
{
return new PlusNode(Left.BuildDerivative(), Right.BuildDerivative());
}
}
public class SinNode : UnaryNode
{
public SinNode(Node child) { base(child); }
public virtual double Evaluate() { return Math.Sin(Child.Evaluate()); }
public virtual Node BuildDerivative()
{
return new MultiplyNode(new CosNode(Child.Clone()), Child.BuildDerivative()); //chain rule
}
}
Funny, I actually did this a few months ago in D and it wasn't received as particularly interesting. My approach was to use templated expression tree classes. I had a Binary class template that could be instantiated with +, *, etc, a unary class that could be instantiated with sin, exp, etc. Derivatives worked by mostly just recursively applying the chain and product rules. For example:
class Binary(alias fun) : MathExpression {
MathExpression left, right;
MathExpression derivative() {
static if(is(fun == add)) {
return left.derivative + right.derivative;
} else static if(is(fun == mul)) {
return left.derivative * right + right.derivative * left;
}
}
real opCall(real x) {
return fun(left(x), right(x));
}
}
class Unary(alias fun) : MathExpression {
MathExpression inner;
MathExpression derivative() {
static if(is(fun == sin)) {
return Unary!(sin)(inner.derivative);
}
}
real opCall(real x) {
return fun(inner(x));
}
}
class Constant : MathExpression {
real val;
real opCall(real x) {
return val;
}
real derivative() {
return new Constant(0);
}
}

Categories

Resources