这些是匿名类型;匿名类型是一种编译器特性,因此布局在编译时是固定不变的,因此它们不会发生变化。我建议:不要使用dynamic
. 例如:
var arr = new[] {
new { column1 = "1", column2 = "name", column3= "somevalue" },
new { column1 = "2", column2 = "name2", column3= "somevalue2" },
new { column1 = "3", column2 = "name3", column3= "somevalue3" }
};
这都是强类型和明确定义的。您可以使用常规操作,例如:
var item2 = arr.FirstOrDefault(x => x.column1 == "2");
再次,所有静态类型。
如果你想搜索所有的列,那么我建议像字典这样的东西更好:
var arr = new[] {
new Dictionary<string,string> { {"column1", "1"}, ... },
new Dictionary<string,string> { {"column1", "2"}, ... },
new Dictionary<string,string> { {"column1", "3"}, ... },
};
既然你可以看看.Values.Contains(...)
编辑:有了评论,我想我更清楚地理解它;我正在描绘一个不透明的方法,它返回IEnumerable<dynamic>
实际上是 POCO 类型(不是动态类型),我们想要检查字符串成员(任意名称)是否匹配。我们应该能够通过反射来做到这一点,但FastMember会使其更快:
static void Main()
{
string search = "ame2";
int rowIndex = 0;
string[] names = null;
TypeAccessor accessor = null;
foreach(object row in GetData())
{
if(names == null)
{ // first row; get the property-names and build an accessor
names = (from prop in row.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
where prop.PropertyType == typeof (string)
select prop.Name).ToArray();
accessor = TypeAccessor.Create(row.GetType());
}
foreach(var name in names)
{
var val = accessor[row, name] as string;
if(val != null && val.Contains(search))
{
Console.WriteLine("row {0}, col {1}, val {2}", rowIndex, name, val);
}
}
rowIndex++;
}
}
static IEnumerable<dynamic> GetData()
{
yield return new {column1 = "1", column2 = "name", column3 = "somevalue"};
yield return new {column1 = "2", column2 = "name2", column3 = "somevalue2"};
yield return new {column1 = "3", column2 = "name3", column3 = "somevalue3"};
}