Другие дали точные и подробные ответы, но здесь я попытаюсь объяснить простым языком.
Когда вы пишете worksheet["A2"]
, вы действительно вызываете функцию-член worksheet
worksheet
имеет функцию-член с именем []
, которая принимает string
и возвращает object
Сигнатура функции-члена []
выглядит как object this[string id]
Итак, функция worksheet["A2"]
возвращает что-то, что является object
. Это может быть int
или string
или многое другое. Все, что знает компилятор, это то, что это будет object
.
В этом примере он возвращает Func<object>
. Это нормально, потому что Func<object>
- это object
. Однако затем вы передаете результат этой функции в качестве параметра другой функции.
Проблема здесь в том, что компилятор знает только, что worksheet["A2"]
возвращает object
. Это так же конкретно, как может быть компилятор.
Таким образом, компилятор видит, что worksheet["A2"]
является объектом, и вы пытаетесь передать объект в функцию, которая не принимает object
в качестве параметра.
Итак, здесь вы должны сказать компилятору "эй, дурак, это Func<object>
", приведя возвращаемый объект к правильному типу.
worksheet.Add("C3", CellFactories.DoAdd(worksheet["A2"], worksheet["B1"]));
можно переписать как
worksheet.Add("C3", CellFactories.DoAdd((Func<object>)worksheet["A2"], (Func<object>)worksheet["B1"]));
Теперь компилятор знает, что, хотя функция []
возвращает object
, она может обрабатывать его как Func<object>
.
примечание: Вы, вероятно, делаете слишком много в одной строке. Это может быть трудно для людей, чтобы читать в будущем.
Почему вызываемый метод «видит» аргумент как тип, отличный от того, который возвращает GetType ()?
Компилятор знает только, что worksheet[]
возвращает объект. Компилятор не может вызвать GetType()
на нем во время компиляции.
Что хорошего в методе GetType ()?
Существует довольно много случаев использования и злоупотребления методом GetType()
, но это совершенно другое обсуждение. ;)
Таким образом, компилятор не предполагает ничего о типах. Это хорошая вещь , потому что вы получаете ошибку времени компиляции, когда пытаетесь вставить этот квадратный колышек в круглое отверстие. Если компилятор не жаловался, эта ошибка возникнет во время выполнения, что означает, что вам, вероятно, потребуется модульный тест для обнаружения проблемы.
Вы можете обойти эту проблему, сказав компилятору: «Я точно знаю, что эта вещь является круглым колышком, поверьте мне». и тогда он скомпилируется.
Если вы врете компилятору, вы получите ошибку во время выполнения при выполнении этого кода.
Это называется "статическая типизация". Противоположная философия называется «динамическая типизация», когда проверки типов выполняются во время выполнения. Static vs dynamic - это длительная дискуссия, и вам, вероятно, стоит изучить ее самостоятельно, если вам интересно.