Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. Hey Marc Clifton!

Hey Marc Clifton!

Scheduled Pinned Locked Moved The Lounge
16 Posts 8 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Kevin Marois

    So I just did this:

    class Program
    {
    static List people = new List();
    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("Name", "Pete");
        var person2 = people.FindFirstExact("Name", "Walter");
        var person3 = people.FindLastExact("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 FindExact(this List list, string valuePropertyName, P propertyValue)
    {
    List found = default(List);
    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

    realJSOPR Offline
    realJSOPR Offline
    realJSOP
    wrote on last edited by
    #6

    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

    1 Reply Last reply
    0
    • Richard DeemingR Richard Deeming

      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

      realJSOPR Offline
      realJSOPR Offline
      realJSOP
      wrote on last edited by
      #7

      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

      Richard DeemingR 1 Reply Last reply
      0
      • Richard DeemingR Richard Deeming

        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

        V Offline
        V Offline
        Vincent Blais
        wrote on last edited by
        #8

        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

        1 Reply Last reply
        0
        • realJSOPR realJSOP

          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

          Richard DeemingR Offline
          Richard DeemingR Offline
          Richard Deeming
          wrote on last edited by
          #9

          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

          "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

          D 1 Reply Last reply
          0
          • realJSOPR realJSOP

            Welcome to yet another example of real-world application of an existing .Net feature. A few days ago, Mac Clifton made a Lounge post describing a little-known LINQ feature - the let clause. I'm sure several of you were wondering if you'd ever find a reason to use let in your own code. Well, I was writing some code today, and decided this would be a perfect example. The code in question is a List extension method which matches a named property to the specified text, and returns the first item whose (named) property is equal to that specified text. Without further ado, here's the method:

            public static List<T> FindExact<T>(this List<T> list, string valuePropertyName, string text)
            {
            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 value == text
            select item).ToList();
            }
            catch (Exception)
            {
            }
            return found;
            }

            public static T FindFirstExact<T>(this List<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 List<T> list, string valuePropertyName, string text)
            {
            T found = default(T);
            try
            {
            found = list.FindExact(valuePropertyName, text).LastOrDefault();
            }
            catch (Exception)
            {
            }
            return found;
            }

            The first thing I do is set found to default(T) (the only valid way to set a value to null in a method that uses generic types). Next, I get the property info for the named property. Finally, I use LINQ to find the first item whose (named) property matches the specified text. If an exception is thrown at any point in the method, a null result is returned. (In hindsight, it might be better to return a list of matching items instead of the first one, but you get the point.) EDIT ============================= I changed the code to be more flexible for my needs - I actually need to be able to find the first and/or last match, but don't care about anything between.

            M Offline
            M Offline
            Mark_Wallace
            wrote on last edited by
            #10

            Damn! You're not as stupid as I look!

            I wanna be a eunuchs developer! Pass me a bread knife!

            1 Reply Last reply
            0
            • realJSOPR realJSOP

              Welcome to yet another example of real-world application of an existing .Net feature. A few days ago, Mac Clifton made a Lounge post describing a little-known LINQ feature - the let clause. I'm sure several of you were wondering if you'd ever find a reason to use let in your own code. Well, I was writing some code today, and decided this would be a perfect example. The code in question is a List extension method which matches a named property to the specified text, and returns the first item whose (named) property is equal to that specified text. Without further ado, here's the method:

              public static List<T> FindExact<T>(this List<T> list, string valuePropertyName, string text)
              {
              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 value == text
              select item).ToList();
              }
              catch (Exception)
              {
              }
              return found;
              }

              public static T FindFirstExact<T>(this List<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 List<T> list, string valuePropertyName, string text)
              {
              T found = default(T);
              try
              {
              found = list.FindExact(valuePropertyName, text).LastOrDefault();
              }
              catch (Exception)
              {
              }
              return found;
              }

              The first thing I do is set found to default(T) (the only valid way to set a value to null in a method that uses generic types). Next, I get the property info for the named property. Finally, I use LINQ to find the first item whose (named) property matches the specified text. If an exception is thrown at any point in the method, a null result is returned. (In hindsight, it might be better to return a list of matching items instead of the first one, but you get the point.) EDIT ============================= I changed the code to be more flexible for my needs - I actually need to be able to find the first and/or last match, but don't care about anything between.

              B Offline
              B Offline
              BillWoodruff
              wrote on last edited by
              #11

              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

              1 Reply Last reply
              0
              • Richard DeemingR Richard Deeming

                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

                realJSOPR Offline
                realJSOPR Offline
                realJSOP
                wrote on last edited by
                #12

                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

                Richard DeemingR 1 Reply Last reply
                0
                • realJSOPR realJSOP

                  Welcome to yet another example of real-world application of an existing .Net feature. A few days ago, Mac Clifton made a Lounge post describing a little-known LINQ feature - the let clause. I'm sure several of you were wondering if you'd ever find a reason to use let in your own code. Well, I was writing some code today, and decided this would be a perfect example. The code in question is a List extension method which matches a named property to the specified text, and returns the first item whose (named) property is equal to that specified text. Without further ado, here's the method:

                  public static List<T> FindExact<T>(this List<T> list, string valuePropertyName, string text)
                  {
                  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 value == text
                  select item).ToList();
                  }
                  catch (Exception)
                  {
                  }
                  return found;
                  }

                  public static T FindFirstExact<T>(this List<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 List<T> list, string valuePropertyName, string text)
                  {
                  T found = default(T);
                  try
                  {
                  found = list.FindExact(valuePropertyName, text).LastOrDefault();
                  }
                  catch (Exception)
                  {
                  }
                  return found;
                  }

                  The first thing I do is set found to default(T) (the only valid way to set a value to null in a method that uses generic types). Next, I get the property info for the named property. Finally, I use LINQ to find the first item whose (named) property matches the specified text. If an exception is thrown at any point in the method, a null result is returned. (In hindsight, it might be better to return a list of matching items instead of the first one, but you get the point.) EDIT ============================= I changed the code to be more flexible for my needs - I actually need to be able to find the first and/or last match, but don't care about anything between.

                  M Offline
                  M Offline
                  Middle Manager
                  wrote on last edited by
                  #13

                  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. :thumbsup:

                  1 Reply Last reply
                  0
                  • Richard DeemingR Richard Deeming

                    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

                    D Offline
                    D Offline
                    Dan Neely
                    wrote on last edited by
                    #14

                    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 :omg: :wtf: 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

                    Richard DeemingR 1 Reply Last reply
                    0
                    • realJSOPR realJSOP

                      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

                      Richard DeemingR Offline
                      Richard DeemingR Offline
                      Richard Deeming
                      wrote on last edited by
                      #15

                      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

                      "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                      1 Reply Last reply
                      0
                      • D Dan Neely

                        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 :omg: :wtf: 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

                        Richard DeemingR Offline
                        Richard DeemingR Offline
                        Richard Deeming
                        wrote on last edited by
                        #16

                        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

                        "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups