Ковариантность и контравариантность являются качествами класса , а не качествами параметров . (Это качества, которые зависят от параметров, но они делают утверждения о классе.)
Итак, Function1[-A,+B]
означает, что можно просмотреть функцию , которая принимает суперклассы из A
в качестве подкласса исходная функция .
Давайте посмотрим это на практике:
class A
class B extends A
val printB: B => Unit = { b => println("Blah blah") }
val printA: A => Unit = { a => println("Blah blah blah") }
Теперь предположим, что вам требуется функция, которая знает, как напечатать B
:
def needsB(f: B => Unit, b: B) = f(b)
Вы можете передать в printB
, Но вы также можете передать в printA
, поскольку он также знает, как печатать B
с (и больше!), Как если бы A => Unit
был подклассом B => Unit
. Это именно то, что означает контрвариантность. Это не значит, что вы можете передать Option[Double]
в printB
и получить что-либо, кроме ошибки времени компиляции!
(Covariance - другой случай: M[B] <: M[A]
if B <: A
.)
from entry in A
where B
переводится (буквально) в:
A.Where(entry=>B)
, а:
select C
переводится напрямую в (с «входом» в качестве нашего контекста):
.Select(entry=>C)
(за исключением случаев, когда это будет entry => entry
, которую компилятор опускает для нетривиальных случаев)
, поэтому просто введите их, и все готово:
var logQuery = xDoc.Descendants("logentry")
.Where(entry=>
entry.Element("author").Value.ToLower().Contains(matchText) ||
entry.Element("msg").Value.ToLower().Contains(matchText) ||
entry.Element("paths").Value.ToLower().Contains(matchText) ||
entry.Element("revision").Value.ToLower().Contains(matchText))
.Select(entry=>new
{
Revision = entry.Attribute("revision").Value,
Author = entry.Element("author").Value,
CR = LogFormatter.FormatCR(entry.Element("msg").Value),
Date = LogFormatter.FormatDate(entry.Element("date").Value),
Message = LogFormatter.FormatComment(entry.Element("msg").Value),
ET = LogFormatter.FormatET(entry.Element("msg").Value),
MergeFrom = LogFormatter.FormatMergeFrom(entry.Element("msg").Value),
MergeTo = LogFormatter.FormatMergeTo(entry.Element("msg").Value)
});