2011-01-29 10 views
1

誰かがより良いタイトルを持っている場合は、私に教えてください。メソッド参照パラメータとしてのインタフェースパラメータ

私はこれに代えてDisposeHelperを作った:

private Something _thing; 

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

...私はこれを行うことができます:

private Something _thing; 

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

をしかし、どうやら私が参考にIDisposableをしDisposeHelper.Dispose養うことができません私はIDisposableとして何かをキャストしない限り、そうする:

private Something _thing; 

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

...これは、元のフィールドを照らし合わせる。

ここでは、より抽象的な例を示します。 DoThisは動作しますが、DoThatはそうではありません:

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

refout式のパラメータの型が正確に一致する必要があるため、それが動作しません。 DoThatが実際にこの実装を持っていた場合を想像:

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

を今、このコードを:

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

SomeOtherImplementationOfFoo代わりのSomethingのインスタンスを参照oで終わるだろう - 明確右することはできません。

だから、refはそれがやっているように動作します。そして、Robの答えはそれを処理する方法を与えます。

0

タイプはプロパティの正確なタイプでなければならないため、機能しません。

DerivedBaseとして関数に渡すことができます。この関数はパラメータをBaseですが、Derivedではなく新しいオブジェクトに割り当てます。 Booom

private Derived d; 

void Modify(ref Base b) 
{ 
    b=new Base(); 
} 

Modify(ref d);//Booom 

回避策は、Robの回答のように汎用パラメータを使用しています。

public static void DisposeAndNull<T>(ref T x) 
    where T:IDisposable 
{ 
    x.Dispose(); 
    x=null; 
} 
関連する問題