Хорошо, например есть набор классов A1 A2 А3 и т.д. порожденные от А.
у них общий набор типовых характеристик например
static Name, Type, Width, Height, у каждого класса свои значения. И возможно они зависит от расчета в родителе.
Эти данные используются как без объектов, так и внутри объектов.
Как удобней писать? в месте каждого вызова A1.Width() или просто Width()? И сколько будет ошибок при copy/paste.
А если бы у этих статик функций было наследование, то можно было бы общую часть их обработки вообще отдать родителю:
Например классу А реализовать функцию
static int Perimetr() {return (Width() + Height())*2;}
Которая нормально работала бы для все наследников.
Скорее всего у вас нет специфических знаний по вызовам виртуальных функций в рантайме.
Поэтому давайте решим так, если бы вы реализовывали вызовы виртуальных функций вы бы не смогли сделать вызов функций у null объектов.
:) Вызов любой функции может дать NullReferenceException.
А самое забавное, что вызов статической функции НИКАК не может вызвать NullReferenceException.
>И вообще тогда какие отличия от экземплярных методов, кроме потери доступа к this в теле метода?
В том что их можно вызвать и без наличия экземпляра класса.
Ну а я за предоставление максимальных возможностей. Только не надо писать про выстрелы в ногу, это не тот случай.
>yourObject -> getType -> someMethod
Именно! Но зачем «getType ->» если его нужно писать всегда? Можно и пропустить двузначностей это не принесет.
Тем более «нормального» getType к сожалению нет :( и вроде делать его не собираются.
Или вас возмущает, что вызов функций у объекта и через ссылку на объект идет через "."?
>Нет. Слишком много возможностей нарушает целостность.
Я так понимаю вы поклонник асемблера и противник библиотек и объектного программирования?
> Если они не нуждаются для расчетов в объекте — это не функции этого объекта.
Конечно — это функция класса. Но для того, что бы она вызвалась у объекта именно того класса которым он является, ее нужно вызывать непосредственно у этого экземпляра класса. Пояснить примером?
Как минимум, наличие возможности лучшее ее отсутствия. Тем более возможности которая никак не изменяет ни синтаксис, не идеологию.
А так это дает более объектно ориентированный доступ к параметрам и функциям которые меняются при наследовании, но не нуждаются для расчетов в самом объекте.
Это хорошо проявляется в задачах типа фабрика объектов.
Понял, почему народ так удивлялся — C# просто не позволяет вызвать через экземпляра класса статическую функцию этого класса.
Тогда естественно виртуальность статик функции теряет смысл.
Так что появилось еще одно пожелание:
Возможность вызова статик функции через экземпляра класса.
у них общий набор типовых характеристик например
static Name, Type, Width, Height, у каждого класса свои значения. И возможно они зависит от расчета в родителе.
Эти данные используются как без объектов, так и внутри объектов.
Как удобней писать? в месте каждого вызова A1.Width() или просто Width()?
И сколько будет ошибок при copy/paste.
А если бы у этих статик функций было наследование, то можно было бы общую часть их обработки вообще отдать родителю:
Например классу А реализовать функцию
static int Perimetr() {return (Width() + Height())*2;}
Которая нормально работала бы для все наследников.
Поэтому давайте решим так, если бы вы реализовывали вызовы виртуальных функций вы бы не смогли сделать вызов функций у null объектов.
B.info() или есть сомнения?
>Если он null, все плохо
Все хорошо — тип объекта то есть. Вот по типу и вызовет.
Конечно класса А.
А если (B(null)).info(); то от B; Что вас смущает?
>Но о виртуальных статических методах можно забыть из-за возможного null.
Откуда null, в статик функции? Даже у виртуальной.
Но для того что бы использовать Type для вызова функций нужен Reflection.
А самое забавное, что вызов статической функции НИКАК не может вызвать NullReferenceException.
>И вообще тогда какие отличия от экземплярных методов, кроме потери доступа к this в теле метода?
В том что их можно вызвать и без наличия экземпляра класса.
:) Расскажите мистер паладин, чем именно ужасен вызов статика из объекта?
Что функция вернет то и будет. Я имел в виду неоднозначностей для компилятора.
>Так вот лучше сделать нормальный getType
Это бесспорно «нормальный getType» без рефлектинга по мне тоже куда важнее. Хотя и проблем вызовом статиков я не вижу.
Похоже я больше склонен к универсальности и общему синтаксису, а вы за строгость и явные разграничения.
>yourObject -> getType -> someMethod
Именно! Но зачем «getType ->» если его нужно писать всегда? Можно и пропустить двузначностей это не принесет.
Тем более «нормального» getType к сожалению нет :( и вроде делать его не собираются.
Или вас возмущает, что вызов функций у объекта и через ссылку на объект идет через "."?
Тогда да, тогда я понимаю вашу принципиальность.
Я так понимаю вы поклонник асемблера и противник библиотек и объектного программирования?
> Если они не нуждаются для расчетов в объекте — это не функции этого объекта.
Конечно — это функция класса. Но для того, что бы она вызвалась у объекта именно того класса которым он является, ее нужно вызывать непосредственно у этого экземпляра класса. Пояснить примером?
А так это дает более объектно ориентированный доступ к параметрам и функциям которые меняются при наследовании, но не нуждаются для расчетов в самом объекте.
Это хорошо проявляется в задачах типа фабрика объектов.
В прочем я нашел способ решить эту проблему с помощью reflection, но решение мне не нравится.
Хочется возможностей самого языка, тем более, что новый синтаксис для этого не нужен.
А явных проблем, почему это нельзя сделать, лично я не вижу.
Почему же?
Для A a; одинаково должно вызываться и
A.info();
и
a.info();
class A {
public static string info() {return «a»;}
}
A a = new A();
string s = a.info(); < — тут баг
Тогда естественно виртуальность статик функции теряет смысл.
Так что появилось еще одно пожелание:
Возможность вызова статик функции через экземпляра класса.
Для статической функции объект совсем не обязателен, вполне хватит и самого класса.
Похоже, что действительно возникло недопонимание в определении, что такое virtual static, даю пример
class A
{
public virtual static string info() {return «a»;}
}
class A2:A
{
public virtual static string info() {return «a2»;}
}