I am new to C# and find myself in situations sometimes where I have to return complex return types for some functions. Like the function may take in some object and return a different view of that object: some fields added, some removed, etc. And other times, I may take in a list of objects and want to return a list of some modified objects and possibly some aggregate calculations on all of them together.
I could 开发者_Python百科accomplish these kinds of things by returning C# native types (like object[]), but it gets ugly to have object[] of object[]'s and then in code have to "know" that object[0][1] corresponds to something.
I suspect it makes sense to create a truly new class called like a FnFooReturn, but then where does it make the most sense to include the definition of such classes so that anywhere that calls the function can use it?
Edit: A specific example: I have a function Foo that takes in a list of objects like:
(int id, int num, string name)
so some example data could be:
(1, 100, "foo")
(1, 203, "foo")
(2, 400, "bar")
(3, 10, "cat")
and I want to return a list of objects like:
(int id, string name, int[] nums)
to look like:
[(1, "foo", [100, 103]), (2, "bar", [400]), (3, "cat", [10])]
so basically it is just a different view of the original list of objects except it combines together all of the objects with the same id to make it easier to loop over in other code later.
You can add an ordinary class to your project and use it wherever you like.
Try LINQ:
var items = new[] {
new { id = 1, num = 100, name = "foo" },
new { id = 1, num = 203, name = "foo" },
new { id = 2, num = 400, name = "bar" },
new { id = 3, num = 10, name = "cat" },
};
var result = items.GroupBy(x => x.id, (k, i) => new { id = k, nums = i.Select(y => y.num).ToArray(), name = i.Select(x => x.name).First() }).ToArray();
If you need encapsulate this logic into a method, use an Extension Method on your list (and empower it with Generics if needed).
Your functions should be like b = F(a)
where a
and b
are menaingful types in your design.
There is some limited room for ad-hoc types, like Tuple<Customer, decimal>
but if you find yourself writing special classes to accomodate a method, something has gone wrong.
In your specific example you should have a concrete type which handles those properties, and utilize LINQ to reinterpret the data in a different "view".
public class Item
{
public int Id { get; private set; }
public int Category { get; set; }
public string Name { get; set; }
public Item(int id, int category, string name)
{
this.Id = id;
this.Category = category;
this.Name = name;
}
}
Later:
var items = new [] { new Item(1, 103, "foo"), ... };
var query = from item in items
where item.Category != 108 /* example */
group by item.Id into g
select new
{
Id = g.Key,
Categories = g.Select(x => x.Category).ToArray()
};
精彩评论