1
public abstract class FieldObjects<T> : ConcurrentDictionary<int, T> where T : FieldObject
{
    public Field Field { get; private set; }

    public FieldObjects(Field field)
        : base()
    {
        this.Field = field;
    }

    public virtual void Add(T value)
    {
        value.Field = this.Field;
        value.ObjectId = this.Field.AssignObjectId();

        this.AddOrUpdate(value.ObjectId, value, null);
    }

    public virtual void Remove(T value)
    {
        value.Field = null;
        value.ObjectId = -1;

        this.TryRemove(value.ObjectId, out value);
    }

    public IEnumerable<T> GetInRange(FieldObject reference, int range)
    {
        foreach (T fieldObject in this.Values)
        {
            if (reference.Position.DistanceFrom(fieldObject.Position) <= range)
            {
                yield return fieldObject;
            }
        }
    }
}

I have this abstract class. I want to be able to iterate over it's values (not a KeyValuePair, but values only) in a safe way so I don't have to use the lock statement every-time. How can I do that?

Frza
  • 25
  • 4
user3865229
  • 125
  • 2
  • 9
  • 6
    what about using ConcurrentDictionary ? Or other thread safe collections: http://msdn.microsoft.com/en-us/library/dd997305(v=vs.110).aspx – Robert Aug 15 '14 at 08:38
  • It might be better to ensure thread-safety in the class that uses the collection, not in the collection itself. – Dirk Aug 15 '14 at 08:39
  • 1
    It is safe unless someone use `Dictionary.Add` ,`Dictionary.Remove`, etc methods directly. I'll suggest not to inherit from `Dictionary` just wrap it, 2) Avoid `lock(this)` use private readonly field instead. Or better use `ConcurrentDictionary`. – Sriram Sakthivel Aug 15 '14 at 08:40
  • @Robert So, if I use a ConcurrentDictionary, I don't have to use the lock statement if I add, remove and iterate over values? – user3865229 Aug 15 '14 at 08:40
  • @Robert That might not be possible since the class doesn't use a dictionary, it inherits from it. – Dirk Aug 15 '14 at 08:41
  • @Dirk then perhaps decorating the ConcurrentDictionary would be an option – Robert Aug 15 '14 at 08:42
  • @Dirk Which begs the question: should you really be inheriting from a dictionary? Domain objects should not derive from collections. Favor composition over inheritance. See: ["Why not inherit from `List`?"](http://stackoverflow.com/a/21694054/857807) – dcastro Aug 15 '14 at 08:43
  • I've switched to a ConcurrentDictionary. Is it okay now? I want to be able to safely remove, add and iterate over values without the need of the lock statement. – user3865229 Aug 15 '14 at 08:43
  • @dcastro Yes, I wouldn't do that either. But you shouldn't ask me that question. – Dirk Aug 15 '14 at 08:43
  • 2
    @Dirk I wasn't asking you, I was just extending your comment, and asking the OP a question :) – dcastro Aug 15 '14 at 08:44
  • @user3865229 Do not use a ConcurrentDictionary just for avoiding a few lock statements. Lock-free collections have some advantages scenarios with a high level of concurrency but if you look at the documentation of it you'll see that you have to pay a price for that. – Dirk Aug 15 '14 at 08:47
  • Maybe rewriting the loop with yield return to linq expression could help ? – IL_Agent Aug 15 '14 at 08:49

0 Answers0