Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как запретить наследование класса без sealed? / 13 сообщений из 13, страница 1 из 1
02.08.2019, 18:02
    #39844778
ЕвгенийВ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как запретить наследование класса без sealed?
Сабж.
...
Рейтинг: 0 / 0
02.08.2019, 18:14
    #39844786
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как запретить наследование класса без sealed?
ЕвгенийВ, приватный конструктор?
...
Рейтинг: 0 / 0
02.08.2019, 18:14
    #39844787
Супер_Пав
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как запретить наследование класса без sealed?
ЕвгенийВСабж.
а зачем?
...
Рейтинг: 0 / 0
03.08.2019, 04:34
    #39844887
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как запретить наследование класса без 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.
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
05.08.2019, 11:12
    #39845316
ЕвгенийВ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как запретить наследование класса без sealed?
С приватным конструктором лучше)
...
Рейтинг: 0 / 0
05.08.2019, 15:22
    #39845426
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как запретить наследование класса без sealed?
ЕвгенийВС приватным конструктором лучше)
А если можно сделать приватный конструктор, то почему нельзя сделать sealed?
...
Рейтинг: 0 / 0
05.08.2019, 22:19
    #39845608
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как запретить наследование класса без sealed?
ЕвгенийВСабж.

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

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

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

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

еще если такой вызов ?.Method(.....
...
Рейтинг: 0 / 0
08.08.2019, 12:09
    #39846898
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как запретить наследование класса без sealed?
ЕвгенийВеще если такой вызов ?.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
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как запретить наследование класса без sealed? / 13 сообщений из 13, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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