|
Awesome. Write it up as a tip with some examples.
If it's not broken, fix it until it is
|
|
|
|
|
So I just did this:
class Program
{<br />
static List<Person> people = new List<Person>();
static void Main(string[] args)
{
people.Add(new Person { Name = "Joan", Age = 102 });
people.Add(new Person { Name = "Pete", Age = 50 });
people.Add(new Person { Name = "Walter", Age = 65 });
people.Add(new Person { Name = "Joan", Age = 17 });
people.Add(new Person { Name = "Walter", Age = 25 });
var person1 = people.FindExact<Person>("Name", "Pete");
var person2 = people.FindFirstExact<Person>("Name", "Walter");
var person3 = people.FindLastExact<Person>("Name", "Joan");
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public override string ToString()
{
return Name + " - " + Age.ToString();
}
}
Works great - if what you're looking for is a string. Maybe enhance so I could search on any property type?
Something similar to this:
public static List<T> FindExact<T,P>(this List<T> list, string valuePropertyName, P propertyValue)
{
List<T> found = default(List<T>);
try
{
PropertyInfo info = typeof(T).GetProperty(valuePropertyName);
found = (from item in list
let value = (string)(info.GetValue(item, null))
where (P)value == propertyValue
select item).ToList();
}
catch (Exception)
{
}
return found;
}
(won't compile, but the idea is nice
If it's not broken, fix it until it is
modified 9-Jun-16 13:43pm.
|
|
|
|
|
This is specifically for finding objects in the list that contain the specified string. Feel free to adapt it to your needs.
".45 ACP - because shooting twice is just silly" - JSOP, 2010
- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010
- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Nice one
The only thing I would change is to use an IEnumerable<t> instead of a List<t>.
That would make the extension method more flexible and make FindExact defered execution instead of greedy because of the toList()
Some quick write in LinqPad
void Main()
{
List<Person> people = new List<Person>();
people.Add(new Person { Name = "Joan", Age = 102 });
people.Add(new Person { Name = "Pete", Age = 50 });
people.Add(new Person { Name = "Walter", Age = 65 });
people.Add(new Person { Name = "Joan", Age = 17 });
people.Add(new Person { Name = "Walter", Age = 25 });
var person1 = people.FindExact<Person>("Name", "Pete");
var person2 = people.FindFirstExact<Person>("Name", "Walter");
var person3 = people.FindLastExact<Person>("Name", "Joan");
person1.Dump();
person2.Dump();
person3.Dump();
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public override string ToString()
{
return Name + " - " + Age.ToString();
}
}
public static class Extensions
{
public static IEnumerable<T> FindExact<T>(this IEnumerable<T> list, string valuePropertyName, string text)
{
IEnumerable<T> found = default(IEnumerable<T>);
try
{
PropertyInfo info = typeof(T).GetProperty(valuePropertyName);
found = from item in list
let value = (string)(info.GetValue(item, null))
where value == text
select item;
}
catch (Exception)
{
}
return found;
}
public static T FindFirstExact<T>(this IEnumerable<T> list, string valuePropertyName, string text)
{
T found = default(T);
try
{
found = list.FindExact(valuePropertyName, text).FirstOrDefault();
}
catch (Exception)
{
}
return found;
}
public static T FindLastExact<T>(this IEnumerable<T> list, string valuePropertyName, string text)
{
T found = default(T);
try
{
found = list.Reverse().FindExact(valuePropertyName, text).First();
}
catch (Exception)
{
}
return found;
}
}
Vince
Remember the dead, fight for the living
|
|
|
|
|
Not sure you really need let in that example:
public static IEnumerable<T> FindExact<T>(this IEnumerable<T> list, string valuePropertyName, string text)
{
IEnumerable<T> found = Enumerable.Empty<T>();
try
{
PropertyInfo info = typeof(T).GetProperty(valuePropertyName);
if (info != null && info.CanRead && info.PropertyType == typeof(string) && info.GetIndexParameters().Length == 0)
{
found = list.Where(item => item != null && (string)info.GetValue(item, null) == text).ToList();
}
}
catch (Exception)
{
}
return found;
}
As Vince said, it's probably better to use IEnumerable<T> , rather than a List<T> . You can still eagerly evaluate the sequence to prevent exceptions from being thrown during enumeration.
You can eliminate most of the exceptions be checking that the property is found, can be read, returns a string , and doesn't have any index parameters; and by checking that the item is not null .
And I'd be inclined to return an empty sequence if the property is invalid or you get an exception, so that you don't have to check the returned value for null all the time.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Richard Deeming wrote: You can eliminate most of the exceptions be checking that the property is found, can be read, returns a string , and doesn't have any index parameters; and by checking that the item is not null .
In the event of any exception, it returns null. There's no need for the extra sanity check code.
".45 ACP - because shooting twice is just silly" - JSOP, 2010
- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010
- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
But at what cost?
Throwing and catching an exception will seriously degrade your code's performance. When there's a simple sanity-check that can avoid the exception, it's always preferable to use it.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Richard Deeming wrote: Throwing and catching an exception will seriously degrade your code's performance.
That's only true if you're throwing them by default instead of exception and even then in the most trivial cases. In the real world once you go beyond trivial math/string fiddling to anything with a file or database access even using exceptions as your primary control method will have a negligible impact.
Performance implications of Exceptions in .NET[^]
Did you ever see history portrayed as an old man with a wise brow and pulseless heart, waging all things in the balance of reason?
Is not rather the genius of history like an eternal, imploring maiden, full of fire, with a burning heart and flaming soul, humanly warm and humanly beautiful?
--Zachris Topelius
Training a telescope on one’s own belly button will only reveal lint. You like that? You go right on staring at it. I prefer looking at galaxies.
-- Sarah Hoyt
|
|
|
|
|
It's still better to use simple sanity checks where possible.
This:
string name = (person != null) ? person.Name : string.Empty;
or, in C# 6:
string name = person?.Name ?? string.Empty;
is much better than:
string name = string.Empty;
try
{
name = person.Name;
}
catch (NullReferenceException)
{
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Good call on returning an empty sequence. More in line with the standards in Linq for a collection. I have missed that one.
Vince
Remember the dead, fight for the living
|
|
|
|
|
Richard Deeming wrote:
found = list.Where(item => item != null && (string)info.GetValue(item, null) == text).ToList();
Do you really think you need to check the item for null here? It is, after all, a list of <T> , so no item in the list will/should be null (unless you're doing some really weird stuff in terms of removal).
".45 ACP - because shooting twice is just silly" - JSOP, 2010
- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010
- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
John Simmons / outlaw programmer wrote: It is, after all, a list of <T> , so no item in the list will/should be null
There's no restriction on the generic type parameter, so it could quite easily be a reference type.
Lists of reference types can quite happily contain null items. No need for any "weird stuff"!
var listOfStrings = new List<string>();
listOfStrings.Add(null);
listOfStrings.Add(default(string));
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Damn! You're not as stupid as I look!
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
Useful code, John, thanks ! Also a great discussion, the kind I most enjoy.
I second Kevin's suggestion you write this up as a tip/trick.
cheers, Bill
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
modified 9-Jun-16 23:08pm.
|
|
|
|
|
Wow! I made something remarkably similar last night (i.e. string parsing) after having read Marc's post and having the need. Your solution has more elegance than mine me thinks.
Thanks to both of you.
|
|
|
|
|
|
Should be on the Insider News page. That's definitely worthy of being widely disseminated.
This space for rent
|
|
|
|
|
|
As was pointed out in the comments, BITS wasn't fooled. A program with admin access told BITS to do something and it did it. Once you have admin/root access, any accusations of compromise are specious.
|
|
|
|
|
Windows has become THE security risk.
All I want to know is - where is Borland?
|
|
|
|
|
It hasn't. Once you grant administrative access, you have no security. The same holds true for any OS. Windows is actually extremely secure and to rant that it isn't is naive and being misinformed.
|
|
|
|
|
Yes, and using BITS to do anything actually useful without admin access is so easy to implement.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
So I'm staying in an Extended Stay hotel while I work on a project for client.
Last night at 11:30 I was awoken with "entertainment" from the adjacent room... bed banging the wall, loud expressions of... well you get the idea..
So half an hour into this I decide to call the front desk. It's midnight at this point and I have to work in the morning. So I explain what's going on and the woman at the front desk says, while laughing, "Well we won't charge you for the entertainment package. I'll go up and talk to them". She never did.
Eventually, since all good things must come to and end, they stopped.
.
.
.
until 5:30 this morning when they woke me up AGAIN. Same thing.. bed banging the wall, woman going off.
This time I'm gonna raise hell.
If it's not broken, fix it until it is
|
|
|
|
|
My worst: A night in a hotel "up north" before a big meeting the next morning.
Midnight and I'm woken up by a huge amount of noise - it sound like someone is running a bunch of Pneumatic drills[^] outside my room. I look out the door - the corridor is clear (but noisy).
I look out the window - nothing.
I call reception.
"Ah. We're remodelling the hotel."
At night?
"Oh yes! It's so we don't inconvenience the guests..."
They moved me to a new room on the opposite side of the building, and I didn't get a bill...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Quote: They moved me to a new room on the opposite side of the building, and I didn't get a bill...
Yeah! Good for you! You shouldn't have to suffer the consequences of their moronic decisions!
Get me coffee and no one gets hurt!
|
|
|
|
|