C#コンパイラは、クエリ式の構文からモナドの関連する演算子メソッドへの呼び出しに変換するとき、モナドがいくつかのインターフェイスを実装していることを本当に気にせず、必要としないことを思い出してください。LINQが提供するコンポジションにモナドが参加するための最小限の要件は何ですか?
拡張子または実際のインスタンスメソッドである演算子メソッドについては気にしません。
しかし、詳細は全く思い出せません。 シーケンス自体の最低要件があるようですが、これは下のクエリでnew Foo<string>()
の式になります。
インターフェイスに必ずしも従う必要はありませんが、GetEnumerator
という名前のメソッドを持つ必要があったか、IEnumerator<T>
メソッドを実装する必要がありました。しかし、私は下の例のクエリがFoo<T>
クラスにGetEnumerator
メソッドがあるかどうかに関係なく動作するので間違っている可能性があります。
しかし、where
というクエリ式を導入すると、受信者の種類が解決されません。
Select
式はうまくいきます。
私は18ヵ月前までこれを知っていましたが、これは簡単なLINQプロバイダを実装した時です。私はそれ以来ずっとそれを忘れてしまった。
このすべての機能が動作するための最小限の要件をリストしてください。
using System;
namespace CompilerDoesNotCareAboutTypeLINQQuerySyntax
{
class Program
{
static void Main(string[] args)
{
// What are the minimum requirements on Foo<T>()?
// How does it resolve this expression new Foo<string>
// such that it knows that Foo<string> has many Bar<string>
// or whatever foo in the query below might resolve to?
var query = from foo in new Foo<string>()
/* where foo. // when I do foo., only the system.object inherited properties of Foo show up */
select foo;
}
}
public class Foo<T>
{
public string Name { get; set; }
public Foo<T> Where<T>(Func<T, bool> predicate)
{
return new Foo<T>();
}
/*IEnumerator<Foo<T>> GetEnumerator()
{
return new List<Foo<T>>().GetEnumerator();
}*/
}
public static class Extensions
{
public static Foo<R> Select<T, R>(this Foo<T> foo, Func<T, R> transformer)
{
return new Foo<R>();
}
}
}
更新
ここServyが指摘し修正を実施した後Where
メソッド宣言の更新です。
system.object
に解決上記のクエリ式クエリ内のどの
foo
に起因するバグを修正し
class Foo<T>
{
public Foo<T> Where(Func<T, bool> predicate)
{
return new Foo<T>();
}
}
。しかし、今度はstring
に解決されます。これは、推論によってWhere
メソッドのジェネリック型パラメータ型です。
Servyが指摘し、今では、宣言する型Foo<T>
のジェネリック型パラメータである、T
に解決として、私はジェネリック型パラメータT
をオーバーロードしていたので、それ以前object
に解決。
まだ質問が残っています: シーケンス式new Foo<string>()
の最小必要条件は何ですか?何もないように見える?次に、シーケンスの場所に置かれる式の値と範囲変数foo
の型の間の相関関係は何ですか? new Foo<T>
が多くのfooを返し、クエリfrom foo in new Foo<T>()...
のfoo
がFoo<T>
に解決された場合、何をする必要がありますか?
ありがとうございます。私の悪い。それで、何にも合致するための何かの必要性は絶対にありません。 –
あなたが強調表示した問題を修正した後、 'where foo.'を実行すると' foo'が 'string'に評価されるのはなぜですか? –
@ WaterCoolerv2型の汎用引数は 'string'であり、同じ汎用引数はメソッドのパラメータであるため、文字列でなければなりません。 – Servy