C # Как сделать универсальный класс? - PullRequest
3 голосов
/ 02 декабря 2009

Как я могу сделать этот универсальный?

class AtomicReference
{
    private Object _value;

    public AtomicReference()
    {
        _value = new Object();
    }

    public AtomicReference(Object value)
    {
        OptimisticSet(value);
    }

    public Object CompareAndSet(Object newValue)
    {
        return Interlocked.Exchange(ref _value, newValue);
    }

    public void OptimisticSet(Object newValue)
    {
        do { 
        } while (_value == Interlocked.CompareExchange(ref _value, _value, newValue));
    }

    public Object Get()
    {
        return _value;
    }
}

Моя неудачная попытка:

class AtomicReference<T>
{
    private T _value;

    public AtomicReference()
    {
    }

    public AtomicReference(T value)
    {
        Set(value);
    }

    public T CompareAndSet(T newValue)
    {
        // _value is not an object that can be referenced
        return  Interlocked.Exchange(ref _value, newValue); 
    }

    public void OptimisticSet(T newValue)
    {
        // I can't use the operator== with type T
        do{}while(_value == CompareAndSet(newValue));
    }

    public T Get()
    {
        return _value;
    }
}

Ответы [ 2 ]

11 голосов
/ 02 декабря 2009

Вам необходимо ограничить T, чтобы быть ссылочным типом, например:

class AtomicReference<T> where T : class {
    private T _value;

    public AtomicReference() { }

    public AtomicReference(T value) {
        OptimisticSet(value);
    }

    public T CompareAndSet(T newValue) {
        return Interlocked.Exchange(ref _value, newValue); 
    }

    public void OptimisticSet(T newValue) {
        while (_value == CompareAndSet(newValue));
    }

    public T Get() {
        return _value;
    }
}

РЕДАКТИРОВАТЬ : Я бы порекомендовал также заменить методы свойством:

public T Value {
    get { return _value; }
    set { while(_value == CompareAndSet(value)); }
}
0 голосов
/ 02 декабря 2009

У меня нет VS 2005, установленного дома, чтобы помочь отладить ваше решение, но я думаю, что вам нужно ограничить T. Вот несколько полезных ресурсов:

Generics C #

Общие объяснения (.NET Framework версия 2.0)

...