私は中の以下の使用方法を見ました:パラメータリストの修飾語の意味は?
Covariance and contravariance real world example
interface IGobbler<in T> {
void gobble(T t);
}
私はでの使用量が何の略かわかりません。 との関係がありますか?、、 ??
私は中の以下の使用方法を見ました:パラメータリストの修飾語の意味は?
Covariance and contravariance real world example
interface IGobbler<in T> {
void gobble(T t);
}
私はでの使用量が何の略かわかりません。 との関係がありますか?、、 ??
あなたが知っていることは、ref
とout
は無視されています。この場合、in
は、T
が機能名の右側にのみ表示されることを意味します(つまり、void gobble(T t)
のような仮パラメータリスト)。それがout
と記載されている場合、T
は関数名の左側に表示されます(つまり、戻り値はT foo(int x)
など)。デフォルト(何も指定しない)では、いずれの場所にもT
が表示されます。
4.0内の修飾子は、共分散と反動を強制する(またはむしろ有効にする)必要があります:in
とout
あなたがin
を追加する場合は、あなただけ内側(反変)の位置にT
を使用することを許可されている - これが外側(共変)の位置であるとしてAdd(T obj)
のようなもので結構ですので、しかしT this[int index] {get;}
はではありません。
これは、4.0の分散機能に不可欠です。差異がある場合、ref
とout
はどちらも使用できません(両方とも、そうでない場合はどちらでもありません)。 C#4.0では
インとアウトの説明は分かりやすいです。しかし、私はまだTとインターフェイスIGobbler
@ q0987いいえ、それは間違っています。デリゲート***またはインターフェイス***。最も顕著なのは 'IEnumerable ' –
です。' IGobbler
、Contravarianceは、Yは、このたIComparer を達成するためにXの派生 タイプがで修飾子でマークされなければならない場合でもたIComparer
<X>
は たIComparer<Y>
にキャストするために、 たとえばことができます。
public interface IComparer<in T> {
public int Compare(T left, T right);
}
てきたが、例示及び説明のためにここを見て:
http://www.csharphelp.com/2010/02/c-4-0-covariance-and-contravariance-of-generics/
をin
修飾子はタイプが反変であると暗黙的に狭い型に変換可能であることを示します。下の例では、ゴブリングがShape
であっても、それはcontravariantと宣言しているので、Action<Rectangle>
に割り当てることができます。これは、デリゲートを呼び出してそれをRectangleに渡す人は、明らかにRectangleをShapeをとるメソッドに渡すことができるからです。
in
とout
を使用する場合にはいくつかのルールがありますが、それは一言で言えば有効です。例えば
:
public class Shape { }
public class Rectangle : Shape { }
public interface IGobbler<Shape>
{
void gobble(Shape shape);
}
public class Gobbler : IGobbler<Shape>
{
public void gobble(Shape r) { }
}
public static class Program
{
public static void Main()
{
var g = new Gobbler();
// notice can implictly convert to a narrower type because of the 'in' keyword
Action<Rectangle> r = g.gobble;
}
}
INキーワード我々は唯一の入力値としてTを使用するコンパイラに指示します。
これらは、ほとんどの開発者にとって馴染みのメタファーあるように私は、消費と生産と考えるのが好きIGobbler
にIGobbler、と言うからキャストできません。飲み込んできゴブラー(消費する)任意の動物はまた、牛を飲み込んできるのでIGobbler<Cow>
を取る方法はまた、IGobbler<Animal>
を受け入れることができます。ここのゴブラーは、特定の種類の動物の消費者であるため、in
タグを使用します。
上記の場合(反差異)は反直感的なように見えるかもしれませんが、を望むRestaurantOwnerの観点から考えてください。もしゴブラーが豚だけを寝かし、レストランオウナーが牛に餌を与えようとするなら、それはうまくいかないでしょう。彼はあまり好きではないゴブラーだけを受け入れることができるので、Gobbler<Animal>
またはGobbler<Herbivore>
が問題ありません。一方
、動物を販売しているあなたはFarmer<Animal>
があると(IEnumerable<Animal>
を返すファームメソッドを持つ。)あなたはBuy(IEnumerable<Animal>)
したい購入者を持っている場合は、購入者が購入する意思があるとして、それは、Farmer<Cow>.Farm()
を受け入れることができます生産された動物や牛はいずれも動物です。ここのFarmerは、特定のタイプのAnimalのプロデューサであるため、 `out 'タグを使用します。
内と外はrefとアウトとは何の関係もありません。
ザキーワードにあなたが筈、
はあなたがロバを供給することができるゴブラーを作成ラインを連結例でTのインスタンスを消費するインタフェースのインスタンスでそれを記述するために使用されますドンキーは四倍体ではありませんが、それから派生しています。したがって、引数として基本クラスの代わりにより特殊化されたインスタンスを使用することができます。
outキーワードは、それをcomsumingのではなく、ものを作り出す事を記述するために使われている以外、ほとんど同じように動作します。同じ例で
、ライン
ISpewer<Rodent> rs = new MouseSpewer();
が呼び出されたときに、マウスを吐き出すISpewerを作成します。マウスはげっ歯類ではありませんが、それから派生しているので、インターフェースが宣言しているものよりも特殊化されたインスタンスを生成する生成クラスを使用することができます。ほとんどの専門のクラスが2つの場合にスワップされる仕方
注意してください。 inキーワードを使用する場合は、インタフェースの汎用引数として特殊クラスを使用しますが、特殊クラスを作成してもコンパイラに通知するためには、基本クラスを汎用引数として使用します。それを基本クラスのように扱います。
このステートメントの仕組みは? IGobbler
QuadrupedGobblerは一般的なIGobblerインタフェースを実装しています。このインタフェースのシグネチャは、このpublic interface IGobbler ...のように見えますが、IGobblerはIGobblerを実装しているためQuadrupedGobblerを含むことができます。 多型を理解していれば、それほど異質ではない概念です。 –
あなたは検索しましたか?検索エンジンが 'in'という単語を取らない場合、' in'の代わりに '+ in'を使う必要があります。 – BoltClock
refは、この文脈で – Jodrell
@BoltClockを適用していないだろう、私は使ってグーグルを検索でした「C#パラメータを中出しrefを」または「パラメータのC#」と有用な情報が返されませんでした。 – q0987