Autovivification in C# - c#

Trying to wrap my head around perl's Autovivification and based on what it sounds like, It seems to work similar to dynamics in C# as a dynamic object is not assigned a type until runtime or, am I totally off here. If so then is there a comparable idea that I can bridge off of in C# that makes sense?
Edit
Okay so I'm apparently way off. So as second part of the 2 part question, is there anything conceptually comparable in C#? To be clear I'm looking for a concept in C# that is comparable to Autovivification. Doesn't have to be exactly the same but close enough conceptually to make sense. And as I stated eariler I am by no means a perl hacker or python hacker by any stretch of the imagination but, I am familar with c based languages C, C++, C#, java, javascript. I was thinking of C#'s dynamics but, as of right now I'm thinking lazy loading based on the info here if that helps....

I can't speak to C#, but in layman's terms, Perl's autovivification is the process of creating a container object out of an undefined value as soon as it is needed.
Despite most of Perl being quite dynamic, Perl's dereferencing syntax unambiguously specifies the type of the reference at compile time. This allows the interpreter to know what it needs out of a variable before the variable is ever defined.
my $var; # undefined
# to autovivify to an array:
#$var = 1..5; # # here implies ARRAY
$$var[4] = 5; # square brackets imply ARRAY
$#$var; # $# implies ARRAY (returns the last index number)
# to autovivify to a hash:
%$var = (a => 1); # % implies HASH
$$var{asdf} = 5; # curly braces imply HASH
This list could be longer, but should give you an idea.
So basically, when you have a line like this:
my $var;
$var->[1]{x}[3]{asdf}
Perl looks on the right side of the -> and sees square braces. This means that the invocant $var must be an array reference. Since the invocant is undefined, Perl creates a new array and installs its reference into $var. This same process is then repeated for every subsequent dereferencing.
So the line above really means:
(((($var //= [])->[1] //= {})->{x} //= [])->[3] //= {})->{asdf};
which is fairly hideous, and hence autovivification. (//= is the defined-or assignment operator in perl 5.10+)
Update:
As per cjm's comment, to put this into general non-perl terms, to achieve autovivification in another language, you need a lazy object that supports indexing via [...] and {...}. When either of these indexing operations are performed, the object replaces itself with either an array or hash. Every time the object is then accessed, if the cell is empty, it should return another lazy object.
obj = new lazy_obj()
level1 = obj[4] # sets obj to be an array, returns a new lazy_obj for level1
level2 = level1{asdf} # sets level1 (and obj[4]) to a hash,
# returns a new lazy_obj for level2
So basically you need two things, the ability to create an object that supports indexing with both array and hash subscripts (or the equivalent), and a mechanism such that an object can replace itself in memory with another object (or that can lock itself to one interpretation, and then store the new object internally.
Something like the following pseudo-code could be a start:
class autoviv {
private var content;
method array_subscript (idx) {
if (!content) {
content = new Array();
}
if (typeof content == Array) {
if (exists content[idx]) return content[idx];
return content[idx] = new autoviv();
} else {
throw error
}
}
method hash_subscript (idx) {
if (!content) {
content = new Hash();
}
if (typeof content == Hash) {
if (exists content{idx}) return content{idx};
return content{idx} = new autoviv();
} else {
throw error
}
}
// overload all other access to return undefined, so that the value
// still looks empty for code like:
//
// var auto = new autoviv();
// if (typeof auto[4] == autoviv) {should run}
// if (auto[4]) {should not run}
}

Uri Guttman's autovivification tutorial might be of some use.
Basically, it is the ability of hitherto untouched aggregates and members of aggregates to spring to life upon first use.
For example, I can do this:
#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper;
my #dummy;
push #{ $dummy[0] }, split ' ', 'this that and the other';
push #{ $dummy[1] }, { qw(a b c d) };
print Dumper \#dummy;
Neither $dummy[0] nor $dummy[1] exist before they are dereferenced.
Now, if you are willing to forgo strict (which, you shouldn't be), you can also do things like:
use Data::Dumper;
#$x = qw(a b c d);
print Dumper $x;
whereby the undefined variable $x becomes an array reference because it is being dereferenced as such.

You can implement autovification-like behavior with creating say, an IDictionary<X,Y> that returns (and stores) a new IDictionary<X,Y> (e.g. recursively the same type) when a [] to an unset key occurs. This approach is used in Ruby to great success (an example) -- however, it's really not so useful in a statically typed language because there is no way to "get to" the leaf values cleanly -- at least in context of most existing contracts such as an IDictionary.
With the advent of dynamic, this may be possible in C# to do sanely, but I do not know.

How about something like this for a simple implementation of auto-vivification like behaviour of a Dictionary in C#? Obviously this doesn't handle it in the generic way that Perl does, but I believe that it has the same effect.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// The purpose of this class is to provide a dictionary with auto-vivification behaviour similar to Perl's
// Using dict[index] will succeed regardless of whether index exists in the dictionary or not.
// A default value can be set to be used as an initial value when the key doesn't exist in the dictionary
namespace XMLTest
{
class AutoDictionary<TKey,TValue> : Dictionary<TKey,TValue> {
Object DefaultValue ;
public AutoDictionary(Object DefaultValue) {
this.DefaultValue = DefaultValue;
}
public AutoDictionary() {
this.DefaultValue = null;
}
public new TValue this[TKey index] {
get {
try {
return base[index];
}
catch (KeyNotFoundException) {
base.Add(index, (TValue)DefaultValue);
return (TValue)DefaultValue ;
}
}
set {
try {
base[index] = value ;
}
catch (KeyNotFoundException) {
base.Add(index, value);
}
}
}
}
}

I would recommend using extension methods instead of inheritance.
e.g.:
namespace DictionaryEx
{
public static class Ex
{
public static TV Vivify<TK, TV>(this IDictionary<TK, TV> dict, TK key)
{
var value = default(TV);
if (dict.TryGetValue(key, out value))
{
return value;
}
value = default(TV);
dict[key] = value;
return value;
}
public static TV Vivify<TK, TV>(this IDictionary<TK, TV> dict, TK key, TV defaultValue)
{
TV value;
if (dict.TryGetValue(key, out value))
{
return value;
}
dict[key] = defaultValue;
return defaultValue;
}
public static TV Vivify<TK, TV>(this IDictionary<TK, TV> dict, TK key, Func<TV> valueFactory)
{
TV value;
if (dict.TryGetValue(key, out value))
{
return value;
}
value = valueFactory();
dict[key] = value;
return value;
}
}
}

Using indexers and C# 4.0 dynamics,
class Tree
{
private IDictionary<string, object> dict = new Dictionary<string, object>();
public dynamic this[string key]
{
get { return dict.ContainsKey(key) ? dict[key] : dict[key] = new Tree(); }
set { dict[key] = value; }
}
}
// Test:
var t = new Tree();
t["first"]["second"]["third"] = "text";
Console.WriteLine(t["first"]["second"]["third"]);
DynamicObject can be used for implementing different syntaxes also,
using System;
using System.Collections.Generic;
using System.Dynamic;
class Tree : DynamicObject
{
private IDictionary<object, object> dict = new Dictionary<object, object>();
// for t.first.second.third syntax
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var key = binder.Name;
if (dict.ContainsKey(key))
result = dict[key];
else
dict[key] = result = new Tree();
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
dict[binder.Name] = value;
return true;
}
// for t["first"]["second"]["third"] syntax
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
var key = indexes[0];
if (dict.ContainsKey(key))
result = dict[key];
else
dict[key] = result = new Tree();
return true;
}
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
dict[indexes[0]] = value;
return true;
}
}
// Test:
dynamic t = new Tree();
t.first.second.third = "text";
Console.WriteLine(t.first.second.third);
// or,
dynamic t = new Tree();
t["first"]["second"]["third"] = "text";
Console.WriteLine(t["first"]["second"]["third"]);

Related

C# get propery value from string path

Given any object, I want to be able to retrieve the value of a property and any "depth".
var name = myObject.GetValue<String>("Name")
or
var father_name = myObject.GetValue<String>("Father.Name")
This is easy and I'm able do achieve it with the following code:
public static T GetValue<T>(this Object obj, String fqname)
{
try
{
Object value = obj;
foreach (var prop in fqname.Split('.').Select(s => value.GetType().GetProperty(s)))
{
value = prop.GetValue(value, null);
}
if (value is T)
{
return (T)value;
}
else
{
// if the type requested is not the same as the stored, attempt a blind conversion
var converter = TypeDescriptor.GetConverter(typeof(T));
return (T)converter.ConvertFromInvariantString(value.ToString());
}
}
catch (NotSupportedException)
{
throw new InvalidCastException($"Cannot convert value to reuested type");
}
}
Now the problem is that this doesn't work for arrays, like:
var main_street = myObject.GetValue<String>("Addresses[0].StreetName")
Not even for the cases of arrays of arrays and so on...
I can start adding these conditions and special cases to my code but before that I figured, as C# already does this, maybe we could leverage some code parsing strategy, Roslyn, ... don't know, something that doesn't feel like reinventing the wheel and supports as many cases as possible.
Any ideas?

Cross referencing structure from single data input

Another one of my can't see the wood for the trees questions.
Background
I've got a requirement to query a predefined structure for cooking equivalents across (at the moment) a small range of cultures. The structure won't change but the possibility of other cultures and/or equivalents being introduced is a very strong possibility.
Problem
I would like to put in place a 2nd 'structure' that would allow me to retain the core of what I've been given, but at the same time, allow me to intelligently input the equivalent measurements only once. In the example below, I've only created an equivalent for a UK measurement to return it's partner Metric and US counterparts. My aim would be that from this single input, the structure would be able to spit back a UK equivalent if given a US counterpart etc, etc.
Question
Is it asking too much of such an implicit structure to be able to operate in this fashion. Is it bad practice to ask for such a thing?? What would be your approach to solving such a dilema. The end game would be that any equivalent should be produced as a single liner along the lines of:
// this should produce a value of **CupLitre**
var eqv = conversion["CupUS"][LocaleM.Metric];
Anyway, without further ado:
The Example
Whip up a console app and paste the code below into it (.net v3.5).
using System;
using System.Collections.Generic;
using UnitOfMeasurements;
namespace UnitOfMeasurements
{
[Flags]
public enum LocaleM
{
None = 0, //(0000)
Metric = 1, //(0001)
UK = 2, //(0010)
US = 4, //(0100)
}
}
class Program
{
public static void Main(string[] args)
{
// single structure representing UK equivalents
// this should be extensible to any equivalent
var conversionUK
= new Dictionary<string, Dictionary<LocaleM, string>>
{
{"PintUK",
new Dictionary<LocaleM, string>
{
{LocaleM.US, "PintUS"},
{LocaleM.Metric, "Litre"}
}
},
{"FlOzUK",
new Dictionary<LocaleM, string>
{
{LocaleM.US, "FlOzUS"},
{LocaleM.Metric, "MilliLitre"}
}
},
{"CupUK",
new Dictionary<LocaleM, string>
{
{LocaleM.US, "CupUS"},
{LocaleM.Metric, "CupLitre"}
}
}
};
// basic printout of results
Console.WriteLine(string.Format("{0}\t{1}\t{2}", "Key","US","Metric"));
foreach (var item in conversionUK)
{
Console.WriteLine(string.Format("{0}\t{1}\t{2}",
item.Key,
item.Value[LocaleM.US],
item.Value[LocaleM.Metric]));
}
Console.WriteLine(string
.Format("Here's an example of our direct 'query' - {0}",
conversionUK["CupUK"][LocaleM.Metric]));
Console.Read();
}
}
Good luck - looking fwd to some simple but elegant answers.
[edit] - i must add that the requirement for the inputs ("PintUK", "CupMetric") etc, to be strings is a must as these values will be driving (IVolumeUnit)Activator.CreateInstance(eqv) methods further downstream to create concrete conversion classes of the given string names.
Following approach assumes that all your mappings are bidirectional and if a->b and b->c then a->c
I would introduce a concept of something like default name (cross-culture) for each your item to convert. For example in your code these default names could be 'Pint', 'FlOz' and 'Cup':
UPDATE: replaced custom MapKey class with .Net tuple to make code simplier.
class MapClass
{
private readonly Dictionary<string, string> _localToDefaultNameMap = new Dictionary<string, string>();
private readonly Dictionary<Tuple<string, LocaleM>, string> _defaultNameToLocalMap = new Dictionary<Tuple<string, LocaleM>, string>();
public void AddMapping(string defaultName, LocaleM locale, string localName)
{
_localToDefaultNameMap.Add(localName, defaultName);
_defaultNameToLocalMap.Add(Tuple.Create(defaultName, locale), localName);
}
// maps from source name to target
public string Map(string sourceLocalName, LocaleM targetLocale)
{
string defaultName = _localToDefaultNameMap[sourceLocalName];
var mapKey = Tuple.Create(defaultName, targetLocale);
var localName = _defaultNameToLocalMap[mapKey];
return localName;
}
}
Usage:
// Creating map:
var map = new MapClass();
map.AddMapping("Pint", LocaleM.UK, "PintUK");
map.AddMapping("Pint", LocaleM.US, "PintUS");
map.AddMapping("Pint", LocaleM.Metric, "Litre");
string ukPintMappedToUS = map.Map("PintUK", LocaleM.US);
UPDATE 2 MapKey equality members generated by resharper:
class MapKey
{
...
public bool Equals(MapKey other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Equals(other.Locale, Locale) && Equals(other.Key, Key);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof (MapKey)) return false;
return Equals((MapKey) obj);
}
public override int GetHashCode()
{
int result = 0;
result = (result * 397) ^ Locale.GetHashCode();
result = (result * 397) ^ (Key != null ? Key.GetHashCode() : 0);
return result;
}
}

Test if a property is available on a dynamic variable

My situation is very simple. Somewhere in my code I have this:
dynamic myVariable = GetDataThatLooksVerySimilarButNotTheSame();
//How to do this?
if (myVariable.MyProperty.Exists)
//Do stuff
So, basically my question is how to check (without throwing an exception) that a certain property is available on my dynamic variable. I could do GetType() but I'd rather avoid that since I don't really need to know the type of the object. All that I really want to know is whether a property (or method, if that makes life easier) is available. Any pointers?
I think there is no way to find out whether a dynamic variable has a certain member without trying to access it, unless you re-implemented the way dynamic binding is handled in the C# compiler. Which would probably include a lot of guessing, because it is implementation-defined, according to the C# specification.
So you should actually try to access the member and catch an exception, if it fails:
dynamic myVariable = GetDataThatLooksVerySimilarButNotTheSame();
try
{
var x = myVariable.MyProperty;
// do stuff with x
}
catch (RuntimeBinderException)
{
// MyProperty doesn't exist
}
I thought I'd do a comparison of Martijn's answer and svick's answer...
The following program returns the following results:
Testing with exception: 2430985 ticks
Testing with reflection: 155570 ticks
void Main()
{
var random = new Random(Environment.TickCount);
dynamic test = new Test();
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 100000; i++)
{
TestWithException(test, FlipCoin(random));
}
sw.Stop();
Console.WriteLine("Testing with exception: " + sw.ElapsedTicks.ToString() + " ticks");
sw.Restart();
for (int i = 0; i < 100000; i++)
{
TestWithReflection(test, FlipCoin(random));
}
sw.Stop();
Console.WriteLine("Testing with reflection: " + sw.ElapsedTicks.ToString() + " ticks");
}
class Test
{
public bool Exists { get { return true; } }
}
bool FlipCoin(Random random)
{
return random.Next(2) == 0;
}
bool TestWithException(dynamic d, bool useExisting)
{
try
{
bool result = useExisting ? d.Exists : d.DoesntExist;
return true;
}
catch (Exception)
{
return false;
}
}
bool TestWithReflection(dynamic d, bool useExisting)
{
Type type = d.GetType();
return type.GetProperties().Any(p => p.Name.Equals(useExisting ? "Exists" : "DoesntExist"));
}
As a result I'd suggest using reflection. See below.
Responding to bland's comment:
Ratios are reflection:exception ticks for 100000 iterations:
Fails 1/1: - 1:43 ticks
Fails 1/2: - 1:22 ticks
Fails 1/3: - 1:14 ticks
Fails 1/5: - 1:9 ticks
Fails 1/7: - 1:7 ticks
Fails 1/13: - 1:4 ticks
Fails 1/17: - 1:3 ticks
Fails 1/23: - 1:2 ticks
...
Fails 1/43: - 1:2 ticks
Fails 1/47: - 1:1 ticks
...fair enough - if you expect it to fail with a probability with less than ~1/47, then go for exception.
The above assumes that you're running GetProperties() each time. You may be able to speed up the process by caching the result of GetProperties() for each type in a dictionary or similar. This may help if you're checking against the same set of types over and again.
Maybe use reflection?
dynamic myVar = GetDataThatLooksVerySimilarButNotTheSame();
Type typeOfDynamic = myVar.GetType();
bool exist = typeOfDynamic.GetProperties().Where(p => p.Name.Equals("PropertyName")).Any();
Just in case it helps someone:
If the method GetDataThatLooksVerySimilarButNotTheSame() returns an ExpandoObject you can also cast to a IDictionary before checking.
dynamic test = new System.Dynamic.ExpandoObject();
test.foo = "bar";
if (((IDictionary<string, object>)test).ContainsKey("foo"))
{
Console.WriteLine(test.foo);
}
The two common solutions to this include making the call and catching the RuntimeBinderException, using reflection to check for the call, or serialising to a text format and parsing from there. The problem with exceptions is that they are very slow, because when one is constructed, the current call stack is serialised. Serialising to JSON or something analogous incurs a similar penalty. This leaves us with reflection but it only works if the underlying object is actually a POCO with real members on it. If it's a dynamic wrapper around a dictionary, a COM object, or an external web service, then reflection won't help.
Another solution is to use IDynamicMetaObjectProvider to get the member names as the DLR sees them. In the example below, I use a static class (Dynamic) to test for the Age field and display it.
class Program
{
static void Main()
{
dynamic x = new ExpandoObject();
x.Name = "Damian Powell";
x.Age = "21 (probably)";
if (Dynamic.HasMember(x, "Age"))
{
Console.WriteLine("Age={0}", x.Age);
}
}
}
public static class Dynamic
{
public static bool HasMember(object dynObj, string memberName)
{
return GetMemberNames(dynObj).Contains(memberName);
}
public static IEnumerable<string> GetMemberNames(object dynObj)
{
var metaObjProvider = dynObj as IDynamicMetaObjectProvider;
if (null == metaObjProvider) throw new InvalidOperationException(
"The supplied object must be a dynamic object " +
"(i.e. it must implement IDynamicMetaObjectProvider)"
);
var metaObj = metaObjProvider.GetMetaObject(
Expression.Constant(metaObjProvider)
);
var memberNames = metaObj.GetDynamicMemberNames();
return memberNames;
}
}
Denis's answer made me think to another solution using JsonObjects,
a header property checker:
Predicate<object> hasHeader = jsonObject =>
((JObject)jsonObject).OfType<JProperty>()
.Any(prop => prop.Name == "header");
or maybe better:
Predicate<object> hasHeader = jsonObject =>
((JObject)jsonObject).Property("header") != null;
for example:
dynamic json = JsonConvert.DeserializeObject(data);
string header = hasHeader(json) ? json.header : null;
Well, I faced a similar problem but on unit tests.
Using SharpTestsEx you can check if a property existis. I use this testing my controllers, because since the JSON object is dynamic, someone can change the name and forget to change it in the javascript or something, so testing for all properties when writing the controller should increase my safety.
Example:
dynamic testedObject = new ExpandoObject();
testedObject.MyName = "I am a testing object";
Now, using SharTestsEx:
Executing.This(delegate {var unused = testedObject.MyName; }).Should().NotThrow();
Executing.This(delegate {var unused = testedObject.NotExistingProperty; }).Should().Throw();
Using this, i test all existing properties using "Should().NotThrow()".
It's probably out of topic, but can be usefull for someone.
Following on from the answer by #karask, you could wrap the function as a helper like so:
public static bool HasProperty(ExpandoObject expandoObj,
string name)
{
return ((IDictionary<string, object>)expandoObj).ContainsKey(name);
}
For me this works:
if (IsProperty(() => DynamicObject.MyProperty))
; // do stuff
delegate string GetValueDelegate();
private bool IsProperty(GetValueDelegate getValueMethod)
{
try
{
//we're not interesting in the return value.
//What we need to know is whether an exception occurred or not
var v = getValueMethod();
return v != null;
}
catch (RuntimeBinderException)
{
return false;
}
catch
{
return true;
}
}
If you control the type being used as dynamic, couldn't you return a tuple instead of a value for every property access? Something like...
public class DynamicValue<T>
{
internal DynamicValue(T value, bool exists)
{
Value = value;
Exists = exists;
}
T Value { get; private set; }
bool Exists { get; private set; }
}
Possibly a naive implementation, but if you construct one of these internally each time and return that instead of the actual value, you can check Exists on every property access and then hit Value if it does with value being default(T) (and irrelevant) if it doesn't.
That said, I might be missing some knowledge on how dynamic works and this might not be a workable suggestion.
If your use case is to convert an api response, carrying about only a few fields, you can use this:
var template = new { address = new { street = "" } };
var response = JsonConvert.DeserializeAnonymousType(await result.Content.ReadAsStringAsync(), template);
string street = response?.address?.street;
Here is the other way:
using Newtonsoft.Json.Linq;
internal class DymanicTest
{
public static string Json = #"{
""AED"": 3.672825,
""AFN"": 56.982875,
""ALL"": 110.252599,
""AMD"": 408.222002,
""ANG"": 1.78704,
""AOA"": 98.192249,
""ARS"": 8.44469
}";
public static void Run()
{
dynamic dynamicObject = JObject.Parse(Json);
foreach (JProperty variable in dynamicObject)
{
if (variable.Name == "AMD")
{
var value = variable.Value;
}
}
}
}
In my case, I needed to check for the existence of a method with a specific name, so I used an interface for that
var plugin = this.pluginFinder.GetPluginIfInstalled<IPlugin>(pluginName) as dynamic;
if (plugin != null && plugin is ICustomPluginAction)
{
plugin.CustomPluginAction(action);
}
Also, interfaces can contain more than just methods:
Interfaces can contain methods, properties, events, indexers, or any
combination of those four member types.
From: Interfaces (C# Programming Guide)
Elegant and no need to trap exceptions or play with reflexion...
I know this is really old post but here is a simple solution to work with dynamic type in c#.
can use simple reflection to enumerate direct properties
or can use the object extention method
or use GetAsOrDefault<int> method to get a new strongly typed object with value if exists or default if not exists.
public static class DynamicHelper
{
private static void Test( )
{
dynamic myobj = new
{
myInt = 1,
myArray = new[ ]
{
1, 2.3
},
myDict = new
{
myInt = 1
}
};
var myIntOrZero = myobj.GetAsOrDefault< int >( ( Func< int > )( ( ) => myobj.noExist ) );
int? myNullableInt = GetAs< int >( myobj, ( Func< int > )( ( ) => myobj.myInt ) );
if( default( int ) != myIntOrZero )
Console.WriteLine( $"myInt: '{myIntOrZero}'" );
if( default( int? ) != myNullableInt )
Console.WriteLine( $"myInt: '{myNullableInt}'" );
if( DoesPropertyExist( myobj, "myInt" ) )
Console.WriteLine( $"myInt exists and it is: '{( int )myobj.myInt}'" );
}
public static bool DoesPropertyExist( dynamic dyn, string property )
{
var t = ( Type )dyn.GetType( );
var props = t.GetProperties( );
return props.Any( p => p.Name.Equals( property ) );
}
public static object GetAs< T >( dynamic obj, Func< T > lookup )
{
try
{
var val = lookup( );
return ( T )val;
}
catch( RuntimeBinderException ) { }
return null;
}
public static T GetAsOrDefault< T >( this object obj, Func< T > test )
{
try
{
var val = test( );
return ( T )val;
}
catch( RuntimeBinderException ) { }
return default( T );
}
}
As ExpandoObject inherits the IDictionary<string, object> you can use the following check
dynamic myVariable = GetDataThatLooksVerySimilarButNotTheSame();
if (((IDictionary<string, object>)myVariable).ContainsKey("MyProperty"))
//Do stuff
You can make a utility method to perform this check, that will make the code much cleaner and re-usable

Reflection & Parameters in C#

I'm writing an application that runs "things" to a schedule.
Idea being that the database contains assembly, method information and also the parameter values. The timer will come along, reflect the method to be run, add the parameters and then execute the method.
Everything is fine except for the parameters.
So, lets say the method accepts an ENUM of CustomerType where CustomerType has two values of CustomerType.Master and CustomerType.Associate.
EDIT
I don't know the type of parameter that will be getting passed in. ENUM used as an example
END OF EDIT
We want to run Method "X" and pass in parameter "CustomerType.Master". In the database, there will be a varchar entry of "CustomerType.Master".
How do I convert the string "CustomerType.Master" into a type of CustomerType with a value of "Master" generically?
Thanks in advance,
Jim
OK, the scope of the question shifted but my original observation and objection to some other solutions still stands.
I think you don't/can't want to use 'generics' here. You don't know the type ahead of time, and since you will need to create the type, there is no need to use a generic implementation because MethodBase.Invoke takes an array of Object.
This code assumes you are instantiating the target from database field. If not just adjust accordingly.
Of course this is not all encompassing and has no useful exception handling, but it will allow you to dynamically execute arbitrary methods on an arbitrary type with arbitrary parameters values all coming from string values in a row.
NOTE: there are many many many scenarios in which this simple executor will not work. You will need to ensure that you engineer your dynamic methods to cooperate with whatever strategy you do end up deciding to use.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using NUnit.Framework;
namespace DynamicMethodInvocation
{
[TestFixture]
public class Tests
{
[Test]
public void Test()
{
// from your database
string assemblyQualifiedTypeName = "DynamicMethodInvocation.TestType, DynamicMethodInvocation";
string methodName = "DoSomething";
// this is how you would get the strings to put in your database
string enumString = Executor.ConvertToString(typeof(AttributeTargets), AttributeTargets.Assembly);
string colorString = Executor.ConvertToString(typeof(Color), Color.Red);
string stringString = "Hmm... String?";
object result = Executor.ExecuteMethod(assemblyQualifiedTypeName, methodName,
new[] { enumString, colorString, stringString });
Assert.IsInstanceOf<bool>(result);
Assert.IsTrue((bool)result);
}
}
public class TestType
{
public bool DoSomething(AttributeTargets #enum, Color color, string #string)
{
return true;
}
}
public class Executor
{
public static object ExecuteMethod(string assemblyQualifiedTypeName, string methodName,
string[] parameterValueStrings)
{
Type targetType = Type.GetType(assemblyQualifiedTypeName);
MethodBase method = targetType.GetMethod(methodName);
ParameterInfo[] pInfo = method.GetParameters();
var parameterValues = new object[parameterValueStrings.Length];
for (int i = 0; i < pInfo.Length; i++)
{
parameterValues[i] = ConvertFromString(pInfo[i].ParameterType, parameterValueStrings[i]);
}
// assumes you are instantiating the target from db and that it has a parameterless constructor
// otherwise, if the target is already known to you and instantiated, just use it...
return method.Invoke(Activator.CreateInstance(targetType), parameterValues);
}
public static string ConvertToString(Type type, object val)
{
if (val is string)
{
return (string) val;
}
TypeConverter tc = TypeDescriptor.GetConverter(type);
if (tc == null)
{
throw new Exception(type.Name + " is not convertable to string");
}
return tc.ConvertToString(null, CultureInfo.InvariantCulture, val);
}
public static object ConvertFromString(Type type, string val)
{
TypeConverter tc = TypeDescriptor.GetConverter(type);
if (tc == null)
{
throw new Exception(type.Name + " is not convertable.");
}
if (!tc.IsValid(val))
{
throw new Exception(type.Name + " is not convertable from " + val);
}
return tc.ConvertFrom(null, CultureInfo.InvariantCulture, val);
}
}
}
I would think you have 2 major options:
Store the type name along with the parameter value and use that to cast things using Type.GetType(string) to resolve the type in question.
Standardize all the methods to be called this way to accept an array of strings, and expect the methods to do any necessary casting.
I know you've stated that you're not doing option 1, but it would help things from the standpoint of calling the functions.
Option 2 is the far more 'generic' way to handle the situation, assuming all values can be represented by and cast/converted from strings to the appropriate type. Of course, that only helps if you actually have control over the definition of the methods being called.
Below is a useful extension method I use in .NET 3.5.
With this extension method available, your code could look like this:
var valueInDb = GetStringFromDb().Replace("CustomerType.", string.Empty);
var value = valueInDb.ToEnum(CustomerType.Associate);
By supplying the default value in the parameter, the compiler will know which Enum you want your string to be turned into. It will try to find your text in the Enum. If it doesn't it will return the default value.
Here is the extension method: (this version also does partial matches, so even "M" would work nicely!)
public static T ToEnum<T>(this string input, T defaultValue)
{
var enumType = typeof (T);
if (!enumType.IsEnum)
{
throw new ArgumentException(enumType + " is not an enumeration.");
}
// abort if no value given
if (string.IsNullOrEmpty(input))
{
return defaultValue;
}
// see if the text is valid for this enumeration (case sensitive)
var names = Enum.GetNames(enumType);
if (Array.IndexOf(names, input) != -1)
{
// case insensitive...
return (T) Enum.Parse(enumType, input, true);
}
// do partial matching...
var match = names.Where(name => name.StartsWith(input, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
if(match != null)
{
return (T) Enum.Parse(enumType, match);
}
// didn't find one
return defaultValue;
}
I still don't fully understand your question... however, you say "Everything is fine except for the parameters."
I'll assume "CustomerType" the name of a property on your object, and "Master" is the string value you want to put in that property.
Here is (another) extension method that may help.
Once you have your new object and the value and property name from the database field, you could use this:
// string newValue = "Master";
// string propertyName = "CustomerType";
myNewObject.SetPropertyValue(propertyName, newValue)
Method:
/// <summary>Set the value of this property, as an object.</summary>
public static void SetPropertyValue(this object obj,
string propertyName,
object objValue)
{
const BindingFlags attr = BindingFlags.Public | BindingFlags.Instance;
var type = obj.GetType();
var property = type.GetProperty(propertyName, attr);
if(property == null) return;
var propertyType = property.PropertyType;
if (propertyType.IsValueType && objValue == null)
{
// This works for most value types, but not custom ones
objValue = 0;
}
// need to change some types... e.g. value may come in as a string...
var realValue = Convert.ChangeType(objValue, propertyType);
property.SetValue(obj, realValue, null);
}
If you are using .NET 4 you can do the following.
var result = default(CustomerType);
if (!Enum.TryParse("Master", out result))
{
// handle error
}

eval(string) to C# code

Is it possible to evaluate the following in C# at runtime
I have a class that contains 3 properties (Field,Operator,Value)
rule.Field;
rule.Operator;
rule.Value;
this is my rule class...
Now I have a loop
foreach(item in items)
{
// here I want to create a dynamic expression to evaluate at runtime
// something like
if (item.[rule.field] [rule.operator] [rule.value])
{ do work }
}
I just don't know the syntax, or if its possible in C#, I know in JS its possible but that's not a compiled language.
Update
Essentially I want a way to eval(stringCode) or a better more supported way.
No, C# doesn't support anything like this directly.
The closest options are:
Create a full valid C# program and dynamically compile it with CSharpCodeProvider.
Build an expression tree, compile and execute it
Perform the evaluation yourself (this may actually be easiest, depending on your operators etc)
Disclaimer: I'm the owner of the project Eval Expression.NET
This library is close to being the JS Eval equivalent. You can almost evaluate and compile all the C# language.
Here is a simple example using your question, but the library goes way beyond this simple scenario.
int field = 2;
int value = 1;
string binaryOperator = ">";
string formula = "x " + binaryOperator + " y";
// For single evaluation
var value1 = Eval.Execute<bool>(formula, new { x = field, y = value });
// For many evaluation
var compiled = Eval.Compile<Func<int, int, bool>>(formula, "x", "y");
var value2 = compiled(field, value);
EDIT Answer comment:
Proprietary library to do simple evaluation? No, thanks
This library does not support only simple evaluation but almost all the C# languages. Allowing you to add dynamically a method, use async, linq, loop, etc., which is more than "to do simple evaluation"
The closest options solution provided by Jon Skeet are great but will surely take several days of development and testing to support all cases, depending on the operators. Surely this library helps some developers, but in some other scenarios, like yours, it could be done without it.
I'm not entirely sure what you are saying. Can you try clarifying it a bit?
Are you wanting to to take a string expression and evaluate it at runtime in C#? If so the answer is no. C# does not support such types of dynamic evaluation.
You'd have to either use the CodeDOM libraries or create an Expression tree, compile it, and execute it. I think building up the expression tree is the best option.
Of course you could put in a switch statement on your operator, which is not bad because there is a limited number of operators you could use anyways.
Here's a way to do this with expression trees (written in LINQPad):
void Main()
{
var programmers = new List<Programmer>{
new Programmer { Name = "Turing", Number = Math.E},
new Programmer { Name = "Babbage", Number = Math.PI},
new Programmer { Name = "Lovelace", Number = Math.E}};
var rule0 = new Rule<string>() { Field = "Name", Operator = BinaryExpression.Equal, Value = "Turing" };
var rule1 = new Rule<double>() { Field = "Number", Operator = BinaryExpression.GreaterThan, Value = 2.719 };
var matched0 = RunRule<Programmer, string>(programmers, rule0);
matched0.Dump();
var matched1 = RunRule<Programmer, double>(programmers, rule1);
matched1.Dump();
var matchedBoth = matched0.Intersect(matched1);
matchedBoth.Dump();
var matchedEither = matched0.Union(matched1);
matchedEither.Dump();
}
public IEnumerable<T> RunRule<T, V>(IEnumerable<T> foos, Rule<V> rule) {
var fieldParam = Expression.Parameter(typeof(T), "f");
var fieldProp = Expression.Property (fieldParam, rule.Field);
var valueParam = Expression.Parameter(typeof(V), "v");
BinaryExpression binaryExpr = rule.Operator(fieldProp, valueParam);
var lambda = Expression.Lambda<Func<T, V, bool>>(binaryExpr, fieldParam, valueParam);
var func = lambda.Compile();
foreach(var foo in foos) {
var result = func(foo, rule.Value);
if(result)
yield return foo;
}
}
public class Rule<T> {
public string Field { get; set; }
public Func<Expression, Expression, BinaryExpression> Operator { get; set; }
public T Value { get; set; }
}
public class Programmer {
public string Name { get; set; }
public double Number { get; set; }
}
A better design for you would be for your rule to apply the test itself (or to an arbitrary value)
By doing this with Func instances you will get the most flexibility, like so:
IEnumerable<Func<T,bool> tests; // defined somehow at runtime
foreach (var item in items)
{
foreach (var test in tests)
{
if (test(item))
{
//do work with item
}
}
}
then your specific test would be something like this for strong type checking at compile time:
public Func<T,bool> FooEqualsX<T,V>(V x)
{
return t => EqualityComparer<V>.Default.Equals(t.Foo, x);
}
For a reflective form
public Func<T,bool> MakeTest<T,V>(string name, string op, V value)
{
Func<T,V> getter;
var f = typeof(T).GetField(name);
if (f != null)
{
if (!typeof(V).IsAssignableFrom(f.FieldType))
throw new ArgumentException(name +" incompatible with "+ typeof(V));
getter= x => (V)f.GetValue(x);
}
else
{
var p = typeof(T).GetProperty(name);
if (p == null)
throw new ArgumentException("No "+ name +" on "+ typeof(T));
if (!typeof(V).IsAssignableFrom(p.PropertyType))
throw new ArgumentException(name +" incompatible with "+ typeof(V));
getter= x => (V)p.GetValue(x, null);
}
switch (op)
{
case "==":
return t => EqualityComparer<V>.Default.Equals(getter(t), value);
case "!=":
return t => !EqualityComparer<V>.Default.Equals(getter(t), value);
case ">":
return t => Comparer<V>.Default.Compare(getter(t), value) > 0;
// fill in the banks as you need to
default:
throw new ArgumentException("unrecognised operator '"+ op +"'");
}
}
If you wanted to be really introspective and handle any literal without knowing at compile time you could use the CSharpCodeProvider to compile a function assuming something like:
public static bool Check(T t)
{
// your code inserted here
}
This is of course a massive security hole so whoever can supply code for this must be fully trusted. Here is a somewhat limited implementation for your specific needs (no sanity checking at all)
private Func<T,bool> Make<T>(string name, string op, string value)
{
var foo = new Microsoft.CSharp.CSharpCodeProvider()
.CompileAssemblyFromSource(
new CompilerParameters(),
new[] { "public class Foo { public static bool Eval("+
typeof(T).FullName +" t) { return t."+
name +" "+ op +" "+ value
+"; } }" }).CompiledAssembly.GetType("Foo");
return t => (bool)foo.InvokeMember("Eval",
BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod ,
null, null, new object[] { t });
}
// use like so:
var f = Make<string>("Length", ">", "2");
For this to work with arbitrary types you would have to do a bit more reflection to find the target assembly for the type to reference it in the compiler parameters.
private bool Eval(object item, string name, string op, string value)
{
var foo = new Microsoft.CSharp.CSharpCodeProvider()
.CompileAssemblyFromSource(
new CompilerParameters(),
new[] { "public class Foo { public static bool Eval("+
item.GetType().FullName +" t) "+
"{ return t."+ name +" "+ op +" "+ value +"; } }"
}).CompiledAssembly.GetType("Foo");
return (bool)foo.InvokeMember("Eval",
BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod ,
null, null, new object[] { item });
}
All the above code is simply a proof of concept, it lacks sanity checking and has serious performance issues.
If you wanted to be even fancier you could use Reflection.Emit with DynamicMethod instances to do it (using proper operators rather than the default comparer instances) but this would require complex handling for types with overridden operators.
By making your check code highly generic you may include more tests in future as you need to. Essentially isolate the part of your code that cares only about a function from t -> true/false from the code that supplies these functions.
CSharpCodeProvider; switch statements that pick the proper different "operators"; the DLR... they are all ways you could do this; but they seem weird solutions to me.
How about just using delegates?
Assuming your Field and Value are numbers, declare something like this:
delegate bool MyOperationDelegate(decimal left, decimal right);
...
class Rule {
decimal Field;
decimal Value;
MyOperationDelegate Operator;
}
Now you can define your 'rule' as, for example, a bunch of lambdas:
Rule rule1 = new Rule;
rule1.Operation = (decimal l, decimal r) => { return l > r; };
rule1.Field = ...
You can make arrays of rules and apply them whichever way you wish.
IEnumerable<Rule> items = ...;
foreach(item in items)
{
if (item.Operator(item.Field, item.Value))
{ /* do work */ }
}
If Field and Values are not numbers, or the type depends on the specific rule, you can use object instead of decimal, and with a little bit of casting you can make it all work.
That's not a final design; it's just to give you some ideas (for example, you would likely have the class evaluate the delegate on its own via a Check() method or something).
You can retrieve the field by reflection. And then implement the operators as methods and uses reflection or some types of enum-delegate mapping to call the operators. The operators should have at least 2 parameters, the input value and the value you are using to test against with.
While it is true that you probably won't find an elegant way to evaluate full C# code on the fly without the use of dynamically compiling code (which is never pretty), you can almost certainly get your rules evaluated in short order using either the DLR (IronPython, IronRuby, etc) or an expression evaluator library that parses and executes a custom syntax. There is one, Script.NET, that provides a very similar syntax to C#.
Take a look here:Evaluating Expressions a Runtime in .NET(C#)
If you have the time / inclination to learn a little Python, then IronPython and the DLR will solve all your issues:
Extending your App with IronPython

Categories