Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
05/28/09 18:06:43 (16 years ago)
Author:
epitzer
Message:

Resolve name clashes of overridden and shadowed properties (#659)

Location:
trunk/sources/HeuristicLab.Persistence
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/DataMemberAccessor.cs

    r1852 r1938  
    1212    public readonly object DefaultValue;
    1313
    14     public DataMemberAccessor(
    15         MemberInfo memberInfo,
    16         StorableAttribute storableAttribute,
    17         object obj) {
     14    public DataMemberAccessor(MemberInfo memberInfo, string name, object defaultvalue, object obj) {
     15      Name = name;
     16      DefaultValue = defaultvalue;
    1817      if (memberInfo.MemberType == MemberTypes.Field) {
    1918        FieldInfo fieldInfo = (FieldInfo)memberInfo;
     
    3231          "The Storable attribute can only be applied to fields and properties.");
    3332      }
    34       Name = storableAttribute.Name ?? memberInfo.Name;
    35       DefaultValue = storableAttribute.DefaultValue;
    3633    }
    3734
    38     public DataMemberAccessor(
    39         string name, object defaultValue,
     35    public DataMemberAccessor(string name, object defaultValue,
    4036        Func<object> getter, Action<object> setter) {
    4137      Name = name;
     
    6157
    6258    public override string ToString() {
    63       return String.Format("DataMember({0}, {1}, {2}, {3})",
     59      return String.Format("DataMemberAccessor({0}, {1}, {2}, {3})",
    6460        Name,
    6561        DefaultValue ?? "<null>",
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableAttribute.cs

    r1893 r1938  
    22using System.Collections.Generic;
    33using System.Reflection;
     4using System.Text;
    45
    56namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable {
     
    1415    public object DefaultValue { get; set; }
    1516
     17    public override string ToString() {
     18      StringBuilder sb = new StringBuilder();
     19      sb.Append("[Storable");
     20      if (Name != null || DefaultValue != null)
     21        sb.Append('(');
     22      if (Name != null) {
     23        sb.Append("Name = \"").Append(Name).Append("\"");
     24        if (DefaultValue != null)
     25          sb.Append(", ");
     26      }
     27      if (DefaultValue != null)
     28        sb.Append("DefaultValue = \"").Append(DefaultValue).Append("\"");
     29      if (Name != null || DefaultValue != null)
     30        sb.Append(')');
     31      sb.Append(']');
     32      return sb.ToString();
     33    }
     34
    1635    private const BindingFlags instanceMembers =
    1736      BindingFlags.Instance |
     
    2039      BindingFlags.DeclaredOnly;
    2140
    22     private static Dictionary<KeyValuePair<Type, bool>, IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>>> memberCache =
    23       new Dictionary<KeyValuePair<Type, bool>, IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>>>();
     41    public sealed class StorableMemberInfo {
     42      public StorableAttribute Attribute { get; private set; }
     43      public MemberInfo MemberInfo { get; private set; }
     44      public StorableMemberInfo(StorableAttribute attribute, MemberInfo memberInfo) {
     45        this.Attribute = attribute;
     46        this.MemberInfo = memberInfo;
     47      }
     48      public override string ToString() {
     49        return new StringBuilder()
     50          .Append('[').Append(Attribute).Append(", ")
     51          .Append(MemberInfo).Append('}').ToString();
     52      }
     53    }
    2454
    25     public static IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>> GetStorableMembers(Type type) {
     55    sealed class TypeQuery {
     56      public Type Type { get; private set; }
     57      public bool Inherited { get; private set; }
     58      public TypeQuery(Type type, bool inherited) {
     59        this.Type = type;
     60        this.Inherited = inherited;
     61      }
     62    }
     63
     64    sealed class MemberCache : Dictionary<TypeQuery, IEnumerable<StorableMemberInfo>> { }
     65
     66    private static MemberCache memberCache = new MemberCache();
     67
     68    public static IEnumerable<StorableMemberInfo> GetStorableMembers(Type type) {
    2669      return GetStorableMembers(type, true);
    2770    }
    2871
    29     public static IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>>
    30         GetStorableMembers(Type type, bool inherited) {
    31       var query = new KeyValuePair<Type, bool>(type, inherited);
     72    public static IEnumerable<StorableMemberInfo> GetStorableMembers(Type type, bool inherited) {
     73      var query = new TypeQuery(type, inherited);
    3274      if (memberCache.ContainsKey(query))
    3375        return memberCache[query];
    34       IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>> storablesMembers = GenerateStorableMembers(type, inherited);
     76      var storablesMembers = GenerateStorableMembers(type, inherited);
    3577      memberCache[query] = storablesMembers;
    3678      return storablesMembers;
    3779    }
    3880
    39     public static IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>>
    40         GenerateStorableMembers(Type type, bool inherited) {
    41       List<KeyValuePair<StorableAttribute, MemberInfo>> storableMembers =
    42         new List<KeyValuePair<StorableAttribute, MemberInfo>>();
     81    private static IEnumerable<StorableMemberInfo> GenerateStorableMembers(Type type, bool inherited) {
     82      var storableMembers = new List<StorableMemberInfo>();
    4383      if (inherited && type.BaseType != null)
    44         storableMembers.AddRange(GenerateStorableMembers(type.BaseType, true));       
     84        storableMembers.AddRange(GenerateStorableMembers(type.BaseType, true));
    4585      foreach (MemberInfo memberInfo in type.GetMembers(instanceMembers)) {
    4686        foreach (object attribute in memberInfo.GetCustomAttributes(false)) {
    47           StorableAttribute storableAttribute =
    48             attribute as StorableAttribute;
     87          StorableAttribute storableAttribute = attribute as StorableAttribute;
    4988          if (storableAttribute != null) {
    50             storableMembers.Add(new KeyValuePair<StorableAttribute, MemberInfo>(storableAttribute, memberInfo));
     89            storableMembers.Add(new StorableMemberInfo(storableAttribute, memberInfo));
    5190          }
    5291        }
     
    5695
    5796    public static Dictionary<string, DataMemberAccessor> GetStorableAccessors(object obj) {
    58       Dictionary<string, DataMemberAccessor> storableAccessors =
    59         new Dictionary<string, DataMemberAccessor>();
    60       foreach (KeyValuePair<StorableAttribute, MemberInfo> pair in GetStorableMembers(obj.GetType())) {
    61         storableAccessors.Add(pair.Value.Name,
    62           new DataMemberAccessor(pair.Value, pair.Key, obj));
     97      var storableAccessors = new Dictionary<string, DataMemberAccessor>();
     98      var nameMapping = createNameMapping(obj.GetType());
     99      var finalNameMapping = analyzeNameMapping(nameMapping);
     100      foreach (var mapping in finalNameMapping) {
     101        storableAccessors.Add(mapping.Value.Attribute.Name ?? mapping.Key,
     102          new DataMemberAccessor(
     103            mapping.Value.MemberInfo,
     104            mapping.Value.Attribute.Name ?? mapping.Key,
     105            mapping.Value.Attribute.DefaultValue,
     106            obj));
    63107      }
    64108      return storableAccessors;
    65109    }
     110
     111    private static Dictionary<string, StorableMemberInfo> analyzeNameMapping(
     112        Dictionary<string, List<StorableMemberInfo>> nameMapping) {
     113      var finalNameMapping = new Dictionary<string, StorableMemberInfo>();
     114      foreach (var attributes in nameMapping) {
     115        if (attributes.Value.Count == 1) {
     116          finalNameMapping[attributes.Key] = attributes.Value[0];
     117        } else if (attributes.Value[0].MemberInfo.MemberType == MemberTypes.Field) {
     118          foreach (var attribute in attributes.Value) {
     119            StringBuilder sb = new StringBuilder();
     120            sb.Append(attribute.MemberInfo.ReflectedType.FullName).Append('.')
     121              .Append(attribute.MemberInfo.Name);
     122            finalNameMapping[sb.ToString()] = attribute;
     123          }
     124        } else {
     125          var uniqueAccessors = new Dictionary<Type, StorableMemberInfo>();
     126          foreach (var attribute in attributes.Value) {
     127            uniqueAccessors[((PropertyInfo)attribute.MemberInfo).GetGetMethod(true).GetBaseDefinition().DeclaringType] =
     128              attribute;
     129          }
     130          if (uniqueAccessors.Count == 1) {
     131            var it = uniqueAccessors.Values.GetEnumerator();
     132            it.MoveNext();
     133            finalNameMapping[attributes.Key] = it.Current;
     134          } else {
     135            foreach (var attribute in uniqueAccessors.Values) {
     136              StringBuilder sb = new StringBuilder();
     137              sb.Append(attribute.MemberInfo.DeclaringType.FullName).Append('.')
     138                .Append(attribute.MemberInfo.Name);
     139              finalNameMapping[sb.ToString()] = attribute;
     140            }
     141          }
     142        }
     143      }
     144      return finalNameMapping;
     145    }
     146
     147    private static Dictionary<string, List<StorableMemberInfo>> createNameMapping(Type type) {
     148      var nameMapping = new Dictionary<string, List<StorableMemberInfo>>();
     149      foreach (StorableMemberInfo storable in GetStorableMembers(type)) {
     150        if (!nameMapping.ContainsKey(storable.MemberInfo.Name))
     151          nameMapping[storable.MemberInfo.Name] = new List<StorableMemberInfo>();
     152        nameMapping[storable.MemberInfo.Name].Add(storable);
     153      }
     154      return nameMapping;
     155    }
    66156  }
    67157}
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs

    r1852 r1938  
    3434    public IEnumerable<Tag> Decompose(object obj) {
    3535      foreach (var mapping in StorableAttribute.GetStorableAccessors(obj)) {
    36         yield return new Tag(mapping.Value.Name ?? mapping.Key, mapping.Value.Get());
     36        yield return new Tag(mapping.Key, mapping.Value.Get());
    3737      }
    3838    }
     
    4949      }
    5050      foreach (var mapping in StorableAttribute.GetStorableAccessors(instance)) {
    51         string name = mapping.Value.Name ?? mapping.Key;
     51        string name = mapping.Key;
    5252        if (memberDict.ContainsKey(name)) {
    5353          mapping.Value.Set(memberDict[name].Value);
  • trunk/sources/HeuristicLab.Persistence/UnitTests/StorableAttributeTests.cs

    r1823 r1938  
    44using Microsoft.VisualStudio.TestTools.UnitTesting;
    55using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     6using System.Reflection;
    67
    78namespace HeuristicLab.Persistence.Test {
     
    1920  }
    2021
     22  class Base {
     23    public string baseName;
     24    [Storable]
     25    public virtual string Name {
     26      get { return "Base"; }
     27      set { baseName = value; }
     28    }
     29  }
     30
     31  class Override : Base {
     32    [Storable]
     33    public override string Name {
     34      get { return "Override"; }
     35      set { base.Name = value; }
     36    }
     37  }
     38
     39  [EmptyStorableClass]
     40  class Intermediate : Override {
     41  }
     42
     43  class New : Intermediate {
     44    public string newName;
     45    [Storable]
     46    public new string Name {
     47      get { return "New"; }
     48      set { newName = value; }
     49    }
     50  }
     51
    2152  [TestClass]
    2253  public class AttributeTest {
     
    2657      DemoClass t = new DemoClass();
    2758      Dictionary<string, DataMemberAccessor> accessors = StorableAttribute.GetStorableAccessors(t);
    28       Assert.IsTrue(accessors.ContainsKey("o"));
     59      Assert.IsTrue(accessors.ContainsKey("TestProperty"));
    2960      Assert.IsTrue(accessors.ContainsKey("x"));
    3061      Assert.IsFalse(accessors.ContainsKey("y"));
    3162      object o = new object();
    3263      t.o = o;
    33       Assert.AreSame(accessors["o"].Get(), o);
     64      Assert.AreSame(accessors["TestProperty"].Get(), o);
    3465      t.x = 12;
    3566      Assert.AreEqual(accessors["x"].Get(), 12);
    3667      t.y = 312890;
    37       accessors["o"].Set(null);
     68      accessors["TestProperty"].Set(null);
    3869      Assert.IsNull(t.o);
    3970      accessors["x"].Set(123);
     
    4172    }
    4273
     74    [TestMethod]
     75    public void TestInheritance() {
     76      New n = new New();
     77      var accessors = StorableAttribute.GetStorableAccessors(n);
     78      var accessDict = new Dictionary<string, DataMemberAccessor>();
     79      foreach (var accessor in accessors) // assert uniqueness
     80        accessDict.Add(accessor.Key, accessor.Value);
     81      Assert.IsTrue(accessDict.ContainsKey(typeof(New).FullName + ".Name"));
     82      Assert.IsTrue(accessDict.ContainsKey(typeof(Override).FullName + ".Name"));
     83      Assert.AreEqual("New", accessDict[typeof(New).FullName + ".Name"].Get());
     84      Assert.AreEqual("Override", accessDict[typeof(Override).FullName + ".Name"].Get());
     85    }
     86
    4387  }
    4488
  • trunk/sources/HeuristicLab.Persistence/UnitTests/UseCases.cs

    r1823 r1938  
    1616using HeuristicLab.Persistence.Auxiliary;
    1717using System.Text.RegularExpressions;
     18using HeuristicLab.Persistence.Test;
    1819
    1920namespace HeuristicLab.Persistence.UnitTest {
     
    541542    }
    542543
     544    [TestMethod]
     545    public void InheritanceTest() {
     546      New n = new New();
     547      XmlGenerator.Serialize(n, tempFile);
     548      New nn = (New)XmlParser.Deserialize(tempFile);
     549      Assert.AreEqual(n.Name, nn.Name);
     550      Assert.AreEqual(((Override)n).Name, ((Override)nn).Name);
     551    }
     552
    543553    [ClassInitialize]
    544554    public static void Initialize(TestContext testContext) {
Note: See TracChangeset for help on using the changeset viewer.