Тип объекта аналогичен типу в унаследованном классе [duplicate]

Для достижения этого поведения вы должны использовать globals() встроенный метод :

def var_of_var(k, v):
    globals()[k] = v

print variable_name # NameError: name 'variable_name' is not defined
some_name = 'variable_name'
globals()[some_name] = 123
print variable_name # 123

some_name = 'variable_name2'
var_of_var(some_name, 456)
print variable_name2 # 456

2
задан P Daddy 17 June 2009 в 16:19
поделиться

3 ответа

Другие дали точные и подробные ответы, но здесь я попытаюсь объяснить простым языком.

Когда вы пишете worksheet["A2"], вы действительно вызываете функцию-член worksheet

worksheet имеет функцию-член с именем [], которая принимает string и возвращает object

. Подпись функции-члена [] выглядит как object this[string id]

Таким образом, функция worksheet["A2"] возвращает то, что является object. Это может быть int или string или многое другое. Все компиляторы знают, что это будет object.

В этом примере вы возвращаете Func<object>. Это прекрасно, потому что Func<object> - a object. Тем не менее, вы затем передаете результат этой функции в качестве параметра в другую функцию.

Проблема заключается в том, что компилятор знает, что worksheet["A2"] возвращает object. Это так же специфично, как и компилятор. Таким образом, компилятор видит, что worksheet["A2"] является объектом, и вы пытаетесь передать объект функции, которая не принимает object в качестве параметра.

Итак, здесь вы должны сообщить компилятору " hey dummy, это 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 - длительная дискуссия, и вам, вероятно, следует исследовать ее самостоятельно, если вам интересно.

2
ответ дан dss539 22 August 2018 в 17:52
поделиться

Вам нужно понять разницу между динамической типизацией и статической типизацией . У индексатора для вашего объекта worksheet, скорее всего, есть статический тип object.

public object this[string cell]{get{...}set{...}}

Поскольку все объекты в C # наследуют от типа object, объект ссылка, хранящаяся в ячейке, может быть ссылкой на любой объект .

То есть, поскольку делегат (например, Func<T>) является object, он может быть сохранен в object ссылке:

Func<object> func = ()=>return "foo";
object o = func; // this compiles fine

И компилятор может понять все это, потому что он неявно понимает, что производный класс может быть сохранен в ссылке на базовый класс.

То, что компилятор не может сделать автоматически, определяет тип динамического типа или тип времени выполнения объекта.

Func<object> func = ()=>return "foo";
object o = func; // this compiles fine
func = o; // <-- ERROR

Компилятор не знает, что object, хранящийся в o, действительно имеет тип Func<object>. Это не должно отслеживать это. Это информация, которая должна быть проверена во время выполнения.

func = (Func<object>)o; // ok!

Вышеприведенная строка кода компилируется во что-то, что ведет себя аналогично этому:

if(o == null)
    func = null;
else if(typeof(Func<object>).IsAssignableFrom(func.GetType()))
    __copy_reference_address__(func, o); // made up function!  demonstration only
else throw new InvalidCastException();

Таким образом, любой cast (преобразование из одного типа в другое) можно проверить во время выполнения, чтобы убедиться, что оно действительно и безопасно.

3
ответ дан P Daddy 22 August 2018 в 17:52
поделиться
  • 1
    +1 Совершенно верно, но, возможно, слишком сложно объяснить кому-то новое для C # и / или программирования. – dss539 17 June 2009 в 17:54

VS утверждает, что оба аргумента в вызове метода выше имеют объект типа, тогда как метод принимает только Func. Но значение обоих элементов рабочего листа имеет тип Func

Да, но объявленный тип - object. Компилятор не может знать, что фактический тип выполнения будет Func<object>, поэтому необходим явный приведение.

1
ответ дан Thomas Levesque 22 August 2018 в 17:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: