0

I'm trying to solve some simple study task, which includes writing an interpreter of some simple language with 4 methods - Set, Sum, Print, Remove; first 2 methods have 2 arguments - variable name and int value to set to variable or sum to its current value, and last 2 methods have only one argument - variable name

The method that I'm writing takes string , for example "set a 3" or "print a", and should work as interpreter of this string (do appropriate actions). The obvious way is to use switch construction (switch by first word), but I've read that it's always better to use Dictionary instead of switch, so I've defined

Dictionary<string, Action<ActionArg>> methods

, where ActionArg is defined supertype with 2 inherited types:

abstract class ActionArg {} 
class ActionArgVal : ActionArg { public string Val {get; set; } }
class ActionArgValVar : ActionArgVal { public int Var {get; set; } }

, and have defined 4 methods, for example,

void Set(ActionArgValVar) { ... }

But when I'm trying to write methods = new Dictionary<string, Action<ActionArg>> { {"set", Set}, ... }, there occurs an error, because Action<ActionArgValVar> couldn't be assigned to Action<ActionArg> because of contravariance of Action.

Is there any way to solve this using Dictionary or tasks like this are better to be solved by simple switch construction?

  • "*but I've read that it's always better to use Dictionary instead of switch*" -- I think that's going a bit far – canton7 Feb 11 '20 at 12:21
  • Have you thought about making _Set, Sum, Print, Remove_ methods generic itself and use the generic constraint to limit a types for your interpreter? Please, share the examples of these methods as well? – Pavel Anikhouski Feb 11 '20 at 12:21
  • `private static void Set(T arg) where T : ActionArg` Pavel Anikhouski that works, thanks for advice! (now Dictionary assigns correctly) canton7 sorry, my English is not very good, you mean it's too complexity to this simple task? – Sergey Melnikov Feb 11 '20 at 12:24
  • Pavel Anikhouski But I have one more question now, in every method now I should use cast, such as, `var argValVar = (ActionArgVarVal)arg`, or there is more elegant way? – Sergey Melnikov Feb 11 '20 at 12:31
  • Pavel Anikhouski `void Set(T arg) where T : ActionArg { var argValVar = (ActionArgVarVal)arg; //working with argValVar }` `methods = new Dictionary> { { "set", Set } };` or you meant something else, sorry? canton7 seems understood - too common phrase about Dictionary and switch – Sergey Melnikov Feb 11 '20 at 12:42
  • (`arg as ActionArgVarVal`, to be correct) – Sergey Melnikov Feb 11 '20 at 12:48
  • Pavel Anikhouski about examples - for example, "set a 5" defines var a with value 5, "sum a 4" makes a 9, "print a" displays it, "remove a" removes it from memory so "print a" after it would produce exception. I didn't write this examples because my question doesn't depend on semantic of these methods.. – Sergey Melnikov Feb 11 '20 at 12:54

0 Answers0