Fog Creek Software
Discussion Board




Welcome! and rules

Joel on Software

Retrieving attribute information from field

I have defined my own IntegerRangeAttribute which is used like so:

  [IntegerRange(DefaultValue = 2000, MinimumValue = 0, MaximumValue = 1000000)]
  private Int32 iNumBurnInIterations = 2000;

At another point I want to get at that information, ie:

  public Int32 GetNumPreIterations ()
  {
      IntegerRangeAttribute range = GetIntegerRange(this.iNumBurnInIterations);

/* Do something here */

      return (this.iNumBurnInIterations);
  }

  private IntegerRangeAttribute GetIntegerRange (object o)
  {
      MemberInfo[] ami = this.GetType().GetMembers(BindingFlags.Instance | BindingFlags.NonPublic);
      foreach (MemberInfo mi in ami)
      {
        if (mi.Name == o.ToString())
            return ((IntegerRangeAttribute) System.Attribute.GetCustomAttribute(mi, typeof(IntegerRangeAttribute)));
      }

      return (null);
  }


Now the problem is, o.ToString() calls the Int32.ToString(), and the name won't match up. I don't know of a good way to get that string programmatically.

Is there a way to get that variable name? Is there a better way to retrive the attribute? 

Walt
Monday, April 25, 2005

Integer is an integer. There is no way for it to know, that it was the value of your private field once. You can change signature and use something like

IntegerRangeAttribute range = GetIntegerRange("iNumBurnInIterations");

DK
Monday, April 25, 2005

Yuk, using Attributes like this is ghastly.

Surely it'd be better to just sub-class the Integer (Int32) type and apply your rules there, or at construction time.

Joel Spolsky
Tuesday, April 26, 2005

Hi, Joel

Could you elaborate on that "yuk", please? It would be really nice to get your reasoning.

DK
Tuesday, April 26, 2005

I had trouble sleeping tonight, so instead sketched a code, that Joel might had in mind - something similar to DB types:

------------------------------------------
public class MyClass
{
  ...

  private ExtendedInt _burns
    = new ExtendedInt(0, 1000000, 2000);

  public int Burns
  {
    get { return (int)_burns; }
    set { _burns.Value = value; }
  }

  ...
}

internal class ExtendedInt
{
  int _value;
  int _min, _max, _default;

  public ExtendedInt(int min, int max, int @default)
  {
    _min = min; _max = max; _default = @default;
    _value = _default;
  }

  public int Value
  {
    get { return _value; }
    set { /* validate value */ _value = value; }
  }

  public static implicit operator int(ExtendedInt eInt)
  {
    return eInt.Value;
  }
}
------------------------------------------

Using property attributes to specify things like validation, mapping or some rendering parameters allows to write a very clean (simple, readable, maintainable) domain classes' code. But due to language limitations it also asks for significant effort in designing and implementing framework, that would gracefully handle these attributes.

DK
Tuesday, April 26, 2005

*  Recent Topics

*  Fog Creek Home