using System.Collections.Generic;
public static void Main()
dynamic t = new NamedTuple(new[] { "one", "two", "three" });
t.Make(new object[] { 3, 2, 1 });
Console.WriteLine(t.one);
public class NamedTuple : DynamicObject
private readonly IDictionary<string, object> _contained = new Dictionary<string, object>();
public NamedTuple(IDictionary<string, object> propertiesAndValues)
_contained = propertiesAndValues;
public NamedTuple(IEnumerable<string> propertyNames)
foreach (var property in propertyNames)
_contained.Add(property, null);
public void Make(IEnumerable<object> contents)
for (int i = 0; i < contents.Count(); i++)
_contained[_contained.Keys.ElementAt(i)] = contents.ElementAt(i);
public ICollection<string> Fields
public NamedTuple Replace(string field, object value)
if (!_contained.ContainsKey(field))
throw new ArgumentException("Field not found in tuple", "field");
var newDict = new Dictionary<string, object>(_contained);
return new NamedTuple(newDict);
public static implicit operator NamedTuple(ExpandoObject eo)
return new NamedTuple((IDictionary<string, object>)eo);
public static implicit operator Dictionary<string, object>(NamedTuple me)
return (Dictionary<string, object>)me._contained;
public override bool TryGetMember(GetMemberBinder binder, out object result)
var contAsDict = (IDictionary<string, object>)_contained;
return contAsDict.TryGetValue(binder.Name, out result);
public override bool TrySetMember(SetMemberBinder binder, object value)
var contAsDict = (IDictionary<string, object>)_contained;
contAsDict[binder.Name] = value;