Как мне создать нулевой объект в C #

Вы можете использовать тип-конвертер . Чтобы преобразовать массив любых типов в массив строк, вы можете зарегистрировать свой собственный конвертер:

 TypeConverter.registerConverter(Object[].class, String[].class, new Converter() {

        @Override
        public String[] convert(Object[] source) {
            String[] strings = new String[source.length];
            for(int i = 0; i < source.length ; i++) {
                strings[i] = source[i].toString();
            }
            return strings;
        }
    });

и использовать его

   Object[] objects = new Object[] {1, 23.43, true, "text", 'c'};
   String[] strings = TypeConverter.convert(objects, String[].class);

13
задан Ahmad Ahmadi 26 July 2015 в 12:17
поделиться

4 ответа

Я склонен согласиться с ответом Вятта Барнетта в том, что вы должны проявлять сдержанность при создании подобных «нулевых» объектов. Тем не менее, для этого есть несколько веских причин. Иногда.

Я также склонен согласиться с ответом Supertux в том, что вся суть нулевого объекта состоит в том, чтобы не проверять, является ли он нулевым, поэтому вы должны потерять свойство IsNull. Если вы действительно чувствуете, что вам нужно свойство IsNull, прочтите ответ Вятта еще раз и подумайте еще раз.

И спасибо CraigTP за прекрасные ссылки для получения дополнительной информации. Хороший материал.

Теперь я предполагаю, что в вашем реальном коде у вас действительно есть конструктор, который пытается установить значения Name или Species (независимо от того, какой эквивалент вашего реального кода мог бы быть вызван). Иначе, почему вы получите предупреждение / ошибку «вызов виртуального члена в конструкторе»? Я столкнулся с парой подобных проблем при использовании новомодного MyProperty {get; установлен; } сам ярлык (особенно, когда используется в структурах, и не заставляйте меня начинать о сериализации версий). Ваше решение - не использовать ярлык, а вместо этого сделать это старомодным способом.

public class Animal {
    protected Animal() { }

    public Animal(string name, string species) {
        _Name = name;
        _Species = species;
    }

    public virtual string Name {
        get { return _Name; }
        set { _Name = value; }
    }
    private string _Name;

    public virtual string Species {
        get { return _Species; }
        set { _Species = value; }
    }
    private string _Species;
}

public sealed class NullAnimal : Animal {
    public override string Name {
        get { return String.Empty; }
        set { }
    }
    public override string Species {
        get { return String.Empty; }
        set { }
    }
}

Это решает проблему установки ваших виртуальных свойств в конструкторе. Вместо этого вы устанавливаете значения личного поля (то, что у вас нет возможности ссылаться, если вы используете ярлык). Для дополнительного удобства скомпилируйте оба метода и используйте Reflector для просмотра полученных сборок.

Чем больше я использую {get; установлен; } ярлык, тем более он мне не нравится.

мы столкнулись с парой подобных проблем при использовании новомодного MyProperty {get; установлен; } сам ярлык (особенно, когда используется в структурах, и не заставляйте меня начинать о сериализации версий). Ваше решение - не использовать ярлык, а вместо этого сделать это старомодным способом.

public class Animal {
    protected Animal() { }

    public Animal(string name, string species) {
        _Name = name;
        _Species = species;
    }

    public virtual string Name {
        get { return _Name; }
        set { _Name = value; }
    }
    private string _Name;

    public virtual string Species {
        get { return _Species; }
        set { _Species = value; }
    }
    private string _Species;
}

public sealed class NullAnimal : Animal {
    public override string Name {
        get { return String.Empty; }
        set { }
    }
    public override string Species {
        get { return String.Empty; }
        set { }
    }
}

Это решает проблему установки ваших виртуальных свойств в конструкторе. Вместо этого вы устанавливаете значения личного поля (то, что у вас нет возможности ссылаться, если вы используете ярлык). Для дополнительного удобства скомпилируйте оба метода и используйте Reflector для просмотра полученных сборок.

Чем больше я использую {get; установлен; } ярлык, тем более он мне не нравится.

мы столкнулись с парой подобных проблем при использовании новомодного MyProperty {get; установлен; } сам ярлык (особенно, когда используется в структурах, и не заставляйте меня начинать о сериализации версий). Ваше решение - не использовать ярлык, а вместо этого сделать это старомодным способом.

public class Animal {
    protected Animal() { }

    public Animal(string name, string species) {
        _Name = name;
        _Species = species;
    }

    public virtual string Name {
        get { return _Name; }
        set { _Name = value; }
    }
    private string _Name;

    public virtual string Species {
        get { return _Species; }
        set { _Species = value; }
    }
    private string _Species;
}

public sealed class NullAnimal : Animal {
    public override string Name {
        get { return String.Empty; }
        set { }
    }
    public override string Species {
        get { return String.Empty; }
        set { }
    }
}

Это решает проблему установки ваших виртуальных свойств в конструкторе. Вместо этого вы устанавливаете значения личного поля (то, что у вас нет возможности ссылаться, если вы используете ярлык). Для дополнительного удобства скомпилируйте оба метода и используйте Reflector для просмотра полученных сборок.

Чем больше я использую {get; установлен; } ярлык, тем более он мне не нравится.

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

public class Animal {
    protected Animal() { }

    public Animal(string name, string species) {
        _Name = name;
        _Species = species;
    }

    public virtual string Name {
        get { return _Name; }
        set { _Name = value; }
    }
    private string _Name;

    public virtual string Species {
        get { return _Species; }
        set { _Species = value; }
    }
    private string _Species;
}

public sealed class NullAnimal : Animal {
    public override string Name {
        get { return String.Empty; }
        set { }
    }
    public override string Species {
        get { return String.Empty; }
        set { }
    }
}

Это решает проблему установки ваших виртуальных свойств в конструкторе. Вместо этого вы устанавливаете значения личного поля (то, что у вас нет возможности ссылаться, если вы используете ярлык). Для дополнительного удобства скомпилируйте оба метода и используйте Reflector для просмотра полученных сборок.

Чем больше я использую {get; установлен; } ярлык, тем более он мне не нравится.

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

public class Animal {
    protected Animal() { }

    public Animal(string name, string species) {
        _Name = name;
        _Species = species;
    }

    public virtual string Name {
        get { return _Name; }
        set { _Name = value; }
    }
    private string _Name;

    public virtual string Species {
        get { return _Species; }
        set { _Species = value; }
    }
    private string _Species;
}

public sealed class NullAnimal : Animal {
    public override string Name {
        get { return String.Empty; }
        set { }
    }
    public override string Species {
        get { return String.Empty; }
        set { }
    }
}

Это решает проблему установки ваших виртуальных свойств в конструкторе. Вместо этого вы устанавливаете значения личного поля (то, что у вас нет возможности ссылаться, если вы используете ярлык). Для дополнительного удобства скомпилируйте оба метода и используйте Reflector для просмотра полученных сборок.

Чем больше я использую {get; установлен; } ярлык, тем более он мне не нравится.

скомпилируйте оба метода и используйте Reflector для просмотра результирующих сборок.

Чем больше я использую {get; установлен; } ярлык, тем более он мне не нравится.

скомпилируйте оба метода и используйте Reflector для просмотра результирующих сборок.

Чем больше я использую {get; установлен; } ярлык, тем более он мне не нравится.

11
ответ дан 2 December 2019 в 03:38
поделиться

Посмотрите, сколько боли вызвали интересные концепции, такие как DbNull, и подумайте, действительно ли это хорошая идея.

Совет: если вы постоянно проверяете наличие null ссылок, вам, вероятно, следует немного переосмыслить API, чтобы помочь предотвратить появление нулевых объектов ближе к вершине стека.

Совет II: если что-то генерирует исключение при неожиданном нулевом значении, на самом деле это нормально. Если у вас есть нулевые значения там, где их не должно быть, все должно пойти отлично.

25
ответ дан 2 December 2019 в 03:38
поделиться

Смысл шаблона "Нулевой объект" в том, что он не требует нулевой проверки для предотвращения сбоя или ошибки.

Например, если вы пытались выполнить операцию со свойством Species и он был нулевым - это вызвало бы ошибку.

Итак, вам не нужен метод isNull, просто верните что-то в получателе, что не вызовет сбой / ошибку приложения, например:

public class Animal
{
    public virtual string Name { get; set; }
    public virtual string Species { get; set; }
}

public sealed class NullAnimal : Animal
{
    public override string Name
    {
        get{ return string.Empty; }
        set { ; }
    }
    public override string Species
    {
        get { return string.Empty; }
        set { ; }
    }
}
3
ответ дан 2 December 2019 в 03:38
поделиться

Вы можете использовать этот подход, только если он уместен. Ваш пример объекта Animal не может быть хорошим примером, потому что он не представляет подходящий случай, когда вы бы использовали этот подход. Например:

Animal animal = new Animal();

if (animal.tail == null)
{
    //do nothing because wagging a tail that doesn't exist may crash the program
}
else
{
    animal.wagTail();
}

В этом примере вы должны построить объект Animal, чтобы, если у животного нет хвоста, оно могло успешно обрабатывать команду wagTail () без сбоев.

Class Animal
{
    Tail tail;

    void wagTail()
    {
        if (this.tail == null)
        {
            //do nothing
        }
        else
        {
            this.tail.doTheWag();
        }
    }
}

Теперь вам не нужно выполнить нулевую проверку, но может просто вызвать animal.wagTail () независимо от того, есть у животного хвост или нет.

2
ответ дан 2 December 2019 в 03:38
поделиться
Другие вопросы по тегам:

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