Closest C# equivalent to the F# match expression? - c#

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;
}
}
}

Related

assert that all fields in 2 objects are the same c#

I am doing unit testing, and basically want to check that the data that 2 objects hold is the same
Assert.AreEqual(object1, object2);
Assert.IsTrue(object1.Equals(object2)); //this of course doesn't work
I am searching for the C# equivalent of assertJ
Assert.That(object1).isEqualToComparingFieldByField(object2)
You could either use records (c# 9 +) or you have to override the Equals method (if you have access and you can change the objects that you're working with).
Records example:
var point = new Point(3, 4);
var point2 = new Point(3, 4);
var test = point.Equals(point2); //this is true
public record Point(int X, int Y);
with classes:
public class Point
{
public int X { get; }
public int Y { get; }
public override bool Equals(object? obj)
{
if (obj == null)
return false;
return obj is Point point && (point.X == X && point.Y == Y);
}
public override int GetHashCode()
{
return HashCode.Combine(X, Y);
}
}
if you are not allowed to touch the implementation, then you could use serialization and compare the strings:
var obj1Str = JsonConvert.SerializeObject(object1);
var obj2Str = JsonConvert.SerializeObject(object2);
Assert.Equal(obj1Str, obj2Str);
using Newtonsoft.Json nuget
C# classes are reference equality, which means that variables are the same using the standard Equals and == if they point to the same object, you could override that behaivour, but it may break something now or in the future.
Or, you could switch to using a construct that's value equality by default, which structs as well as record classes are. If you can't (or don't want to) do that you can implement a value equals "helper" method yourself. I would not recommend overriding the Equals method or the == operator, as that can (and most likely will) lead to errors in the future instead I recommend you write your own ValueEquals method or extension method, something along the lines of
class Foo
{
public int Count {get; set;}
public string Message {get; set;}
}
public static bool ValueEquals(this Foo self, Foo other)
{
return self.Count == other.Count && self.Message == other.Message;
}
public void MyTest()
{
// Arrange and Act
...
// Assert
Assert.IsTrue(myFoo1.ValueEquals(myFoo2));
}
Depending on whether or not you can/ want to add a ValueEquals to your Foo class you can decide on doing it with an extension method or a normal method.
You could also implement a IEqualityComparer<T> like
public class FooValueEqualityComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo foo1, Foo foo2)
{
return foo1.Count == foo2.Count &&
foo1.Message == foo2.Message;
}
public int GetHashCode(Foo foo)
{
return foo.GetHashCode();
}
}
// Use it
public void MyTest()
{
// Arrange and Act
...
// Assert
Assert.IsTrue(new FooEqualityComparer().Equals(myFoo1, myFoo2));
}
Or, you could write a generic ValueEquals that works for all^* classes using Reflection:
public static class ValueEqualityComparer
{
public static bool ValueEquals<T>(this T self, T other) where T : class
{
var type = self.GetType();
if (type == typeof(string))
return self.Equals(other);
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var property in properties)
{
var selfValue = property.GetValue(self);
var otherValue = property.GetValue(other);
// String is special, it's not primitive but is value equality like primitives
if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
{
if (!selfValue.Equals(otherValue))
return false;
}
// If the property is a List value equals each member
// Maybe find another type that allows indexing and is less restrictive
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
var selfList = ((IEnumerable)property.GetValue(self)).Cast<object>();
var otherList = ((IEnumerable)property.GetValue(other)).Cast<object>();
try
{
// Using EquiZip from MoreLinq: https://github.com/morelinq/MoreLINQ/blob/master/MoreLinq/EquiZip.cs
foreach (var element in selfList.EquiZip(otherList, (selfItem, otherItem) => new { selfItem, otherItem }))
{
if (!ValueEquals(element.selfItem, element.otherItem))
return false;
}
}
catch (InvalidOperationException)
{
// MoreLINQ throws a InvalidOperationException if our two enumerables aren't the same length
return false;
}
}
else
{
if (!ValueEquals(selfValue, otherValue))
return false;
}
}
return true;
}
}
This implementation is by no means perfect, and should honestly only be used for UnitTests and also should be thoroughly tested itself. You can see my tests as a dotnetfiddle here
Or you could do it "dirty" and serialize the objects to a string and compare those values.

How to make a subclass constructor based on a parent class instance?

I have an Item and a subclass AdvancedItem (all made of value-types if that matters):
public Item
{
public string A;
public bool B;
public char C;
...// 20 fields
}
public AdvancedItem : Item
{
public string Z;
}
It's easy to simply create an Item or an AdvancedItem independently:
var item = new Item { A = "aa", B = true, C = 'c', ... };
var aItem = new AdvancedItem { A = "aa", B = true, C = 'c', ..., Z = "zz" };
Now, I just want to turn an Item into an AdvancedItem by providing it the string Z separately. In order to achieve that I was thinking of using a constructor.
Attempt A:
// annoying, we are not using the inheritance of AdvancedItem:Item
// so we will need to edit this whenever we change the class Item
public AdvancedItem(Item item, string z)
{
A = item.A;
B = item.B;
...;//many lines
Z = z;
}
Attempt B:
// to use inheritance it seems I need another constructor to duplicate itself
public Item(Item item)
{
A = item.A;
B = item.B;
...;//many lines
}
public AdvancedItem(Item item, string z) : base(Item)
{
Z = z;
}
Is there any way to improve this second attempt to avoid writing many lines of X = item.X? Maybe a solution to auto-clone or auto-duplicate a class with itself where public Item(Item item) would be wrote in one line?
Consider using AutoMapper to copy properties between objects.
This would allow the following:
Item a = new Item { A = 3, B = 'a', .... };
AdvancedItem advanced= Mapper.Map<AdvancedItem>(a);
string z = "Hello World";
advanced.Z = z;
Update
If you do not want to use AutoMapper you can use Reflection or better, Expressions. However this will make your code a bit more complex
Consider these two types:
class Item
{
public int A, B, C;
public string D, E, F;
private int privateInt;
public Item(int valueOfPrivateField)
{
privateInt = valueOfPrivateField;
}
}
class AdvancedItem : Item
{
public string G;
public AdvancedItem(int valueOfPrivateField) : base(valueOfPrivateField)
{
}
}
We can define a method that creates a field-wise copy expression. Since you mention that all your fields are value types we can just copy each field one by one to the other object:
private static void MapFields<T>(T target, T source)
{
Type type = typeof (T);
if (!Mappers.ContainsKey(type))
{
//build expression to copy fields from source to target;
var targetParam = Expression.Parameter(typeof(object));
var targetCasted = Expression.TypeAs(targetParam, typeof(T));
var sourceParam = Expression.Parameter(typeof(object));
var sourceCasted = Expression.TypeAs(sourceParam, typeof(T));
var setters = new List<Expression>();
//get all non-readonly fields
foreach (var fieldInfo in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where(f => !f.IsInitOnly))
{
Expression targetField = Expression.Field(targetCasted, fieldInfo);
Expression sourceField = Expression.Field(sourceCasted, fieldInfo);
setters.Add(Expression.Assign(targetField, sourceField));
}
Expression block = Expression.Block(setters);
var mapperFunction = Expression.Lambda<Action<object, object>>(block, targetParam,
sourceParam).Compile();
Mappers[type] = mapperFunction;
}
Mappers[type](target, source);
}
private static readonly Dictionary<Type, Action<object, object>> Mappers =
new Dictionary<Type, Action<object, object>>();
This caches functions that map all fields from the source to the target object, and should have close to the same performance as manually writing this.A = A, this.B = B etc.
Calling the method:
static void Main(string[] args)
{
var item = new Item(56) {A = 5, B = 6};
var advanced = new AdvancedItem(0);
MapFields(advanced, item);
int a = advanced.A; //5
int b = advanced.B; //6;
//note that advanced.privateInt == 56!
}
Please note that this code is more complex and less reliable than AutoMapper and is not recommended or ready for production systems.
One object-oriented way to implement this kind of thing for class hierarchies is to introduce a protected copy constructor in the base class (although it still requires you to write all the assignments):
public class Item
{
protected Item(Item other)
{
this.A = other.A;
this.B = other.B;
this.C = other.C;
}
public string A;
public bool B;
public char C;
// 20 fields
}
Then you would call that from the derived class like so:
public class AdvancedItem : Item
{
public AdvancedItem(Item item, string z): base(item)
{
Z = z;
}
public string Z;
}
Note that this approach does NOT prevent you from having to write all the assignment lines, but you only need to write them once, and it does mean that you now have a protected copy constructor available, which can be very useful. Also, the assignments are now all in the base class where they belong.
This approach is extendable to further derived classes. You can introduce a protected copy constructor to AdvancedItem written in terms of the public constructor (to avoid duplicated code).
For example:
public class AdvancedItem : Item
{
protected AdvancedItem(AdvancedItem other): this(other, other.Z)
{
}
public AdvancedItem(Item item, string z): base(item)
{
Z = z;
}
public string Z;
}
public class EvenMoreAdvancedItem: AdvancedItem
{
public EvenMoreAdvancedItem(AdvancedItem advancedItem, double q): base(advancedItem)
{
Q = q;
}
public double Q;
}
I would do something like this. Use a static factory method with a private constructor, and have a copy constructor defined in the base class.
AdvancedItem
{
Public Static AdvancedItem FromItem(Item i, string z)
{
AdvancedItem item = new AdvancedItem(i);
item.Z = z;
return item;
}
private AdvancedItem(Item i) : Base(i) {}
}
Then usage is AdvancedItem i = AdvancedItem.FromItem(item, extraThing);
Yes as suggested by Bas you can go with Automapper but along with it there is one another option is using Otis..I know Automapper is better than Otis but it can be considered as one option..
Check it out :-
http://code.google.com/p/otis-lib/
As socumented in official site :-
Otis is a .Net object transformation library, i.e. an object to object
mapper.
It automatically generates converter assemblies or classes which
convert instances of one type to instances of some other type. These
transformation can be described in type metadata using attributes, or
separately in an XML source (file, string, database)
Otis is intended to be used to solve some common design and
implementation tasks, e.g. to ease the implementation of support for
DTO classes (more here), or to convert business domain type instances
to presentation layer instances, but more generally, it can be used
anywhere where a transformation between different types is needed.
Otis removes the need to manually implement type converters.
Given that what you really want to do is serialize different parts of the object for different services, I would use Composition instead of Inheritance.
So you would have:
public Item
{
public string A;
public bool B;
public char C;
...// 20 fields
}
public AdvancedItem
{
[DataMember]
public Item baseItem;
[DataMember]
public string Z;
}
public Item(Item item)
{
A = item.A;
B = item.B;
...;//many lines
}
public AdvancedItem(Item item, string z)
{
baseItem = item; // or item.Clone();
Z = z;
}

Is it safe to use GetHashCode to compare identical Anonymous types?

Given two identical anonymous type objects:
{msg:"hello"} //anonType1
{msg:"hello"} //anonType2
And assume that they haven't resolved to the same type (e.g. they might be defined in different assemblies)
anonType1.Equals(anonType2); //false
Furthermore, assume that at compile time, I can't get the structure of one (say anonType1) because the API only exposes object
So, to compare them, I thought of the following techniques:
Use reflection to get the msg property on anonType1 for comparison.
Cast anonType1 to a dynamic type and reference .msg on the dynamic member for comparison
Compare the result of .GetHashCode() on each object.
My question is: Is it safe to use Option 3? I.e. is it sensible to assume that the .GetHashcode() implementation will always return the same value for indentically-structured, but different anonymous types in the current and all future versions of the .NET framework?
Interesting question. The specification defines that Equals and GetHashcode (note the typo in the specification!) methods will behave for instances of the same type, however the implementation is not defined. As it happens, the current MS C# compiler implements this using magic numbers like a seed of -1134271262 and a multiplier of -1521134295. But that is not part of the specification. Theoretically that could change radically between C# compiler versions and it would still meet what it needs to. So if the 2 assemblies are not compiled by the same compiler, there is no guarantee. Indeed, it would be "valid" (but unlikely) for the compiler to think up a new seed value every time it compiles.
Personally, I would look at using IL or Expression techniques to do this. Comparing similarly-shaped objects member-wise by name is fairly easy to do with Expression.
For info, I've also looked at how mcs (the Mono compiler) implements GetHashCode, and it is different; instead of seed and multiplier, it uses a combination of seed, xor, multiplier, shifts and additions. So the same type compiled by Microsoft and Mono will have very different GetHashCode.
static class Program {
static void Main() {
var obj = new { A = "abc", B = 123 };
System.Console.WriteLine(obj.GetHashCode());
}
}
Mono: -2077468848
Microsoft: -617335881
Basically, I do not think you can guarantee this.
How about:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
class Foo
{
public string A { get; set; }
public int B; // note a field!
static void Main()
{
var obj1 = new { A = "abc", B = 123 };
var obj2 = new Foo { A = "abc", B = 123 };
Console.WriteLine(MemberwiseComparer.AreEquivalent(obj1, obj2)); // True
obj1 = new { A = "abc", B = 123 };
obj2 = new Foo { A = "abc", B = 456 };
Console.WriteLine(MemberwiseComparer.AreEquivalent(obj1, obj2)); // False
obj1 = new { A = "def", B = 123 };
obj2 = new Foo { A = "abc", B = 456 };
Console.WriteLine(MemberwiseComparer.AreEquivalent(obj1, obj2)); // False
}
}
public static class MemberwiseComparer
{
public static bool AreEquivalent(object x, object y)
{
// deal with nulls...
if (x == null) return y == null;
if (y == null) return false;
return AreEquivalentImpl((dynamic)x, (dynamic)y);
}
private static bool AreEquivalentImpl<TX, TY>(TX x, TY y)
{
return AreEquivalentCache<TX, TY>.Eval(x, y);
}
static class AreEquivalentCache<TX, TY>
{
static AreEquivalentCache()
{
const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
var xMembers = typeof(TX).GetProperties(flags).Select(p => p.Name)
.Concat(typeof(TX).GetFields(flags).Select(f => f.Name));
var yMembers = typeof(TY).GetProperties(flags).Select(p => p.Name)
.Concat(typeof(TY).GetFields(flags).Select(f => f.Name));
var members = xMembers.Intersect(yMembers);
Expression body = null;
ParameterExpression x = Expression.Parameter(typeof(TX), "x"),
y = Expression.Parameter(typeof(TY), "y");
foreach (var member in members)
{
var thisTest = Expression.Equal(
Expression.PropertyOrField(x, member),
Expression.PropertyOrField(y, member));
body = body == null ? thisTest
: Expression.AndAlso(body, thisTest);
}
if (body == null) body = Expression.Constant(true);
func = Expression.Lambda<Func<TX, TY, bool>>(body, x, y).Compile();
}
private static readonly Func<TX, TY, bool> func;
public static bool Eval(TX x, TY y)
{
return func(x, y);
}
}
}

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

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.

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