title: Get attribute values from property and list values without knowing the attribute type
body: <p>I want to pass in the attribute name and return the value.  This will be in a generic util and it will not know the attribute type.  </p>
  
  <p><strong>Update</strong>
  This is the actual working code if someone needs to do this.  I needed a way to have the core code parse the attributes without knowing what they were.</p>
  
  <pre><code>public void LoadPropertiesToGrid(BaseGridPropertyModel model)
  {
      foreach (PropertyInfo prop in ReflectionUtil.FindPublicPropeties(model))
      {
          object editTyp = ReflectionUtil.GetPropertyAttributes(prop, "EditorType"); 
          object rowIdx = ReflectionUtil.GetPropertyAttributes(prop, "ColIndex");
          object name = ReflectionUtil.GetPropertyAttributes(prop, "Name");
          object visible = ReflectionUtil.GetPropertyAttributes(prop, "Visible");
          ConfigureColumn((string) name, (int) rowIdx, (bool) visible, (string) editTyp);
       }
  }
  [Serializable]
  public class CanvasPropertiesViewModel : BaseGridPropertyModel
  {
      [PropertiesGrid(Name = "TEsting Name 0", ColIndex = 0)]
      public string StringData1 { get; set; }
  
      [PropertiesGrid(Name = "TEsting Name 2", ColIndex = 2)]
      public string StringData2 { get; set; }
  
      [PropertiesGrid(Name = "TEsting Name 1", ColIndex = 1)]
      public string StringData3 { get; set; }
  }
  [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
  public sealed class PropertiesGridAttribute : Attribute
  {
      /// &lt;summary&gt;
      /// Editor type
      /// &lt;/summary&gt;
      public Type EditorType { get; set; }
  
      /// &lt;summary&gt;
      /// Sets Column Index
      /// &lt;/summary&gt;
      public int ColIndex { get; set; }
  
      /// &lt;summary&gt;
      /// Visible to Grid
      /// &lt;/summary&gt;
      public bool Visible { get; set; }
  
      /// &lt;summary&gt;
      /// Dispaly Name of the property
      /// &lt;/summary&gt;
      public string Name { get; set; }
  }
  public static object GetPropertyAttributes(PropertyInfo prop, string attributeName)
  {
      // look for an attribute that takes one constructor argument
      foreach (CustomAttributeData attribData in prop.GetCustomAttributesData())
      {
          string typeName = attribData.Constructor.DeclaringType.Name;
          //if (attribData.ConstructorArguments.Count == 1 &amp;&amp; (typeName == attributeName || typeName == attributeName + "Attribute"))
          //{
          //    return attribData.ConstructorArguments[0].Value;
          //}
          foreach (CustomAttributeNamedArgument att in attribData.NamedArguments)
          {
              if(att.GetPropertyValue&lt;string&gt;("MemberName") == attributeName)
              {
                  return att.TypedValue.Value;
              }
          }
      }
      return null;
  }
  
  //PropertyExpressionParser 
  public static TRet GetPropertyValue&lt;TRet&gt;(this object obj, string propertyPathName)
  {
      if (obj == null)
      {
          throw new ArgumentNullException("obj");
      }
  
      string[] parts = propertyPathName.Split('.');
      string path = propertyPathName;
      object root = obj;
  
      if (parts.Length &gt; 1)
      {
          path = parts[parts.Length - 1];
          parts = parts.TakeWhile((p, i) =&gt; i &lt; parts.Length - 1).ToArray();
          string path2 = String.Join(".", parts);
          root = obj.GetPropertyValue&lt;object&gt;(path2);
      }
  
      var sourceType = root.GetType();
      var value = (TRet)sourceType.GetProperty(path).GetValue(root, null);
      return value;
  }
  </code></pre>