Reputation: 11287
How do I get the value of one of the new properties out of query in the DoIt function below?
public object GetData()
{
var table = GetDataTable();
var view = table.DefaultView;
//..... more code
var query = from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new
{
ShortName = grouping.Key,
SCount = grouping.Sum( count => count.Field<int>("ProfCount")),
DisplayText = string.Empty
};
return query;
}
// this code doesn't work
public void DoIt()
{
var result = GetData();
string shortName = result.ShortName;
}
Thanks!
Upvotes: 0
Views: 7990
Reputation: 11287
This gives me what I need:
public object GetData()
{
var table = GetDataTable();
var view = table.DefaultView;
//..... more code
var query = from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new Object[]
{
grouping.Key,
grouping.Sum( count => count.Field<int>("ProfCount")),
string.Empty
};
return query;
}
public void DoIt()
{
// Note: Pretend that GetData returned only one result
object[] result = GetData() as object[];
var shortName = result[0];
}
Upvotes: 0
Reputation: 241583
Well, DoIt
has no idea that result
has a property named ShortName
because its typed as an object
. You could create a concrete class that holds the results, use reflection, or use dynamic
. Note that either way, GetData
is really returning an IEnumerable<T>
where T
is currently an anonymous type.
Using a concrete class:
public class Foo {
public string ShortName { get; set; }
public int SCount { get; set; }
public string DisplayText { get; set; }
}
public IEnumerable<Foo> GetData() {
var table = GetDataTable();
var view = table.DefaultView;
//..... more code
var query = from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new Foo
{
ShortName = grouping.Key,
SCount = grouping.Sum( count => count.Field<int>("ProfCount")),
DisplayText = string.Empty
};
return query;
}
public void DoIt() {
var result = GetData();
foreach(var item in result) {
Console.WriteLine(item.ShortName);
}
}
Using reflection:
public IEnumerable GetData() {
var table = GetDataTable();
var view = table.DefaultView;
//..... more code
var query = from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new Foo
{
ShortName = grouping.Key,
SCount = grouping.Sum( count => count.Field<int>("ProfCount")),
DisplayText = string.Empty
};
return query;
}
public void DoIt() {
var result = GetData();
PropertyInfo property = result.First().GetType().GetProperty("ShortName");
foreach(var item in result) {
string shortName = property.GetValue(item, null);
Console.WriteLine(shortName);
}
}
Upvotes: 1
Reputation: 1038710
Anonymous types are not called anonymous types for nothing. So:
Define a type with a name (6 additional lines of code):
public class Foo
{
public string ShortName { get; set; }
public int SCount { get; set; }
public string DisplayText { get; set; }
}
Now modify your GetData
signature to (0 additional lines of code):
public IEnumerable<Foo> GetData()
And your LINQ query to (3 additional characters, or a couple more if you choose more meaningful name):
var query =
from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new Foo
{
ShortName = grouping.Key,
SCount = grouping.Sum( count => count.Field<int>("ProfCount")),
DisplayText = string.Empty
};
Upvotes: 4
Reputation: 11651
You're returning an anonymous type (via select new {}), which is only valid in the local scope. You need to create a concrete type and return that from your function rather than object.
public SomeClass GetData()
{
var table = GetDataTable();
var view = table.DefaultView;
//..... more code
var query = from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new SomeClass
{
ShortName = grouping.Key,
SCount = grouping.Sum( count => count.Field<int>("ProfCount")),
DisplayText = string.Empty
};
return query;
}
// this code doesn't work
public void DoIt()
{
var result = GetData();
string shortName = result.ShortName;
}
public class SomeClass
{
public string ShortName { get; set; }
public int SCount { get; set; }
public string DisplayText { get; set; }
}
Upvotes: 2
Reputation: 168978
You can't without using reflection. Since it is an anonymous type, you cannot cast to it in the DoIt()
method either, since the type name is not known at compile time.
Upvotes: 0