Using data from another method with Linq - c#

So I have a method which will return an array of objects, but I want to call the method inside the query method which will use linq to return the result. I think this is feasible, but not sure if I'm right or not. The solution I could think of is calling the method & instantiating the array again inside the query method and then use linq as usual.
Class A{
public Items[] GetItems(){
Items[] item = new Items[4];
return items;
}
}
In another class in another file, which will do some routing with rest. that uses the data from method GetItems in class A to make query to the server. May be passing an array as an argument to the ItemsHandler method perhaps?
Class B{
[Route("~api/item")]
private IEnumerable<Items> ItemsHandler(){
return A.GetItems();
}
}

So, assuming I'm reading the question correctly, I think this is at least a start. We can worry over the specifics if I'm not on a completely wrong track:
private string[] Filter(string[] names, string like) {
return names.Where(n => n.Contains(like)).ToArray();
}
IEnumerable also has a .ToList() method, which is usually more convenient, but you mentioned arrays. Likewise, if the data elements aren't strings, the condition can be more complex.
You can then call it relatively naturally:
string[] names = MethodThatReturnsAnArrayOfNames();
string[] filtered_names = Filter (names, "ar");
Filter(), of course, can also be public, where that's of use.

Related

decorate IEnumerable without looping

I need to create an IEnummerable of DcumentSearch object from IQueryable
The following code causes the database to load the entire result which makes my app slow.
public static IEnumerable<DocumentSearch> BuildDocumentSearch(IQueryable<Document> documents)
{
var enumerator = documents.GetEnumerator();
while(enumerator.MoveNext())
{
yield return new DocumentSearch(enumerator.Current);
}
}
The natural way of writing this is:
public static IEnumerable<DocumentSearch> BuildDocumentSearch(IQueryable<Document> documents)
{
return documents.Select(doc => new DocumentSearch(doc));
}
When you call one of the IEnumerable extension methods like Select, Where, OrderBy etc, you are still adding to the recipe for the results that will be returned. When you try to access an element of an IEnumerable (as in your example), the result set must be resolved at that time.
For what it's worth, your while loop would be more naturally written as a foreach loop, though it should have the same semantics about when the query is executed.

If method returns interface type, why can't I pass the result to a concrete type?

The question maybe a little confusing, but it's hard to make clear this question in a subject title.
I have method declared and implemented like this:
public IList<string> GetBookTitles()
{
IList<string> bookTitles = new List<string>();
// do something to populate the bookTitles list.
return bookTitles;
}
Why can't I pass the result of this method to a List<string>? After all, List<string> is a kind of IList<string>.
Well, for starters, just look at the members of IList and compare it with List. List has methods that an IList doesn't. (List has a BinarySearch method that IList doesn't, just as a single example.)
Arrays also implement IList, as an example. An array however is not a List, so you can't, and shouldn't, be able to pass a string[] to a method that accepts a List<string>.
You have a few possible solutions. One would be to just change your method to return a List<string> rather than an IList<string> (that's what I'd suggest). If that's what you really need then you shouldn't be restricting the return type to IList<string>. Another (poorer) option would be to cast the result back to a List<string> before passing it to the next method, since you happen to know that it's what the underlying type really is.
After all, List<string> is a kind of IList<string>.
But there are also other kinds of IList<String>.
What if your method were to return an IList<String> which is a ReadOnlyCollection<String> instead?
IList<string> x = new ReadOnlyCollection<string>();
List<string> y = x; //Huh?
The compiler uses the signature of your methods, not the implementation when deciding if you can assign the result of GetBookTitles to your variable, so it can't know that the result will in fact be a List. If it would allow you to do such a thing, then you could write something like this:
List<string> myBooks = GetBookTitles();
myBooks.Sort();
In your example you could do this, and in fact you can if you cast the result of your method:
List<string> myBooks = (List<string>)GetBookTitles();
But then one day you could decide that your book collection is not modifiable, and you rewrite your method as follows:
public IList<string> GetBookTitles()
{
IList<string> tmp = new List<string>();
// do something to populate the bookTitles list.
IList<string> bookTitles = new ReadOnlyCollection<string>(tmp);
return bookTitles;
}
ReadOnlyCollection does not implement Sort, so your app would compile, but would crash at runtime.
Using the cast approach it would crash when trying to do the cast, but in this case you are taking the responsibility of deciding that that kind of cast is feasible and do not have the compiler trying to guess.
A better approach could be to use as instead of the cast and chek for null. I.e.:
List<string> myBooks = GetBookTitles() as List<string>;
if (myBooks != null)
myBooks.Sort();
You should be able to, you just need an explicit conversion.
List<string> foo = (List<string>)GetBookTitles()
should do it.
The interface may be implemented in various classes which are not same. So, it will be difficult to find the respective class.
You can type cast from IList to List!!!

What's the proper way to handle a variable across multiple methods?

Say I have a List<Objects>. I want to define the list of objects in one method, and use them in several others.
Here's the ways I've come up with and I'm looking for more or the correct way to do it.
You can define List<Objects> in every method that uses it.
Pros: It works. No chance of getting the wrong variable.
Cons: Code duplication.
You can use a private List<Objects> defined in the class and update it using (ref ListObjects)
Pros: I only have to define it once.
Cons: I feel like it's messy and bad practice.
You can pass List<Objects> as a parameter to the methods that use it.
Pros: Prevents code duplication
Cons: Have to make my populate functions return functions, and add parameters to my other methods. Possible conflicts with Events?
So that's what I've come up with. I'm really not sure which to use or if there's a better way to do this. Thoughts?
EDIT: Including some code as requested.
private List<MedicalPlan> medicalPlansList;
This is the list. It is a list that gets information from a database, here:
private void BindMedicalList()
{
medicalPlansList = new MedicalPlanRepository().RetrieveAll().Where(x => x.Year == year).ToList();
}
Then it's used to find objects in that list, such as
var result =
medicalPlansList.FirstOrDefault(
c => c.CoverageLevels.Any(p => p.Id == id));
This is, in general, how I'd do it. If you always use the same sequence of functions on a list, consider creating a chained function to handle that. You can also directly pass a function call inside one of the other function calls (as long as it returns a list), but that tends to look messy.
public List<int> DoSomethingWithList(List<int> list)
{
//do stuff
return list;
}
public List<int> DoSomethingElseWithList(List<int> list)
{
//do other stuff
return list;
}
public void SomeOtherFunction(string[] args)
{
var list = new List<int>() { 1, 2, 3, 4 }; //create list
list = DoSomethingWithList(list); //change list
list = DoSomethingElseWithList(list); //change list further
}
If you are working with an object that has a List<T> field, I'd do like this:
public class MyBigClass
{
private List<int> myList;
public MyBigClass()
{
//instantiate list in constructor
myList = new List<int>() { 1, 2, 3, 4 };
}
public void PublicListAdder(int val)
{
myList.Add(val);
}
private void PrivateListCleaner()
{
//remove all even numbers, just an example
myList.RemoveAll(x => x % 2 == 0);
}
}
You rarely need to use ref in C#, because it automatically handles pointers for you. You are (usually) not passing around a struct, you are passing around an object reference (which basically is a pointer).
Your #1 and #2 don't really make sense:
If you define a different list in every method that uses it, then you're using a different list each time. This is not sharing the list; this doesn't work. If you mean "call your method that creates the list from each method that uses it" then the same still applies: you're using a different list each time.
You don't need to use ref ListObjects to update a private member; a private member is just accessed by its name. This isn't bad practice; this is standard object-oriented practice.
Passing all required data into a method as parameters makes the method inherently more reusable as it reduces coupling to the class the method belongs to.
In short: #3 is good practice to an extent, as it increases the reusability of code. However, the use of #2 is fundamentally the reason we have Object-Oriented programming: to save you from repeatedly passing parameters into all your methods. This is exactly what private fields are designed for!
In most cases, I would probably go with Anders' answer. Depending on your situation, another way that is worth considering is to write extension methods for List.
namespace ExtensionMethods
{
public static class MyExtensions
{
public static object DoSomething(this List<T> list)
{
//do the something with list
}
}
}
And then you can use it like so:
var list = new List<int>();
list.DoSomething();
In that example, list is passed as the parameter to the extension method.
Usually a List<T> shouldn't belong to the state of an instance and exposed since it's mutable and you may change the state from the outside otherwise -unless your getter is designed to return a readonly list. Unless your design clearly allow such a possibility when it may occur. My reply doesn't really answer to your question is just a suggestion of good object oriented design. As someone already suggested much better than me you may pass a List back and forth each method and directly modify it.

How to get an empty list of a collection?

I have a collection of anonymous class and I want to return an empty list of it.
What is the best readable expression to use?
I though of the following but I don't think they are readably enough:
var result = MyCollection.Take(0).ToList();
var result = MyCollection.Where(p => false).ToList();
Note: I don't want to empty the collection itself.
Any suggestion!
Whats about:
Enumerable.Empty<T>();
This returns an empty enumerable which is of type T. If you really want a List so you are free to do this:
Enumerable.Empty<T>().ToList<T>();
Actually, if you use a generic extension you don't even have to use any Linq to achieve this, you already have the anonymous type exposed through T
public static IList<T> GetEmptyList<T>(this IEnumerable<T> source)
{
return new List<T>();
}
var emp = MyCollection.GetEmptyList();
Given that your first suggestion works and should perform well - if readability is the only issue, why not create an extension method:
public static IList<T> CreateEmptyCopy(this IEnumerable<T> source)
{
return source.Take(0).ToList();
}
Now you can refactor your example to
var result = MyCollection.CreateEmptyCopy();
For performance reasons, you should stick with the first option you came up with.
The other one would iterate over the entire collection before returning an empty list.
Because the anonymous type there is no way, in source code, to create a list. There is, however, a way to create such list through reflection.

Ugly thing and advantage of anonymos method -C#

I was asked to explain the ugly thing and advantages of anonymous method.
I explained possibly
Ugly thing
anonymous methods turning quickly into spaghetti code.
Advantages
We can produce thread safe code using anonymous method :Example
static List<string> Names = new List<string>(
new string[] {
"Jon Skeet",
"Marc Gravell",
"David",
"Bill Gates"
});
static List<string> FindNamesStartingWith(string startingText)
{
return Names.FindAll(
delegate(string name)
{
return name.StartsWith(startingText);
});
}
But really i did not know whether it is thread safe or not.I was asked to justify it.
Can any one help me to understand
(1) advantages of anonymous methods
(2) Is the above code thread safe or not?
Well, "thread safe" is a pretty broad term. What sort of multi-threaded use are you thinking of? I'd expect it to be safe without any data corruption or exceptions if nothing's writing to the list...
Now, as for the "ugliness" of anonymous methods... are you using C# 3? If so, start using lambda expressions, which are generally cleaner:
static List<string> FindNamesStartingWith(string startingText)
{
return Names.FindAll(name => name.StartsWith(startingText));
}
Alternatively, using LINQ:
static List<string> FindNamesStartingWith(string startingText)
{
return Names.Where(name => name.StartsWith(startingText)).ToList();
}
Or if you don't necessarily need a list:
static IEnumerable<string> FindNamesStartingWith(string startingText)
{
return Names.Where(name => name.StartsWith(startingText));
}
Or if you prefer a query expression:
static IEnumerable<string> FindNamesStartingWith(string startingText)
{
return from name in names
where name.StartsWith(startingText)
select name;
}
None of these look like spaghetti code to me. However, if you're going to ask whether you should use this or something else, you should really put forward an alternative. Here's a simple one:
static List<string> FindNamesStartingWith(string startingText)
{
List<string> ret = new List<string>();
foreach (string name in Names)
{
if (name.StartsWith(startingText))
{
ret.Add(name);
}
}
return ret;
}
Do you find that clearer? If so, that's fine - but I suspect it's just that you're not really familiar with anonymous functions, LINQ etc. As you can see, there's significantly more code - it would definitely take me longer to check that that does the right thing than any of the earlier samples.
Well, it all depends on what you mean by thread-safe.
If, during the execution of FindAll, some other thread changes the underlying Names collection, then you might get odd results.
Is multiple calls to FindAll on multiple threads safe by themselves, that is, with only them executing? Yes, that's a definite yes.
As for the advantages of anonymous methods, consider the alternative.
You want to:
Find some item of the collection
The only way to know which item you want to find is to evaluate some expression for each one
You could do it like this:
List<string> result = new List<string>();
foreach (string name in Names)
if (name.StartsWith(startingText))
result.Add(name);
return result;
or, given the new lambda syntax, you could do it like this:
return Names.FindAll(name => name.StartsWith(startingText));
I know which one I prefer, but they do different things, with the same result (in this case.)
In the first case, you execute all the code yourself, there's no magic.
In the second case, you give to FindAll a way to figure out which items to put into the result. There is no non-executable way to do that in this case, you need to have FindAll execute some code, that you specify, for each item.

Categories

Resources