Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/EnumerableDecomposer.cs @ 1542

Last change on this file since 1542 was 1542, checked in by epitzer, 15 years ago

Numerous small changes, coding conventions, renames, mini refactoring (#548)

File size: 2.3 KB
Line 
1using System;
2using System.Collections;
3using System.Reflection;
4using HeuristicLab.Persistence.Core;
5using HeuristicLab.Persistence.Interfaces;
6using System.Collections.Generic;
7
8namespace HeuristicLab.Persistence.Default.Decomposers {
9
10  public class EnumerableCache {
11    readonly List<object> values;
12    int nSet;
13    int count;
14    readonly object enumerable;
15    readonly MethodInfo addMethod;
16
17    public EnumerableCache(object enumerable, MethodInfo addMethod) {     
18      values = new List<object>();
19      this.enumerable = enumerable;
20      this.addMethod = addMethod;
21      count = -1;
22    }
23
24    public Setter GetNextSetter() {     
25      int index = values.Count;     
26      values.Add(new object());
27      return v => Set(index, v);
28    }
29
30    private void Set(int index, object value) {     
31      values[index] = value;
32      nSet += 1;
33      if (count >= 0 && nSet >= count)
34        Fill();
35    }
36
37    public void Terminate() {
38      count = values.Count;     
39      if (nSet >= count)
40        Fill();
41    }
42
43    private void Fill() {     
44      foreach ( object v in values ) {
45        addMethod.Invoke(enumerable, new[] {v});
46      }
47    }
48
49  }
50
51  public class EnumerableDecomposer : IDecomposer {
52
53    public int Priority {
54      get { return 100; }
55    }
56
57
58    public bool CanDecompose(Type type) {
59      return
60        type.GetInterface(typeof(IEnumerable).FullName) != null &&
61        type.GetMethod("Add") != null &&
62        type.GetMethod("Add").GetParameters().Length == 1 &&
63        type.GetConstructor(
64          BindingFlags.Public |
65          BindingFlags.NonPublic |
66          BindingFlags.Instance,
67          null, Type.EmptyTypes, null) != null;
68    }
69
70    public IEnumerable<Tag> Decompose(object obj) {
71      foreach (object o in (IEnumerable)obj) {
72        yield return new Tag(null, o);
73      }
74    }
75
76    public object CreateInstance(Type type) {
77      return Activator.CreateInstance(type, true);
78    }
79
80    public object Populate(object instance, IEnumerable<Tag> tags, Type type) {
81      MethodInfo addMethod = type.GetMethod("Add");
82      EnumerableCache cache = new EnumerableCache(instance, addMethod);
83      foreach (var tag in tags) {
84        tag.SafeSet(cache.GetNextSetter());
85      }
86      cache.Terminate();
87      return instance;
88    }
89
90  } 
91
92}
Note: See TracBrowser for help on using the repository browser.