Skip to content

Instantly share code, notes, and snippets.

@akimboyko
Last active December 18, 2015 04:08
Show Gist options
  • Select an option

  • Save akimboyko/5722980 to your computer and use it in GitHub Desktop.

Select an option

Save akimboyko/5722980 to your computer and use it in GitHub Desktop.
Dynamic definition of `GetEnumerator` using DLR without implementing `GetEnumerator` at compile time. Inspired by http://hotcode.org/speeches/c-deep-dive/
void Main()
{
dynamic something = new DynamicEnumerable();
something.DynamicMethod = new Action<string>(str => str.Dump());
"First `dynamic` GetEnumerator".Dump();
something.GetEnumerator = new Func<IEnumerator>(() =>
"test of dynamic enumerator".ToCharArray().GetEnumerator());
foreach(dynamic part in something)
{
(part as object).Dump();
}
"Second `dynamic` GetEnumerator".Dump();
something.GetEnumerator = new Func<IEnumerator>(() =>
Enumerable.Range(1, 10).GetEnumerator());
foreach(dynamic part in something)
{
(part as object).Dump();
}
something.DynamicMethod("dynamic invication");
}
class DynamicEnumerable : DynamicObject
{
private readonly Dictionary<string, object> dictionary = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return dictionary.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
dictionary[binder.Name] = value;
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
Type dictType = typeof(Dictionary<string, object>);
try
{
result = dictType.InvokeMember(
binder.Name,
BindingFlags.InvokeMethod,
null, dictionary, args);
return true;
}
catch
{
result = null;
return false;
}
}
public override bool TryConvert(ConvertBinder binder, out object result)
{
if(typeof(IEnumerable).IsAssignableFrom(binder.Type))
{
try
{
if(dictionary.ContainsKey("GetEnumerator"))
{
result = ((IEnumerator)((Func<object>)dictionary["GetEnumerator"])()).ToIEnumerable();
}
else
{
result = Enumerable.Empty<object>();
}
return true;
}
catch(Exception ex)
{
ex.Dump();
}
}
result = null;
return false;
}
}
public static class Extension
{
public static IEnumerable ToIEnumerable(this IEnumerator enumerator)
{
while ( enumerator.MoveNext() ) {
yield return enumerator.Current;
}
}
}
@akimboyko

Copy link
Copy Markdown
Author

More simple sample by InnerSelf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment