powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как запретить наследование класса без sealed?
13 сообщений из 13, страница 1 из 1
Как запретить наследование класса без sealed?
    #39844778
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сабж.
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39844786
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВ, приватный конструктор?
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39844787
Супер_Пав
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВСабж.
а зачем?
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39844887
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
class Program
{
  public static void Main(string[] args)
  {
    foreach (var f in new Func<Foo>[]
    {
      () => new Foo(),
      Foo.CreateNew,
      () => new Bar(), 
      () => new Bar(123)
    })
      try
      {
        Console.WriteLine(f());
      }
      catch(Exception e)
      {
        Console.WriteLine("{0}: {1}", e.GetType(), e.Message);
      }
    Console.WriteLine("done");
    Console.ReadKey(true);
  }
}

class Foo
{
  public Foo()
  {
    var mi = new StackTrace().GetFrame(1).GetMethod();
    if (!mi.IsConstructor) return;
    var t = mi.DeclaringType;
    if (typeof(Foo)!=t &&  typeof(Foo).IsAssignableFrom(t))
      throw new ApplicationException("AARGH!!!111");
  }

  public static Foo CreateNew()=>new Foo();
}

class Bar : Foo
{
  public int N { get; }
  public Bar(int n) => N = n;
  public Bar(){ }
}
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39845316
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С приватным конструктором лучше)
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39845426
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВС приватным конструктором лучше)
А если можно сделать приватный конструктор, то почему нельзя сделать sealed?
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39845608
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВСабж.

sealed явно выражает намерение, это больше не про установку ограничения.
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39845714
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttЕвгенийВСабж.

sealed явно выражает намерение, это больше не про установку ограничения.
По идее должны быть еще оптимизации, типа call вместо call virt
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39845751
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВПо идее должны быть еще оптимизации, типа call вместо call virt
Почему должны? Отличие call от callvirt (для второго явно неудачно подобрали название) в том, что callvirt проверяет указатель экземпляра, на котором делается вызов, на null, а call не проверяет, а вовсе не в том, что callvirt для виртуальных методов - он сплошь и рядом вызывается и на невиртуальных. call вообще используется в единичных случаях. Я навскидку могу вспомнить только 2: 1) вызов статик-метода; 2) вызов метода непосредственно на результате конструктора (тпа new Foo().Bar()).
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39845783
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
3. вызов метода структуры, но в этом случае еще будет загрузка в стек самой структуры, ее this, даже если он нафик там не нужен.
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39845815
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВвызов метода структуры, но в этом случае еще будет загрузка в стек самой структуры

не, обычный ref
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39846512
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
не, обычный ref
Да, точно, в стек попадает только адрес.

Сон Веры Павловны,

еще если такой вызов ?.Method(.....
...
Рейтинг: 0 / 0
Как запретить наследование класса без sealed?
    #39846898
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВеще если такой вызов ?.Method(.....
Если Method не виртуальный, иначе всё тот же callvirt. В случае с вызовом непосредственно на результате конструктора, кстати, то же самое. Компилятор видит, что метод виртуальный, значит, даже если не нужна проверка указателя, то всё равно нужно взять фактический тип объекта, залезть в его wtable, итд - и использует callvirt. Даже если класс sealed.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
class Program
{
  public static void Main(string[] args)
  {
    new Foo().Bar();
    new Foo().Zot();
    var f = new Foo();
    f?.Bar();
    f?.Zot();
    new Zot().Bar();
    new Zot().Zot();
    var z = new Zot();
    z?.Bar();
    z?.Zot();
  }
}

class Foo
{
  public void Bar(){}
  public virtual void Zot(){}
}

sealed class Zot: Foo {}

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
.method public hidebysig static 
  void Main (
    string[] args
  ) cil managed 
{
  // Method begins at RVA 0x2050
  // Code size 96 (0x60)
  .maxstack 3
  .entrypoint

  IL_0000: newobj instance void test2.Foo::.ctor()
  IL_0005: call instance void test2.Foo::Bar()
  IL_000a: newobj instance void test2.Foo::.ctor()
  IL_000f: callvirt instance void test2.Foo::Zot()
  IL_0014: newobj instance void test2.Foo::.ctor()
  IL_0019: dup
  IL_001a: dup
  IL_001b: brtrue.s IL_0020

  IL_001d: pop
  IL_001e: br.s IL_0025

  IL_0020: call instance void test2.Foo::Bar()

  IL_0025: dup
  IL_0026: brtrue.s IL_002b

  IL_0028: pop
  IL_0029: br.s IL_0030

  IL_002b: callvirt instance void test2.Foo::Zot()

  IL_0030: newobj instance void test2.Zot::.ctor()
  IL_0035: call instance void test2.Foo::Bar()
  IL_003a: newobj instance void test2.Zot::.ctor()
  IL_003f: callvirt instance void test2.Foo::Zot()
  IL_0044: newobj instance void test2.Zot::.ctor()
  IL_0049: dup
  IL_004a: dup
  IL_004b: brtrue.s IL_0050

  IL_004d: pop
  IL_004e: br.s IL_0055

  IL_0050: call instance void test2.Foo::Bar()

  IL_0055: dup
  IL_0056: brtrue.s IL_005a

  IL_0058: pop
  IL_0059: ret

  IL_005a: callvirt instance void test2.Foo::Zot()
  IL_005f: ret
} // end of method Program::Main
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как запретить наследование класса без sealed?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]