答えて
実際には同じですが(インターフェイスパラメータを受け入れるメソッドでは、具体的なオブジェクトをインターフェイスタイプにアップキャストするという点を除いて)、わずかに異なるシナリオを検討してください。我々は、私たちの方法は、二つのインタフェースIMyInterface1
とIMyInterface2
を実装し、それ以外のコードはコンパイルべきではないことだけでクラスを受け入れるようにしたいとしましょう:
interface IMyInterface1 { }
interface IMyInterface2 { }
class MyClass : IMyInterface1 { }
public void Method1<T>(Class1 c, T obj) where T : IMyInterface1, IMyInterface2
{
}
我々はそれが二番目のパラメータだとしてインターフェイスを受け取るメソッドを作成した場合、それはので、条件を満たしていますこの例ではMyClassとIMyInterface2のように、ユーザーが1つのインターフェイスのみを実装するクラスインスタンスを送信することをユーザーが制限することはありませんが、2番目のインターフェイスは実装しません。
ユーザーはどのインターフェースを送信する必要がありますか?コンパイル時に送信する必要がある型は実際にはわかりません。
これは一般的な制約と一般的な制約を使用するのに適していますが、一方では単一のインタフェースパラメータを使用することはできません。
これは私が探している答えです – Rayet
void
メソッドに大きな違いはありません。
public void Method1<T>(class1 c, T obj) where T : Imyinterface
t
は
Imyinterface
でなければなりません
public void Method2(class1 c, Imyinterface obj, Type t)
に等しいです。
Type
をメソッドに渡す必要があり、コンパイル時にType
にいくつかの制約を適用する必要がある場合は、汎用メソッドを使用します。
ジェネリックメソッドを使用すると、あなたにわずかな署名の変更で様々な可能性を提供します:
public void Method1<T>(class1 c, T obj) where T:Imyinterface, new()
:
これは、タイプTの新しいインスタンスをインスタンス化することができます。public T Method1<T>(class1 c, T obj) where T:Imyinterface
:
これにより、必要に応じて戻り値をキャストせずにメソッドを使用できます。public void Method1<T>(class1 c, ref T obj) where T:Imyinterface
:
これにより、obj
の参照に新しい値を付けることができます。out
にも同じです。
これらは非汎用バージョンでは不可能です。
ジェネリック型のインスタンスをインスタンス化するには、制約リストに[new constraint](https://msdn.microsoft.com/en-us/library/sd2w2ew5.aspx)を追加する必要があります。そうでなければ、それはコンパイルされません –
@GianPaolo - 良い点、私は少しだけ私の答えを拡大しました。 – Amit
前述したように、voidメソッドでは、使用方法に大きな違いはありません。
舞台裏で見てみると、汎用メソッドでは、.NETはそれを呼び出すタイプごとに別々のメソッドをコンパイルすることがわかります。これは、構造体で呼び出されたときにボクシングを避ける効果があります。
戻り値の型を使用すると大きな違いが発生します。ジェネリックバージョンで
public T Method1<T>(class1 c, T obj) where T: IMyInterface
と
public IMyinterface Method2(class1 c, IMyInterface obj)
、あなたは元の型を取得するので、あなたは、元の型にプロパティやメソッド(インスタンスまたは拡張)を呼び出し続けることができます。
汎用でないバージョンでは、IMyInterface
の値が戻されるだけなので、IMyInterface
の一部であるプロパティまたはメソッドのみを呼び出すことができます。
私の本では、これは拡張メソッドと流暢なスタイルのAPIで使用すると最も興味深いです。
public static T Move<T>(this T animal) where T : ICanMove
{
return animal;
}
public static T Fly<T>(this T animal) where T : ICanFly
{
return animal;
}
public static T Pounce<T>(this T animal) where T : ICanPounce
{
return animal;
}
タイガーICanMoveとICanPounceを実装し、イーグルはICanMoveとICanFlyを実装していることを考えると、私は元の型に適用される上記の拡張メソッドを呼び出すことができます。 Intellisenseは、Eagleには.Fly()および.Move()、Tigerには.Pounce()および.Move()を表示します。ここで
var birdie = new Eagle();
birdie
.Move()
.Fly()
.Move()
.Fly();
var kitty = new Tiger();
kitty
.Move()
.Pounce()
.Move()
.Pounce();
あなたは非包括的に動かし実施された場合、それは次のようになります。
public static ICanMove Move<T>(this ICanMove animal)
{
return animal;
}
をICanMoveインタフェースが返されるので、コンパイラはそれが元々イーグルや虎だったという考えを持っていませんしたがって、ICanMoveインターフェイスの一部である拡張機能、メソッド、またはプロパティのみを使用できます。
- 1. Javaに関して<E> public static <E> void
- 2. Collections.sort()の宣言:</p> <pre><code>public static <T extends Comparable<? super T>> void sort(List<T> list) </code></pre> <p>及びません:<? super T>ではなく<T>
- 3. 私は2つの機能</p> <pre><code>void foo() { std::cout << 1 << std::endl; } void bar() { std::cout << 2 << std::endl; } </code></pre> <p>をお持ちの場合は2個の関数のC++
- 4. Cの<と<<の違いは何ですか?
- 5. Swift <<, ><, <=< and > = <
- 6. Heredoc <<<または<<?
- 7. スレッディングAndroidのは、今私は</p> <pre><code>public void someStuff(){ new Thread(new Runnable() { @Override public void run() { //doing long task doOtherStuff(); } }).start(); } public void doOtherStuff(){ doEvenMoreStuff(); } </code></pre> <p>をやってるUIスレッド
- 8. BaseType <any>はどのように指定できますか?</p> <pre><code>public class WrapperBase<T> where T : PocoBase </code></pre><p>といくつかの実装をその基底クラスの上に:
- 9. 関数の引数:それは不可能です</p> <pre><code>void foo(vector<Clazz*>& v) { ... v[0]->method(); ... } void foo(vector<Clazz>& v) { ... v[0].method(); ... } </code></pre> <p>/:ベクトル<Clazz*>&ベクトル<Clazz>&
- 10. はイムがページを取得</p> <pre><code>public void getHtml() throws IOException { String html = Jsoup.connect("http://vp.by/").get().html(); System.out.println(html); } </code></pre> <p>Jsoup
- 11. aspxの<%:と<%=と<%#の違いは何ですか?
- 12. Gitは<<<<<<< HEADをファイルに追加し続けます
- 13. C#ラムダ?</p> <p><code>public int ID;</code></p> <p><code>public MovingObject character;</code></p> <p>私は多分、行う必要があります。クラスのリストでプロパティ(文字)が1
- 14. cout << coutとcout <<とcoutの違いは何ですか?
- 15. ジェネリック制約は、我々は<code>T</code>で<em>共同バリアント</em>ある</p> <pre><code>public interface IEnumerable<out T> { /*...*/ } </code></pre> <p>ようなインターフェイスを持っているとしましょうコ分散
- 16. のstd ::機能とstd :: <code>std::packaged_task</code>が<code>void operator()(ArgTypes... args)</code>をオーバーロードしていますので、私は、<code>std::function<void()></code>の<code>std::vector</code>に<code>std::packaged_task</code>を移動しようとしていますpackaged_task変換
- 17. C#アクション<><>パラメータ
- 18. 違いは</p> <pre><code>BYTE* p; </code></pre> <p>と</p> <pre><code>BYTE^ p; </code></pre> <p>の違いは何ですかポインタ
- 19. リアクタマッピングモノ<Boolean>モノラル<Void>
- 20. ASP.NET MVCで "<%="、 "<%:" "<%#"の違いは何ですか?
- 21. このコードでは、私は</p> <pre><code>import "OAMutableURLRequest.h" import "OAConsumer.h" </code></pre> <p>そして印刷使用してい
- 22. コピーベクトル<shared_pt<T>>私はC++
- 23. "クラスA:B <C>"と "クラスA <T>:B <T>のT:C"の違いは何ですか?
- 24. なぜGoogle Closure Compilerはオブジェクトのプロパティ名の名前を変更しますか?</p> <pre><code>var obj = JSON.parse(some_data); </code></pre> <p>をそして、<code>obj</code>プロパティ<code>x</code>持っていることが想定されています:
- 25. in C、*、=、++、<< |オペレータ
- 26. connection.Close()とconnection.Dispose()の違いは何ですか? <code>SQLiteDataReader</code>オブジェクトの</p> <ul> <li><code>Close()</code></li> <li><code>Dispose()</code></li> </ul> <p>同じ:
- 27. 「<%:」は何をしますか?</p> <pre><code><%: Model.FirstName %> </code></pre> <p>「<%:」何をん:行う
- 28. std :: operator <<とstd :: ostream :: operator <<
- 29. <<<
- 30. Tortoise svn <<<<をファイルに追加しています!
私はこの場合、同じ機能を持っていると言います。 – Jonesopolis
1つの違いは、汎用メソッドで回避される2番目のバージョンを呼び出すときに構造体が囲まれることです。 – Lee
@Lee [this](http://stackoverflow.com/questions/63671/is-it-safe-for-structs-to-implement-interfaces)を参照してください。通常、構造体にインターフェースを継承するのは避けてください。 – Amit