Writing an interpreter in C#: Best way to implement instructions? - c#

I'm writting a PLC language interpreter using C#. That PLC language contains over 20 data types and 25 instructions or so. As soon as I started to generate code I balance two differents ways to write instructions:
1) Every kind of instruction is represented in one class which contains a big switch in order to chose the data type. Example:
public class ADD : Instruction
{
private string type;
public ADD(string type)
{
this.type = type;
}
public bool Exec(Context c)
{
switch (type)
{
case "INT":
short valor2 = c.PopINT();
short valor = c.PopINT();
short result = (short)(valor + valor2);
c.PushINT(result);
break;
case "DINT":
int valor4 = c.PopDINT();
int valor3 = c.PopDINT();
int result2 = (int)(valor4 + valor3);
c.PushDINT(result2);
break;
case "BOOL":
// Implement BOOL
break;
// Implement other types...
default:
break;
}
c.IP++;
return false; ;
}
}
2) Each class represent a single instruction with a single data type. This way avoid the big switch. Example:
public class ADDi : Instruction
{
public bool Exec(Context c)
{
short valor = c.PopINT();
short valor2 = c.PopINT();
short result = (short)(valor + valor2);
c.PushINT(result);
c.IP++;
return false;
}
}
I'm using COMMAND desing pattern (Exec()) to write instructions. I think second choice is better because avoids the big switch, but that choice involves to write over 400 instructions.
Always keep in mind that in this case execution performance is more important than performance in translation.
So, my precise question is as follows: Is there any other way to factorize instructions and data types? I'm looking for writing the lesser amount of instructions without penalizing performance.
EDIT:
This picture shows my type hierarchy:
This is INT class implementation:
public class INT : ANY_INT
{
public override string DefaultInitValue()
{
return "0";
}
public override int GetBytes()
{
return 2;
}
public override string GetLastType()
{
return this.ToString();
}
public override string ToString()
{
return "INT";
}
}
Some classes are more complex (structs, arrays,...).
Operations Push and Pop are defined as follows:
public void PushINT(short value)
{
//SP -> Stack Pointer
resMem.WriteINT(SP, value);
SP += 2;
}
public short PopINT()
{
SP -= 2;
short value = resMem.ReadINT(SP);
return value;
}
And, finally, operations to read and write in memory.
public void WriteINT(int index, short entero)
{
SetCapacity(index + 2); // Memory grows up dinamically
memory[index] = (sbyte)((ushort)entero >> 8 & 0x00FF);
memory[index + 1] = (sbyte)((ushort)entero >> 0 & 0x00FF);
}
public short ReadINT(int index)
{
return (short)(((short)(memory[index]) << 8 & 0xFF00) |
((short)(memory[index + 1]) & 0x00FF));
}
I hope this info helps. Thank you.

If you can change the implementation of Context to support generic types (e.g., Pop<int> instead of PopINT()) you can use delegates to make the implementation simpler.
Addition:
var addInt = new MathInstruction<int>((a, b) => a + b));
var addDouble = new MathInstruction<double>((a, b) => a + b));
var addDecimal = new MathInstruction<decimal>((a, b) => a + b));
Subtraction:
var subtractInt = new MathInstruction<int>((a, b) => a - b));
var subtractDouble = new MathInstruction<double>((a, b) => a - b));
var subtractDecimal = new MathInstruction<decimal>((a, b) => a - b));
Division:
var divideIntAsDouble = new MathInstruction<int, double>((a, b) => a / b));
var divideDouble = new MathInstruction<double>((a, b) => a / b));
var divideDecimal = new MathInstruction<decimal>((a, b) => a / b));
And conversion between types:
var addIntAndDouble = new MathInstruction<int, double, double>((a, b) => a + b));
It would be implemented like this:
class MathInstruction<TA, TB, TResult> : Instruction
{
private Func<TA, TB, TResult> callback;
public MathInstruction(Func<TA, TB, TResult> callback)
{
this.callback = callback;
}
public bool Exec(Context c)
{
var a = c.Pop<TA>();
var b = c.Pop<TB>();
var result = callback(a, b);
c.Push<TResult>(result);
return false;
}
}
// Convenience
class MathInstruction<T, TResult> : MathInstruction<T, T, TResult>
class MathInstruction<T> : MathInstruction<T, T, T>
I'm imagining that your context simply has a Stack<object> and PopINT, PopBOOL etc. just pop the argument and cast. In that case you can probably just use:
public T Pop<T>()
{
var o = stack.Pop();
return Convert.ChangeType(o, typeof(T));
}
public void Push<T>(T item)
{
stack.Push(item);
}
Note this could also handle your logical operators - for example:
var logicalAnd = new MathInstruction<bool>((a, b) => a && b);
var logicalOr = new MathInstruction<bool>((a, b) => a || b);

Could you use inheritance ? I would see a clever combination of inheritance concerning the datatypes, and then a strategy pattern to delegate the execution to the appropriate objects.
But then we really would need to see a class diagramm to help you out.
Just remember to program to an interface, not a type, and also, composition is more powerful than inheritance. I hope this can help you out.

Related

Writing generic arithmetic in C#

I have a list of numbers, and I wrote a method that performs some calculations on these numbers; all in all, it's about a page of code. The method performs some arithmetic and comparisons on these numbers.
My problem is that, in one case, the list is an IList<byte>, and in another case, it's an IList<float>. The algorithm in both cases is exactly the same (yes, I'm aware of things like overflow errors and loss of precision, but in my case it works). How can I write a method that will handle both lists ? I can't write something like void DoStuff<T>(IList<T> numbers), because there are no arithmetic operators (+ - * /) that are generic.
One solution is to simply store everything as float, but I'd like to avoid it. The lists are quite long, and thus storing floats instead of bytes would cost too much memory. I could also do something like DoStuffFloat(byteList.Select(b => (float)b)), but I don't want to pay the performance penalty, either, if I can avoid it.
Short of copy-pasting the entire method and replacing "float" with "byte" (or vice versa), is there some decent solution ?
EDIT: I should've mentioned that I'm restricted to using .NET 3.5 for this project.
What you could do is create a generic interface that includes the operations that you want to support, create a generic factory to create instances for the supported types to perform the operations, and use it.
e.g.,
public interface IOperations<T>
{
T Add(T a, T b);
T Subtract(T a, T b);
T Multiply(T a, T b);
T Divide(T a, T b);
}
public static class Operations<T>
{
public static IOperations<T> Default { get { return Create(); } }
static IOperations<T> Create()
{
var type = typeof(T);
switch (Type.GetTypeCode(type))
{
case TypeCode.Byte:
return (IOperations<T>)new ByteOperations();
case TypeCode.Single:
return (IOperations<T>)new SingleOperations();
default:
var message = String.Format("Operations for type {0} is not supported.", type.Name);
throw new NotSupportedException(message);
}
}
class ByteOperations : IOperations<byte>
{
public byte Add(byte a, byte b) { return unchecked ((byte)(a + b)); }
public byte Subtract(byte a, byte b) { return unchecked ((byte)(a - b)); }
public byte Multiply(byte a, byte b) { return unchecked ((byte)(a * b)); }
public byte Divide(byte a, byte b) { return unchecked ((byte)(a / b)); }
}
class SingleOperations : IOperations<float>
{
public float Add(float a, float b) { return a + b; }
public float Subtract(float a, float b) { return a - b; }
public float Multiply(float a, float b) { return a * b; }
public float Divide(float a, float b) { return a / b; }
}
}
T Mean<T>(IList<T> numbers)
{
var operations = Operations<T>.Default;
var sum = numbers.Aggregate(operations.Add);
var count = (T)Convert.ChangeType(numbers.Count, typeof(T));
return operations.Divide(sum, count);
}
var resultByte = Mean(new byte[] { 1, 2, 3, 4 }); // 2
var resultSingle = Mean(new float[] { 1.1F, 2.1F, 3.1F, 4.1F }); // 2.6F
var resultInt = Mean(new int[] { 1, 2, 3, 4 }); // not supported
If you don't mind a small performance hit, you could dynamically create the operations needed.
class GenericOperations<T> : IOperations<T>
{
public GenericOperations()
{
add = CreateLambda(Expression.Add);
subtract = CreateLambda(Expression.Subtract);
multiply = CreateLambda(Expression.Multiply);
divide = CreateLambda(Expression.Divide);
}
private Func<T, T, T> add, subtract, multiply, divide;
private static Func<T, T, T> CreateLambda(Func<Expression, Expression, BinaryExpression> op)
{
var a = Expression.Parameter(typeof(T), "a");
var b = Expression.Parameter(typeof(T), "b");
var body = op(a, b);
var expr = Expression.Lambda<Func<T, T, T>>(body, a, b);
return expr.Compile();
}
public T Add(T a, T b) { return add(a, b); }
public T Subtract(T a, T b) { return subtract(a, b); }
public T Multiply(T a, T b) { return multiply(a, b); }
public T Divide(T a, T b) { return divide(a, b); }
}
I don't know if this is the best method for your case but it is useful for similar cases too.
This can be done by using the dynamic keyword. What dynamic will do is it will not do the compile time checks until runtime.
Here is a small sample program to show how it works.
class Program
{
static void Main()
{
List<byte> bytes = new List<byte>();
bytes.Add(2);
bytes.Add(1);
List<float> floats = new List<float>();
floats.Add(2.5F);
floats.Add(1F);
Console.WriteLine(DoStuff(bytes));
Console.WriteLine(DoStuff(floats));
Console.ReadLine();
}
static dynamic DoStuff(IList items)
{
dynamic item0 = items[0];
dynamic item1 = items[1];
return item0 - item1;
}
}
Unfortunately in my quick testing I could not make IList<dynamic> work however using the non generic IList then accessing the members as a dynamic works fine.
Create classes to wrap the underlying values, and have them each implement an interface with the operations you need. Then, use ILists of that interface instead of the raw values.

C# Memoization of functions with arbitrary number of arguments [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 4 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
I'm trying to create a memoization interface for functions with arbitrary number of arguments, but I'm failing miserably I feel like my solution is not very flexible. I tried to define an interface for a function which gets memoized automatically upon execution and each function will have to implement this interface. Here is an example with a two parameter Exponential Moving Average function:
class EMAFunction:IFunction
{
Dictionary<List<object>, List<object>> map;
class EMAComparer : IEqualityComparer<List<object>>
{
private int _multiplier = 97;
public bool Equals(List<object> a, List<object> b)
{
List<object> aVals = (List<object>)a[0];
int aPeriod = (int)a[1];
List<object> bVals = (List<object>)b[0];
int bPeriod = (int)b[1];
return (aVals.Count == bVals.Count) && (aPeriod == bPeriod);
}
public int GetHashCode(List<object> obj)
{
// Don't compute hash code on null object.
if (obj == null)
{
return 0;
}
List<object> vals = (List<object>) obj[0];
int period = (int) obj[1];
return (_multiplier * period.GetHashCode()) + vals.Count;
}
}
public EMAFunction()
{
NumParams = 2;
Name = "EMA";
map = new Dictionary<List<object>, List<object>>(new EMAComparer());
}
#region IFunction Members
public int NumParams
{
get;
set;
}
public string Name
{
get;
set;
}
public object Execute(List<object> parameters)
{
if (parameters.Count != NumParams)
throw new ArgumentException("The num params doesn't match!");
if (!map.ContainsKey(parameters))
{
//map.Add(parameters,
List<double> values = new List<double>();
List<object> asObj = (List<object>)parameters[0];
foreach (object val in asObj)
{
values.Add((double)val);
}
int period = (int)parameters[1];
asObj.Clear();
List<double> ema = TechFunctions.ExponentialMovingAverage(values, period);
foreach (double val in ema)
{
asObj.Add(val);
}
map.Add(parameters, asObj);
}
return map[parameters];
}
public void ClearMap()
{
map.Clear();
}
#endregion
}
Here are my tests of the function:
private void MemoizeTest()
{
DataSet dataSet = DataLoader.LoadData(DataLoader.DataSource.FROM_WEB, 1024);
List<String> labels = dataSet.DataLabels;
Stopwatch sw = new Stopwatch();
IFunction emaFunc = new EMAFunction();
List<object> parameters = new List<object>();
int numRuns = 1000;
long sumTicks = 0;
parameters.Add(dataSet.GetValues("open"));
parameters.Add(12);
// First call
for(int i = 0; i < numRuns; ++i)
{
emaFunc.ClearMap();// remove any memoization mappings
sw.Start();
emaFunc.Execute(parameters);
sw.Stop();
sumTicks += sw.ElapsedTicks;
sw.Reset();
}
Console.WriteLine("Average ticks not-memoized " + (sumTicks/numRuns));
sumTicks = 0;
// Repeat call
for (int i = 0; i < numRuns; ++i)
{
sw.Start();
emaFunc.Execute(parameters);
sw.Stop();
sumTicks += sw.ElapsedTicks;
sw.Reset();
}
Console.WriteLine("Average ticks memoized " + (sumTicks/numRuns));
}
Update:
Thanks for pointing out my n00bish error... I always forget to call Reset on the stopwatch!
I've seen another approach to memoization as well... it doesn't offer n-argument memoization, but my approach with the Interface is not much more advantageous since I have to write a class for each function. Is there a reasonable way that I can merge these ideas into something more robust? I want to make it easier to memoize a function without making the user write a class for each function that they intend to use.
How about this? First write a one-argument memoizer:
static Func<A, R> Memoize<A, R>(this Func<A, R> f)
{
var d = new Dictionary<A, R>();
return a=>
{
R r;
if (!d.TryGetValue(a, out r))
{
r = f(a);
d.Add(a, r);
}
return r;
};
}
Straightforward. Now write a function tuplifier:
static Func<Tuple<A, B>, R> Tuplify<A, B, R>(this Func<A, B, R> f)
{
return t => f(t.Item1, t.Item2);
}
And a detuplifier:
static Func<A, B, R> Detuplify<A, B, R>(this Func<Tuple<A, B>, R> f)
{
return (a, b) => f(Tuple.Create(a, b));
}
and now a two-argument memoizer is easy:
static Func<A, B, R> Memoize<A, B, R>(this Func<A, B, R> f)
{
return f.Tuplify().Memoize().Detuplify();
}
To write a three-argument memoizer just keep following this pattern: make a 3-tuplifier, a 3-untuplifier, and a 3-memoizer.
Of course, if you don't need them, there's no need to make the tuplifiers nominal methods:
static Func<A, B, R> Memoize<A, B, R>(this Func<A, B, R> f)
{
Func<Tuple<A, B>, R> tuplified = t => f(t.Item1, t.Item2);
Func<Tuple<A, B>, R> memoized = tuplified.Memoize();
return (a, b) => memoized(Tuple.Create(a, b));
}
UPDATE: You ask what to do if there is no tuple type. You could write your own; it's not hard. Or you could use anonymous types:
static Func<T, R> CastByExample<T, R>(Func<T, R> f, T t) { return f; }
static Func<A, B, R> Memoize<A, B, R>(this Func<A, B, R> f)
{
var example = new { A=default(A), B=default(B) };
var tuplified = CastByExample(t => f(t.A, t.B), example);
var memoized = tuplified.Memoize();
return (a, b) => memoized(new {A=a, B=b});
}
Slick, eh?
UPDATE: C# 7 now has value tuples built in to the language; use them rather than rolling your own or using anonymous types.
First, you need to call sw.Reset() between your tests. Otherwise your results for the second test will be in addition to the time from the first.
Second, you probably shouldn't use vals.GetHashCode() in your GetHashCode() override on the comparer, as this will lead you to getting different hash codes for objects that would evaluate to true for your Equals override. For now, I would worry about making sure that equivalent objects always get the same hash code rather than trying to get an even distribution of the codes. If the hash codes don't match, Equals will never be called, so you'll end up processing the same parameters multiple times.
StopWatch.Stop does not reset the stopwatch so you are accumulating time on each start/stop.
For example
Stopwatch sw = new Stopwatch();
sw.Start();
System.Threading.Thread.Sleep(100);
sw.Stop();
Debug.WriteLine(sw.ElapsedTicks);
sw.Start();
System.Threading.Thread.Sleep(100);
sw.Stop();
Debug.WriteLine(sw.ElapsedTicks);
Gives the following results
228221
454626
You can use StopWatch.Restart (Framework 4.0) to restart the stopwatch each time, or if not Framework 4.0, you can use StopWatch.Reset to reset the stopwatch.
Alternative (to tuples & anonymous types) approach might be as follows:
static void Main(string[] args)
{
var func = Memoize<int, int, int>(Func);
Console.WriteLine(func(3)(4));
Console.WriteLine(func(3)(5));
Console.WriteLine(func(2)(5));
Console.WriteLine(func(3)(4));
}
//lets pretend this is very-expensive-to-compute function
private static int Func(int i, int j)
{
return i + j;
}
private static Func<TArg1, Func<TArg2, TRes>> Memoize<TArg1, TArg2, TRes>(Func<TArg1, TArg2, TRes> func)
{
Func<TArg1, Func<TArg2, TRes>> func1 =
Memoize((TArg1 arg1) => Memoize((TArg2 arg2) => func(arg1, arg2)));
return func1;
}
private static Func<TArg, TRes> Memoize<TArg, TRes>(Func<TArg, TRes> func)
{
var cache = new Dictionary<TArg, TRes>();
return arg =>
{
TRes res;
if( !cache.TryGetValue(arg, out res) )
{
Console.WriteLine("Calculating " + arg.ToString());
res = func(arg);
cache.Add(arg, res);
}
else
{
Console.WriteLine("Getting from cache " + arg.ToString());
}
return res;
};
}
Based on these two Memoize funcs you can easily build extensions for as many args as you wish.
I initially came here just looking for an abstract memoization method for a no-parameter function. This isn't exactly an answer to the question but wanted to share my solution in case someone else came looking for the simple case.
public static class MemoizationExtensions
{
public static Func<R> Memoize<R>(this Func<R> f)
{
bool hasBeenCalled = false; // Used to determine if we called the function and the result was the same as default(R)
R returnVal = default(R);
return () =>
{
// Should be faster than doing null checks and if we got a null the first time,
// we really want to memoize that result and not inadvertently call the function again.
if (!hasBeenCalled)
{
hasBeenCalled = true;
returnVal = f();
}
return returnVal;
};
}
}
If you use LinqPad you can use the following code to easily test out the functionality through the use of LinqPad's super cool Dump method.
new List<Func<object>>(new Func<object>[] {
() => { "Entered func A1".Dump(); return 1; },
() => { "Entered func A2".Dump(); return default(int); },
() => { "Entered func B1".Dump(); return String.Empty; },
() => { "Entered func B2".Dump(); return default(string); },
() => { "Entered func C1".Dump(); return new {Name = String.Empty}; },
() => { "Entered func C2".Dump(); return null; },
})
.ForEach(f => {
var f1 = MemoizationExtensions.Memoize(f);
Enumerable
.Range(1,3)
.Select(i=>new {Run=i, Value=f1()})
.Dump();
});
P.S. You will need to include the MemoizationExtensions class in the code of the LinqPad script otherwise it won't work!

Closest C# equivalent to the F# match expression?

I'm in the situation where a lot of my classes are containers of well-known but unordered objects of different types, e.g. a container may look as follows:
public class Container
{
public A A { get; private set; }
public B B { get; private set; }
public C C { get; private set; }
public bool StoreIfKnown(object o)
{
// TODO...
}
}
So if o is of type A it should be stored in the A property, type B in the B property and so on.
In F# the StoreIfKnown method could be written something like the following (excuse the syntax errors, my F# is not great and quite rusty):
match o with
| ?: A a -> A <- a; true
| ?: B b -> B <- b; true
| ?: C c -> C <- c; true
| _ -> false
But in C# the only way seems to be the rather verbose:
if (o is A)
{
this.A = (A)o;
return true;
}
if (o is B)
{
this.B = (B)o;
return true;
}
// etc.
return false;
I could do it with the as keyword to avoid the test/cast pattern which would be faster, but is even more verbose.
Is there any elegant way to do this in C#?
You could author an extension method on 'o' and helper classes to enable a programming model like
o.Match<A>( a => { this.A = a; return true; } )
.Match<B>( b => { this.B = b; return true; } )
.Else( () => { return false; } )
But be wary of doing too much DSL-like hackery here, lest you end up with an API only you understand.
See also
http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx
Its not as nifty as Brian's solution, but this doesn't require defining a new DSL. You'll notice your repeating the following code:
if (o is {DataType})
{
{Property} = ({DataType})o;
return true;
}
Its easy enough to pull that template into its own method, resulting in something like this:
public class Container
{
public A A { get; private set; }
public B B { get; private set; }
public C C { get; private set; }
private bool TestProp<T>(object o, Action<T> f)
{
if (o is T)
return false;
f((T)o);
return true;
}
public bool StoreIfKnown(object o)
{
return
TestProp<A>(o, x => A = x) ||
TestProp<B>(o, x => B = x) ||
TestProp<C>(o, x => C = x) ||
false;
}
}
If you're working with reference types, you can take advantage of type inference with the following adjustments:
private bool TestProp<T>(T o, Action<T> f)
{
if (o == null)
return false;
f(o);
return true;
}
public bool StoreIfKnown(object o)
{
return
TestProp(o as A, x => A = x) ||
TestProp(o as B, x => B = x) ||
TestProp(o as C, x => C = x) ||
false;
}
I've been playing around with a little match builder (inspired by Brian's answer) which allows type checking, guard clauses, and returning of a result from the whole thing. It uses type inference so the only place you need to specify a type is where you actually want to.
So, imagining type C has an IsActive property which we want to be true, it would look something like this:
var stored = Match.Against(o)
.When<A>().Then(a => { this.A = a; return true; })
.When<B>().Then(b => { this.B = b; return true; })
.When<C>(c => c.IsActive).Then(c => { this.C = c; return true; })
.Otherwise(a => false);
Which I think is pretty readable, especially as it allows a predicate to be run against the derived type before actually matching which is something I do need.
The code is quite lengthy as it needs a number of partially-specified builder classes in the background to allow the type inference to work, so I can't really post it here. But if anyone's interested let me know in the comments and I'll stick it up on my blog and put a link here.
Bart de Smet once went crazy with pattern matching, starting here (goes all the way up to part 8). If you ever manage to get through all this content there shouldn't be any questions left to pattern matching in C#. If there are, they probably cannot be answered by stackoverflow :)
As of August 2016 and preview of C# 7.0, there is a limited support for pattern matching. You can try if by using Visual Studio “15” Preview 4.
According to the MSDN blog, you can use patterns in two places:
on the right-hand side of is expressions
in the case clauses in switch statements
Possible patterns are:
Constant patterns of the form c (where c is a constant expression in C#), which test that the input is equal to c
Type patterns of the form T x (where T is a type and x is an identifier), which test that the input has type T, and if so, extracts the value of the input into a fresh variable x of type T
Var patterns of the form var x (where x is an identifier), which always match, and simply put the value of the input into a fresh variable x with the same type as the input
I didn't install Visual Studio 15, so I'm not sure I rewrote your code correctly, but it should not be far off:
public class Container
{
public A A { get; private set; }
public B B { get; private set; }
public C C { get; private set; }
public bool StoreIfKnown(object obj)
{
switch (obj)
{
case A a:
this.A = a
// I don't put "break" because I'm returning value from a method
return true;
case B b:
this.B = b
return true;
case C c:
this.C = c
return true;
default:
WriteLine("<other>");
return false;
}
}
}

Mathematical function differentiation with C#?

I see that I can declare a function with (say)
public double Function(double parameter)
but what if I do want to take the derivative of that function?
You can't calculate the exact derivative of a function using a computer program (unless you're doing symbolic math... but that's another, way more complicated, topic).
There are several approaches to computing a numerical derivative of a function. The simplest is the centered three-point method:
Take a small number h
Evaluate [f(x+h) - f(x-h)] / 2h
Voilà, an approximation of f'(x), with only two function evaluations
Another approach is the centered five-point method:
Take a small number h
Evaluate [f(x-2h) - 8f(x-h) + 8f(x+h) - f(x+2h)] / 12h
Voilà, a better approximation of f'(x), but it requires more function evaluations
Another topic is how to implement this using C#. First, you need a delegate that represents a function that maps a subset of the real numbers onto a another subset of the real numbers:
delegate double RealFunction(double arg);
Then, you need a routing that evaluates the derivative:
public double h = 10e-6; // I'm not sure if this is valid C#, I'm used to C++
static double Derivative(RealFunction f, double arg)
{
double h2 = h*2;
return (f(x-h2) - 8*f(x-h) + 8*f(x+h) - f(x+h2)) / (h2*6);
}
If you want an object-oriented implementation, you should create the following classes:
interface IFunction
{
// Since operator () can't be overloaded, we'll use this trick.
double this[double arg] { get; }
}
class Function : IFunction
{
RealFunction func;
public Function(RealFunction func)
{ this.func = func; }
public double this[double arg]
{ get { return func(arg); } }
}
class Derivative : IFunction
{
IFunction func;
public static double h = 10e-6;
public Derivative(IFunction func)
{ this.func = func; }
public double this[double arg]
{
get
{
double h2 = h*2;
return (
func[arg - h2] - func[arg + h2] +
( func[arg + h] - func[arg - h] ) * 8
) / (h2 * 6);
}
}
}
If you're thinking of symbolic manipulation of formulae then you're better off doing your derivations in languages like Maple or Mathematica. They're designed for symbolic computation.
EDIT: If Maple and Mathematica are too expensive for you then there are other options. Wikipedia has a fairly complete listing of computer algebra packages. http://en.wikipedia.org/wiki/Comparison_of_computer_algebra_systems
Are you thinking of Lambda Expressions?
Basically you can pass a function into a function.
So think of a Sort on an object.
Depending on the nature of the object would help determine how the objects are sorted.
But you can still create a generic sort function then pass in how to compare objects.
Another approach can be to leverage the extensions methods using the well-known definition of the derivative number and compute its approximation accordingly.
As it has already been mentioned, this is pretty easy for a numeric approach not a symbolic one:
public partial static class IEnumerableExtensions
{
public static IEnumerable<Double> Derivate1<TSource>(this IEnumerable<TSource> source, Func<TSource, Double> selectorX, Func<TSource, Double> selectorY)
{
var enumerator = source.GetEnumerator();
enumerator.Reset();
enumerator.MoveNext();
var itemPrevious = enumerator.Current;
var itemNext = default(TSource);
while (enumerator.MoveNext())
{
itemNext = enumerator.Current;
var itemPreviousX = selectorX(itemPrevious);
var itemPreviousY = selectorY(itemPrevious);
var itemNextX = selectorX(itemNext);
var itemNextY = selectorY(itemNext);
var derivative = (itemNextY - itemPreviousY) / (itemNextX - itemPreviousX);
yield return derivative;
itemPrevious = itemNext;
}
}
}
or if you are more into a foreach fashion
public partial static class IEnumerableExtensions
{
public static IEnumerable<Double> Derivate2<TSource>(IEnumerable<TSource> source, Func<TSource, Double> selectorX, Func<TSource, Double> selectorY)
{
var itemPrevious = source.First();
source = source.Skip(1);
foreach (var itemNext in source)
{
var itemPreviousX = selectorX(itemPrevious);
var itemPreviousY = selectorY(itemPrevious);
var itemNextX = selectorX(itemNext);
var itemNextY = selectorY(itemNext);
var derivative = (itemNextY - itemPreviousY) / (itemNextX - itemPreviousX);
yield return derivative;
itemPrevious = itemNext;
}
}
}
You can refactor everything as below:
public static partial class MathHelpers
{
public static Double Derivate(Double xPrevious, Double xNext, Double yPrevious, Double yNext)
{
var derivative = (yNext - yPrevious)/(xNext - xPrevious);
return derivative;
}
}
public static class IEnumerableExtensions
{
public static IEnumerable<Double> Derivate<TSource>(IEnumerable<TSource> source, Func<TSource, Double> selectorX, Func<TSource, Double> selectorY)
{
var itemPrevious = source.First();
source = source.Skip(1);
foreach (var itemNext in source)
{
var derivative = MathHelpers.Derivate(selectorX(itemPrevious), selectorX(itemNext), selectorY(itemPrevious), selectorY(itemNext));
yield return derivative;
itemPrevious = itemNext;
}
}
}
If you have written the function, it's already been derived.
And given that it's an int function, I'll assume you don't mean the calculus definition of "derive".

Is there a better alternative than this to 'switch on type'?

Seeing as C# can't switch on a Type (which I gather wasn't added as a special case because is relationships mean that more than one distinct case might apply), is there a better way to simulate switching on type other than this?
void Foo(object o)
{
if (o is A)
{
((A)o).Hop();
}
else if (o is B)
{
((B)o).Skip();
}
else
{
throw new ArgumentException("Unexpected type: " + o.GetType());
}
}
With C# 7, which shipped with Visual Studio 2017 (Release 15.*), you are able to use Types in case statements (pattern matching):
switch(shape)
{
case Circle c:
WriteLine($"circle with radius {c.Radius}");
break;
case Rectangle s when (s.Length == s.Height):
WriteLine($"{s.Length} x {s.Height} square");
break;
case Rectangle r:
WriteLine($"{r.Length} x {r.Height} rectangle");
break;
default:
WriteLine("<unknown shape>");
break;
case null:
throw new ArgumentNullException(nameof(shape));
}
With C# 6, you can use a switch statement with the nameof() operator (thanks #Joey Adams):
switch(o.GetType().Name) {
case nameof(AType):
break;
case nameof(BType):
break;
}
With C# 5 and earlier, you could use a switch statement, but you'll have to use a magic string containing the type name... which is not particularly refactor friendly (thanks #nukefusion)
switch(o.GetType().Name) {
case "AType":
break;
}
Switching on types is definitely lacking in C# (UPDATE: in C#7 / VS 2017 switching on types is supported - see Zachary Yates's answer). In order to do this without a large if/else if/else statement, you'll need to work with a different structure. I wrote a blog post awhile back detailing how to build a TypeSwitch structure.
https://learn.microsoft.com/archive/blogs/jaredpar/switching-on-types
Short version: TypeSwitch is designed to prevent redundant casting and give a syntax that is similar to a normal switch/case statement. For example, here is TypeSwitch in action on a standard Windows form event
TypeSwitch.Do(
sender,
TypeSwitch.Case<Button>(() => textBox1.Text = "Hit a Button"),
TypeSwitch.Case<CheckBox>(x => textBox1.Text = "Checkbox is " + x.Checked),
TypeSwitch.Default(() => textBox1.Text = "Not sure what is hovered over"));
The code for TypeSwitch is actually pretty small and can easily be put into your project.
static class TypeSwitch {
public class CaseInfo {
public bool IsDefault { get; set; }
public Type Target { get; set; }
public Action<object> Action { get; set; }
}
public static void Do(object source, params CaseInfo[] cases) {
var type = source.GetType();
foreach (var entry in cases) {
if (entry.IsDefault || entry.Target.IsAssignableFrom(type)) {
entry.Action(source);
break;
}
}
}
public static CaseInfo Case<T>(Action action) {
return new CaseInfo() {
Action = x => action(),
Target = typeof(T)
};
}
public static CaseInfo Case<T>(Action<T> action) {
return new CaseInfo() {
Action = (x) => action((T)x),
Target = typeof(T)
};
}
public static CaseInfo Default(Action action) {
return new CaseInfo() {
Action = x => action(),
IsDefault = true
};
}
}
One option is to have a dictionary from Type to Action (or some other delegate). Look up the action based on the type, and then execute it. I've used this for factories before now.
With JaredPar's answer in the back of my head, I wrote a variant of his TypeSwitch class that uses type inference for a nicer syntax:
class A { string Name { get; } }
class B : A { string LongName { get; } }
class C : A { string FullName { get; } }
class X { public string ToString(IFormatProvider provider); }
class Y { public string GetIdentifier(); }
public string GetName(object value)
{
string name = null;
TypeSwitch.On(value)
.Case((C x) => name = x.FullName)
.Case((B x) => name = x.LongName)
.Case((A x) => name = x.Name)
.Case((X x) => name = x.ToString(CultureInfo.CurrentCulture))
.Case((Y x) => name = x.GetIdentifier())
.Default((x) => name = x.ToString());
return name;
}
Note that the order of the Case() methods is important.
Get the full and commented code for my TypeSwitch class. This is a working abbreviated version:
public static class TypeSwitch
{
public static Switch<TSource> On<TSource>(TSource value)
{
return new Switch<TSource>(value);
}
public sealed class Switch<TSource>
{
private readonly TSource value;
private bool handled = false;
internal Switch(TSource value)
{
this.value = value;
}
public Switch<TSource> Case<TTarget>(Action<TTarget> action)
where TTarget : TSource
{
if (!this.handled && this.value is TTarget)
{
action((TTarget) this.value);
this.handled = true;
}
return this;
}
public void Default(Action<TSource> action)
{
if (!this.handled)
action(this.value);
}
}
}
You can use pattern matching in C# 7 or above:
switch (foo.GetType())
{
case var type when type == typeof(Player):
break;
case var type when type == typeof(Address):
break;
case var type when type == typeof(Department):
break;
case var type when type == typeof(ContactType):
break;
default:
break;
}
Create a superclass (S) and make A and B inherit from it. Then declare an abstract method on S that every subclass needs to implement.
Doing this the "foo" method can also change its signature to Foo(S o), making it type safe, and you don't need to throw that ugly exception.
C# 8 enhancements of pattern matching made it possible to do it like this. In some cases it do the job and more concise.
public Animal Animal { get; set; }
...
var animalName = Animal switch
{
Cat cat => "Tom",
Mouse mouse => "Jerry",
_ => "unknown"
};
Yes, thanks to C# 7 that can be achieved. Here's how it's done (using expression pattern):
switch (o)
{
case A a:
a.Hop();
break;
case B b:
b.Skip();
break;
case C _:
return new ArgumentException("Type C will be supported in the next version");
default:
return new ArgumentException("Unexpected type: " + o.GetType());
}
If you were using C# 4, you could make use of the new dynamic functionality to achieve an interesting alternative. I'm not saying this is better, in fact it seems very likely that it would be slower, but it does have a certain elegance to it.
class Thing
{
void Foo(A a)
{
a.Hop();
}
void Foo(B b)
{
b.Skip();
}
}
And the usage:
object aOrB = Get_AOrB();
Thing t = GetThing();
((dynamic)t).Foo(aorB);
The reason this works is that a C# 4 dynamic method invocation has its overloads resolved at runtime rather than compile time. I wrote a little more about this idea quite recently. Again, I would just like to reiterate that this probably performs worse than all the other suggestions, I am offering it simply as a curiosity.
You should really be overloading your method, not trying to do the disambiguation yourself. Most of the answers so far don't take future subclasses into account, which may lead to really terrible maintenance issues later on.
For built-in types, you can use the TypeCode enumeration. Please note that GetType() is kind of slow, but probably not relevant in most situations.
switch (Type.GetTypeCode(someObject.GetType()))
{
case TypeCode.Boolean:
break;
case TypeCode.Byte:
break;
case TypeCode.Char:
break;
}
For custom types, you can create your own enumeration, and either an interface or a base class with abstract property or method...
Abstract class implementation of property
public enum FooTypes { FooFighter, AbbreviatedFool, Fubar, Fugu };
public abstract class Foo
{
public abstract FooTypes FooType { get; }
}
public class FooFighter : Foo
{
public override FooTypes FooType { get { return FooTypes.FooFighter; } }
}
Abstract class implementation of method
public enum FooTypes { FooFighter, AbbreviatedFool, Fubar, Fugu };
public abstract class Foo
{
public abstract FooTypes GetFooType();
}
public class FooFighter : Foo
{
public override FooTypes GetFooType() { return FooTypes.FooFighter; }
}
Interface implementation of property
public enum FooTypes { FooFighter, AbbreviatedFool, Fubar, Fugu };
public interface IFooType
{
FooTypes FooType { get; }
}
public class FooFighter : IFooType
{
public FooTypes FooType { get { return FooTypes.FooFighter; } }
}
Interface implementation of method
public enum FooTypes { FooFighter, AbbreviatedFool, Fubar, Fugu };
public interface IFooType
{
FooTypes GetFooType();
}
public class FooFighter : IFooType
{
public FooTypes GetFooType() { return FooTypes.FooFighter; }
}
One of my coworkers just told me about this too: This has the advantage that you can use it for literally any type of object, not just ones that you define. It has the disadvantage of being a bit larger and slower.
First define a static class like this:
public static class TypeEnumerator
{
public class TypeEnumeratorException : Exception
{
public Type unknownType { get; private set; }
public TypeEnumeratorException(Type unknownType) : base()
{
this.unknownType = unknownType;
}
}
public enum TypeEnumeratorTypes { _int, _string, _Foo, _TcpClient, };
private static Dictionary<Type, TypeEnumeratorTypes> typeDict;
static TypeEnumerator()
{
typeDict = new Dictionary<Type, TypeEnumeratorTypes>();
typeDict[typeof(int)] = TypeEnumeratorTypes._int;
typeDict[typeof(string)] = TypeEnumeratorTypes._string;
typeDict[typeof(Foo)] = TypeEnumeratorTypes._Foo;
typeDict[typeof(System.Net.Sockets.TcpClient)] = TypeEnumeratorTypes._TcpClient;
}
/// <summary>
/// Throws NullReferenceException and TypeEnumeratorException</summary>
/// <exception cref="System.NullReferenceException">NullReferenceException</exception>
/// <exception cref="MyProject.TypeEnumerator.TypeEnumeratorException">TypeEnumeratorException</exception>
public static TypeEnumeratorTypes EnumerateType(object theObject)
{
try
{
return typeDict[theObject.GetType()];
}
catch (KeyNotFoundException)
{
throw new TypeEnumeratorException(theObject.GetType());
}
}
}
And then you can use it like this:
switch (TypeEnumerator.EnumerateType(someObject))
{
case TypeEnumerator.TypeEnumeratorTypes._int:
break;
case TypeEnumerator.TypeEnumeratorTypes._string:
break;
}
I liked Virtlink's use of implicit typing to make the switch much more readable, but I didn't like that an early-out isn't possible, and that we're doing allocations. Let's turn up the perf a little.
public static class TypeSwitch
{
public static void On<TV, T1>(TV value, Action<T1> action1)
where T1 : TV
{
if (value is T1) action1((T1)value);
}
public static void On<TV, T1, T2>(TV value, Action<T1> action1, Action<T2> action2)
where T1 : TV where T2 : TV
{
if (value is T1) action1((T1)value);
else if (value is T2) action2((T2)value);
}
public static void On<TV, T1, T2, T3>(TV value, Action<T1> action1, Action<T2> action2, Action<T3> action3)
where T1 : TV where T2 : TV where T3 : TV
{
if (value is T1) action1((T1)value);
else if (value is T2) action2((T2)value);
else if (value is T3) action3((T3)value);
}
// ... etc.
}
Well, that makes my fingers hurt. Let's do it in T4:
<## template debug="false" hostSpecific="true" language="C#" #>
<## output extension=".cs" #>
<## Assembly Name="System.Core.dll" #>
<## import namespace="System.Linq" #>
<## import namespace="System.IO" #>
<#
string GenWarning = "// THIS FILE IS GENERATED FROM " + Path.GetFileName(Host.TemplateFile) + " - ANY HAND EDITS WILL BE LOST!";
const int MaxCases = 15;
#>
<#=GenWarning#>
using System;
public static class TypeSwitch
{
<# for(int icase = 1; icase <= MaxCases; ++icase) {
var types = string.Join(", ", Enumerable.Range(1, icase).Select(i => "T" + i));
var actions = string.Join(", ", Enumerable.Range(1, icase).Select(i => string.Format("Action<T{0}> action{0}", i)));
var wheres = string.Join(" ", Enumerable.Range(1, icase).Select(i => string.Format("where T{0} : TV", i)));
#>
<#=GenWarning#>
public static void On<TV, <#=types#>>(TV value, <#=actions#>)
<#=wheres#>
{
if (value is T1) action1((T1)value);
<# for(int i = 2; i <= icase; ++i) { #>
else if (value is T<#=i#>) action<#=i#>((T<#=i#>)value);
<#}#>
}
<#}#>
<#=GenWarning#>
}
Adjusting Virtlink's example a little:
TypeSwitch.On(operand,
(C x) => name = x.FullName,
(B x) => name = x.LongName,
(A x) => name = x.Name,
(X x) => name = x.ToString(CultureInfo.CurrentCulture),
(Y x) => name = x.GetIdentifier(),
(object x) => name = x.ToString());
Readable and fast. Now, as everybody keeps pointing out in their answers, and given the nature of this question, order is important in the type matching. Therefore:
Put leaf types first, base types later.
For peer types, put more likely matches first to maximize perf.
This implies that there is no need for a special default case. Instead, just use the base-most type in the lambda, and put it last.
Given inheritance facilitates an object to be recognized as more than one type, I think a switch could lead to bad ambiguity. For example:
Case 1
{
string s = "a";
if (s is string) Print("Foo");
else if (s is object) Print("Bar");
}
Case 2
{
string s = "a";
if (s is object) Print("Foo");
else if (s is string) Print("Bar");
}
Because s is a string and an object.
I think when you write a switch(foo) you expect foo to match one and only one of the case statements. With a switch on types, the order in which you write your case statements could possibly change the result of the whole switch statement. I think that would be wrong.
You could think of a compiler-check on the types of a "typeswitch" statement, checking that the enumerated types do not inherit from each other. That doesn't exist though.
foo is T is not the same as foo.GetType() == typeof(T)!!
Should work with
case type _:
like:
int i = 1;
bool b = true;
double d = 1.1;
object o = i; // whatever you want
switch (o)
{
case int _:
Answer.Content = "You got the int";
break;
case double _:
Answer.Content = "You got the double";
break;
case bool _:
Answer.Content = "You got the bool";
break;
}
As per C# 7.0 specification, you can declare a local variable scoped in a case of a switch:
object a = "Hello world";
switch (a)
{
case string myString:
// The variable 'a' is a string!
break;
case int myInt:
// The variable 'a' is an int!
break;
case Foo myFoo:
// The variable 'a' is of type Foo!
break;
}
This is the best way to do such a thing because it involves just casting and push-on-the-stack operations, which are among the fastest operations an interpreter can run, just preceded by bitwise operations and boolean conditions.
As compared to using Dictionary<K, V>, here's much less memory usage and basically zero computation.
This, on the other hand, should be as fast (if not faster, even) as using a chain of if statements:
object a = "Hello world";
if (a is string)
{
// The variable 'a' is a string!
} else if (a is int)
{
// The variable 'a' is an int!
} // etc.
I would either
use method overloading (just like x0n), or
use subclasses (just like Pablo), or
apply the visitor pattern.
Another way would be to define an interface IThing and then implement it in both classes
here's the snipet:
public interface IThing
{
void Move();
}
public class ThingA : IThing
{
public void Move()
{
Hop();
}
public void Hop(){
//Implementation of Hop
}
}
public class ThingA : IThing
{
public void Move()
{
Skip();
}
public void Skip(){
//Implementation of Skip
}
}
public class Foo
{
static void Main(String[] args)
{
}
private void Foo(IThing a)
{
a.Move();
}
}
If you know the class you are expecting but you still don't have an object you can even do this:
private string GetAcceptButtonText<T>() where T : BaseClass, new()
{
switch (new T())
{
case BaseClassReview _: return "Review";
case BaseClassValidate _: return "Validate";
case BaseClassAcknowledge _: return "Acknowledge";
default: return "Accept";
}
}
You can create overloaded methods:
void Foo(A a)
{
a.Hop();
}
void Foo(B b)
{
b.Skip();
}
void Foo(object o)
{
throw new ArgumentException("Unexpected type: " + o.GetType());
}
And cast the argument to dynamic type in order to bypass static type checking:
Foo((dynamic)something);
You're looking for Discriminated Unions which are a language feature of F#, but you can achieve a similar effect by using a library I made, called OneOf
https://github.com/mcintyre321/OneOf
The major advantage over switch (and if and exceptions as control flow) is that it is compile-time safe - there is no default handler or fall through
void Foo(OneOf<A, B> o)
{
o.Switch(
a => a.Hop(),
b => b.Skip()
);
}
If you add a third item to o, you'll get a compiler error as you have to add a handler Func inside the switch call.
You can also do a .Match which returns a value, rather than executes a statement:
double Area(OneOf<Square, Circle> o)
{
return o.Match(
square => square.Length * square.Length,
circle => Math.PI * circle.Radius * circle.Radius
);
}
I would create an interface with whatever name and method name that would make sense for your switch, let's call them respectively: IDoable that tells to implement void Do().
public interface IDoable
{
void Do();
}
public class A : IDoable
{
public void Hop()
{
// ...
}
public void Do()
{
Hop();
}
}
public class B : IDoable
{
public void Skip()
{
// ...
}
public void Do()
{
Skip();
}
}
and change the method as follows:
void Foo<T>(T obj)
where T : IDoable
{
// ...
obj.Do();
// ...
}
At least with that you are safe at the compilation-time and I suspect that performance-wise it's better than checking type at runtime.
Create an interface IFooable, then make your A and B classes to implement a common method, which in turn calls the corresponding method you want:
interface IFooable
{
public void Foo();
}
class A : IFooable
{
//other methods ...
public void Foo()
{
this.Hop();
}
}
class B : IFooable
{
//other methods ...
public void Foo()
{
this.Skip();
}
}
class ProcessingClass
{
public void Foo(object o)
{
if (o == null)
throw new NullRefferenceException("Null reference", "o");
IFooable f = o as IFooable;
if (f != null)
{
f.Foo();
}
else
{
throw new ArgumentException("Unexpected type: " + o.GetType());
}
}
}
Note, that it's better to use as instead first checking with is and then casting, as that way you make 2 casts, so it's more expensive.
I such cases I usually end up with a list of predicates and actions. Something along these lines:
class Mine {
static List<Func<object, bool>> predicates;
static List<Action<object>> actions;
static Mine() {
AddAction<A>(o => o.Hop());
AddAction<B>(o => o.Skip());
}
static void AddAction<T>(Action<T> action) {
predicates.Add(o => o is T);
actions.Add(o => action((T)o);
}
static void RunAction(object o) {
for (int i=0; o < predicates.Count; i++) {
if (predicates[i](o)) {
actions[i](o);
break;
}
}
}
void Foo(object o) {
RunAction(o);
}
}
With C# 8 onwards you can make it even more concise with the new switch. And with the use of discard option _ you can avoid creating innecesary variables when you don't need them, like this:
return document switch {
Invoice _ => "Is Invoice",
ShippingList _ => "Is Shipping List",
_ => "Unknown"
};
Invoice and ShippingList are classes and document is an object that can be either of them.
After having compared the options a few answers here provided to F# features, I discovered F# to have a way better support for type-based switching (although I'm still sticking to C#).
You might want to see here and here.
Try to go that way:
public void Test(BaseType #base)
{
switch (#base)
{
case ConcreteType concrete:
DoSomething(concrete);
break;
case AnotherConcrete concrete:
DoSomething(concrete);
break;
}
}
I agree with Jon about having a hash of actions to class name. If you keep your pattern, you might want to consider using the "as" construct instead:
A a = o as A;
if (a != null) {
a.Hop();
return;
}
B b = o as B;
if (b != null) {
b.Skip();
return;
}
throw new ArgumentException("...");
The difference is that when you use the patter if (foo is Bar) { ((Bar)foo).Action(); } you're doing the type casting twice. Now maybe the compiler will optimize and only do that work once - but I wouldn't count on it.
As Pablo suggests, interface approach is almost always the right thing to do to handle this. To really utilize switch, another alternative is to have a custom enum denoting your type in your classes.
enum ObjectType { A, B, Default }
interface IIdentifiable
{
ObjectType Type { get; };
}
class A : IIdentifiable
{
public ObjectType Type { get { return ObjectType.A; } }
}
class B : IIdentifiable
{
public ObjectType Type { get { return ObjectType.B; } }
}
void Foo(IIdentifiable o)
{
switch (o.Type)
{
case ObjectType.A:
case ObjectType.B:
//......
}
}
This is kind of implemented in BCL too. One example is MemberInfo.MemberTypes, another is GetTypeCode for primitive types, like:
void Foo(object o)
{
switch (Type.GetTypeCode(o.GetType())) // for IConvertible, just o.GetTypeCode()
{
case TypeCode.Int16:
case TypeCode.Int32:
//etc ......
}
}
This is an alternate answer that mixes contributions from JaredPar and VirtLink answers, with the following constraints:
The switch construction behaves as a function, and receives functions as parameters to cases.
Ensures that it is properly built, and there always exists a default function.
It returns after first match (true for JaredPar answer, not true for VirtLink one).
Usage:
var result =
TSwitch<string>
.On(val)
.Case((string x) => "is a string")
.Case((long x) => "is a long")
.Default(_ => "what is it?");
Code:
public class TSwitch<TResult>
{
class CaseInfo<T>
{
public Type Target { get; set; }
public Func<object, T> Func { get; set; }
}
private object _source;
private List<CaseInfo<TResult>> _cases;
public static TSwitch<TResult> On(object source)
{
return new TSwitch<TResult> {
_source = source,
_cases = new List<CaseInfo<TResult>>()
};
}
public TResult Default(Func<object, TResult> defaultFunc)
{
var srcType = _source.GetType();
foreach (var entry in _cases)
if (entry.Target.IsAssignableFrom(srcType))
return entry.Func(_source);
return defaultFunc(_source);
}
public TSwitch<TResult> Case<TSource>(Func<TSource, TResult> func)
{
_cases.Add(new CaseInfo<TResult>
{
Func = x => func((TSource)x),
Target = typeof(TSource)
});
return this;
}
}
Yes - just use the slightly weirdly named "pattern matching" from C#7 upwards to match on class or structure:
IObject concrete1 = new ObjectImplementation1();
IObject concrete2 = new ObjectImplementation2();
switch (concrete1)
{
case ObjectImplementation1 c1: return "type 1";
case ObjectImplementation2 c2: return "type 2";
}

Categories

Resources