Closed tdwright closed 6 years ago
The problem is that ConTabs determines the columns via reflection.
If I do:
var Data = new List<object>()
{
new { Prop1 = "valueX" },
new { Prop1 = "valueY", Prop2 = 3.0 },
new { prop3 = "valueZ" }
};
var table = Table<Object>.Create(Data);
Console.WriteLine(table.ToString());
I get an exception:
ConTabs.Exceptions.PublicPropertiesNotFoundException On Table
creation, no valid properties were identified. Check access modifiers.
So I suppose we may need to think about a new construction. I guess if we took an ArrayList
(or similar) and derived the columns by reading the property names, then doing a Unique()
. We can assume in this case that all properties should be included, as they otherwise wouldn't have been included.
The other problem this may expose is what we do with nulls. The example you've used would currently throw a NullReferenceException
for the missing values. This may not be the desired behaviour even with non-anonymous objects.
I wanted to ask if that's how the table should look (assuming that the program works correctly). And in order to handle anonymous types we could have a wrapper/Factory that spits out all the columns.
I am not suggesting to feed anonymous types to the current implementation.
Ah, I see. Well that table looks pretty much as I'd expect, yes.
Hi @Ravikc - have you had any further thoughts on this? It felt like you were heading in a pretty interesting direction.
I got a little busy at work. But basically the path I had chosen required some code duplication. So i am trying to find a more elegant way to achieve the same.
Ah, cool. There's absolutely no rush with this - we're all doing this in our spare time after all!
I was able to get this to work with a helper class and method:
public static class Table
{
public static Table<TResult> Create<TResult>(IEnumerable<TResult> source) where TResult : class
{
return Table<TResult>.Create(source);
}
}
I found this works fine and the demo works with with only a small change (note the L modifier to the integer literals in DistanceFromSun
):
// Get some data (can be an IEnumerable of anything)
var Data = new[] {
new { Name = "Mercury", DistanceFromSun = 57909227L, OrbitalPeriod = 88F, Diameter = 4879, Fact = "Mercury is the smallest planet." },
new { Name = "Venus", DistanceFromSun = 108209475L, OrbitalPeriod = 225F, Diameter = 12104, Fact = "Venus is the hottest planet." },
new { Name = "Earth", DistanceFromSun = 149598262L, OrbitalPeriod = 365.24F, Diameter = 12742, Fact = "Earth is where we live" },
new { Name = "Mars", DistanceFromSun = 227943824L, OrbitalPeriod = 693.5F, Diameter = 6779, Fact = "Mars is also often described as the “Red Planet” due to its reddish appearance." },
new { Name = "Jupiter", DistanceFromSun = 778340821L, OrbitalPeriod = 4343.5F, Diameter = 139822, Fact = "Jupiter is the largest planet." },
new { Name = "Saturn", DistanceFromSun = 1426666422L, OrbitalPeriod = 10767.5F, Diameter = 116464, Fact = "Saturn is best known for its fabulous ring system that was first observed in 1610 by the astronomer Galileo Galilei." },
new { Name = "Uranus", DistanceFromSun = 2870658186L, OrbitalPeriod = 30660F, Diameter = 50724, Fact = "Uranus became the first planet discovered with the use of a telescope." },
new { Name = "Neptune", DistanceFromSun = 4498396441L, OrbitalPeriod = 60152F, Diameter = 49244, Fact = "On average Neptune is the coldest planet" },
};
// Create a table object
var table = Table.Create(Data);
Optionally, you could add an extension method:
public static Table<TResult> AsTable<TResult>(this IEnumerable<TResult> source) where TResult : class
{
return Table<TResult>.Create(source);
}
Which would allow the demo to change to:
// Create a table object
var table = Data.AsTable();
Hi @sixlettervariables. Thanks for picking this up.
Very neat application of generics. It hadn't occurred to me that it could be this easy!
I also like the flexibility that this dual approach (new ctor and ext method) allows.
Would love to see a pull request for this!
Tom
Please see #47. We would likely use the AsTable
extension.
Fixed by #47
I'd like to take this forward. So suppose we declare our anonymous list something like this:
or this:
What kind to table should it produce? I was thinking something like this:
Let's decide the expected output first and then we can discuss the implementation. What do you think?