2011-01-29 3 views
1

Если у кого-то есть лучший заголовок, дайте мне знать.метод Параметр интерфейса в качестве эталонных задач

Я сделал DisposeHelper так вместо этого:

private Something _thing; 

void Dispose() 
{ 
    if(_thing != null) 
    { 
     _thing.Dispose(); 
     _thing = null; 
    } 
} 

... я мог бы сделать это:

private Something _thing; 

void Dispose() 
{ 
    DiposeHelper.Dipose(ref _thing); 
} 

Но, видимо, я не могу кормить DisposeHelper.Dispose в IDisposable в качестве ссылки , если я не отбрасываю что-то как IDisposable, так как:

private Something _thing; 

void Dispose() 
{ 
    IDisposable d = _thing; 
    DiposeHelper.Dipose(ref d); 
} 

... что означало бы это не то NUL lify исходное поле.

Вот более абстрактный пример. DoThis работает, DoThis:

public class Test 
{ 
    public Test() 
    { 
     Something o = new Something(); 

     DoThis(o); 

     DoThat(ref o); 
    } 

    private void DoThis(IFoo obj) { } 

    private void DoThat(ref IFoo obj) { } 
} 

public class Something : IFoo { } 

public interface IFoo { } 

Почему я не могу это сделать?

ответ

2

Я не знаю технической причины, почему вы не можете.

Это работает, однако:

var o = new Something(); 
DoThat(ref o); 

private void DoThat<T>(ref T obj) where T : class, IFoo { 
    obj = null; 
} 
2

Это не работает, потому что типы параметров для ref и out выражений должны точно совпадать. Представьте себе, если DoThat на самом деле была эта реализация:

private void DoThat(ref IFoo obj) 
{ 
    obj = new SomeOtherImplementationOfFoo(); 
} 

Сейчас этот код:

Something o = new Something(); 
DoThat(ref o); 

бы в конечном итоге с o ссылкой на экземпляр SomeOtherImplementationOfFoo вместо Something - которые явно не могут быть правы.

Так вот почему ref работает так, как он делает - и ответ Роба дает возможность обойти его.

0

Это не работает, потому что тип должен быть точного типа свойства.

Представьте, что вы можете передать Derived как Base в функцию по ссылке. Теперь функция присваивает параметру новый объект, который является Base, но не Derived. Booom

Обход использует общий параметр, как в ответе Роба.

public static void DisposeAndNull<T>(ref T x) 
    where T:IDisposable 
{ 
    x.Dispose(); 
    x=null; 
} 
Смежные вопросы