Assume I have a class A that has a private List Plist and the functions necessary for basic interaction with it (adding, deleting etc). In my class B, I use these functions, but also want to iterate/search/whatever over it via LINQ in many different ways. Creating a new function for every query seems unreasonable, so I wonder if I could create a function that takes a query as an argument and applies it to the private list. I am aware that it pretty much defeats the point of having the list private in the first place, however Im wondering if it's possible
Technically, I would like it to work like this (which it obviously doesnt, but you get the idea):
public class A
{
private List<C> Plist { get; set; } = new List<C>();
public C Search(string query)
{
this.Plist.query
}
}
public class B
{
A a = new A();
a.Search("Where(i => i.AnotherListInC.Contains(SomeObject))");
}
Is there a way to access a private property with complex LINQ queries, or more generally, concatenate a string to existing code to create new code?
If you need to use String as parameter it will be hard as you would have to emit code. If you just want to search private list than create method that accepts predicate as parameter:
public class A
{
private List<C> Plist { get; set; } = new List<C>();
public IEnumerable<C> Search(Func<C, bool> predicate)
{
return this.Plist.Where(predicate);
}
}
public class B
{
public void SomeMethod()
{
A a = new A();
a.Search(i => i.AnotherListInC.Contains(SomeObject));
}
}
Similar method can be written for any Linq
method. Just create method that accepts the same parameters as Linq
method except of first parameter (IEnumerable<TSource>
).
In case you want all Linq
methods available you can implement IEnumerable<C>
on your class A
public class A : IEnumerable<C>
{
private List<C> Plist { get; set; } = new List<C>();
public IEnumerator<C> GetEnumerator()
{
return ((IEnumerable<C>)Plist).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<C>)Plist).GetEnumerator();
}
}
public class B
{
public void SomeMethod()
{
A a = new A();
a.Where(i => i.AnotherListInC.Contains(SomeObject));
a.Any(i => i.AnotherListInC.Contains(SomeObject));
}
}