'Более свободный' ввод в C# путем разрушения дерева наследования

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

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

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

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

5
задан Matthew Scharley 17 September 2008 в 23:55
поделиться

10 ответов

Я думаю, что сделал бы этот [интервал] и этот [строка] средства доступа виртуальный и переопределил бы их в BList/BDictionary. Классы, где средства доступа не имеет смысла, должны бросить NotSupportedException () (возможно, при наличии реализации по умолчанию в BItem).

Это заставляет Ваш код работать таким же образом и дает Вам более читаемую ошибку в случае, если необходимо записать

 (BInteger)torrent["info"][0]["files"]["length"];

по ошибке.

5
ответ дан 13 December 2019 в 19:39
поделиться

Моя рекомендация состояла бы в том, чтобы представить больше абстракций. Я нахожу его путающий, что BItem имеет DecodeFile (), который возвращает BDictionary. Это может быть разумной вещью сделать в домене потока, я не знаю.

Однако я нашел бы API как следующее более разумное:

BFile torrent = BFile.DecodeFile("my.torrent");
int filelength = torrent.Length;
1
ответ дан 13 December 2019 в 19:39
поделиться

Путем я вижу его, не, все BItems являются наборами, таким образом не, все BItems имеют индексаторы, таким образом, индексатор не должен быть в BItem. Я получил бы другой абстрактный класс из BItem, давайте назовем его BCollection и поместим индексаторы там, что-то как:

abstract class BCollection : BItem {

      public BItem this[int index] {get;}
      public BItem this[string index] {get;}
}

и сделайте BList, и BDictionary наследовались BCollection. Или Вы могли приложить дополнительные усилия и сделать BCollection универсальным классом.

1
ответ дан 13 December 2019 в 19:39
поделиться

Если длина файла - что-то, что Вы часто получаете, почему бы не реализовать свойство в классе BDictionary (?)... так, чтобы Вы кодировали, становится:

BDictionary torrent = BItem.DecodeFile("my.torrent");
int filelength = torrent.FileLength;

Тем путем детали реализации скрыты от пользователя.

1
ответ дан 13 December 2019 в 19:39
поделиться

Сделал Вы рассматриваете парсинг простого "пути", таким образом, Вы могли записать этому этот путь:

BDictionary torrent = BItem.DecodeFile("my.torrent");
int filelength = (int)torrent.Fetch("info.files.0.length");

Возможно, не лучший способ, но удобочитаемость увеличивается (немного)

0
ответ дан 13 December 2019 в 19:39
поделиться

Вы действительно не должны получать доступ ни к каким производным классам от базового класса, поскольку он в значительной степени повреждает идею ООП. Readibility, конечно, имеет большое значение, но я не обменял бы его на возможность многократного использования. Рассмотрите случай, когда необходимо будет добавить другой подкласс - необходимо будет также обновить базовый класс соответственно.

3
ответ дан 13 December 2019 в 19:39
поделиться
  • Если Вы имеете полный контроль над своей кодовой базой и своим мыслительным процессом, любой ценой сделайте.
  • В противном случае Вы будете сожалеть об этом день, некоторый новый человек вводит деривацию BItem, что Вы не видели вход в Ваш BList или BDictionary.

Если необходимо сделать это, по крайней мере перенестись, это (управляйте доступом к списку) в классе, который имеет сигнатуры методов со строгим контролем типов.

BString GetString(BInteger);
SetString(BInteger, BString);

Примите и возвратите BStrings даже при том, что Вы внутренне храните его в BList BItems. (позвольте мне разделить, прежде чем я сделаю свои 2 B или не 2 B),

0
ответ дан 13 December 2019 в 19:39
поделиться

Хм. Я на самом деле утверждал бы, что первая строка кодированных более читаема, чем второе - она берет немного дольше для выяснения то, что идет на нее, но его более очевидное, что Вы рассматриваете объекты как BList или BDictionary. Применение методов к абстрактному классу скрывает ту деталь, которая может мешать выяснять то, что на самом деле делает Ваш метод.

0
ответ дан 13 December 2019 в 19:39
поделиться

Это - просто я

BDictionary torrent = BItem.DecodeFile("my.torrent");int filelength = (BInteger)((BDictionary)((BList)((BDictionary)             torrent["info"])["files"])[0])["length"];

Вам не нужен 'поток' броска BDictionary, объявляется как BDictionary

public BItem this[int index]{    get { return ((BList)this)[index]; }}public BItem this[string index]{    get { return ((BDictionary)this)[index]; }}

Они не достигают желаемого результата, поскольку тип возврата является все еще абстрактной версией, таким образом, все еще необходимо бросить.

Переписанный код должен был бы быть

BDictionary torrent = BItem.DecodeFile("my.torrent");int filelength = (BInteger)((BList)((BDictionary)torrent["info"]["files"])[0])["length"];

Который является настолько же плох как первая партия

0
ответ дан 13 December 2019 в 19:39
поделиться

При представлении дженериков можно постараться не бросать.

class DecodedTorrent : BDictionary<BDictionary<BList<BDictionary<BInteger>>>>
{
}

DecodedTorrent torrent = BItem.DecodeFile("mytorrent");
int x = torrent["info"]["files"][0]["length"];

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

0
ответ дан 13 December 2019 в 19:39
поделиться
Другие вопросы по тегам:

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