Что вызывает исключение в string.concat - PullRequest
1 голос
/ 03 января 2011

Вот несколько классов:

public class MyItem : ParamOut
{
    public string Code
    {
        get { return _quoteCode; }
    }

    public InnerItem[] Skus
    {
        get { return _skus; }
    }

    public PriceSummary Price
    {
        get { return _price; }
    }

    public override string ToString()
    {
        return string.Concat("Code=", Code, "; SKUs=[", Skus != null ? "{" + string.Join("},{", Array.ConvertAll(Skus, item => item.ToString())) + "}" : "", "]"
            , "; Price={", Price.ToString(), "}", base.ToString()
            );
    }

    ...
}

public abstract class ParamOut
{
    public override string ToString()
    {
        return null;
    }

    public string ErrorMessage { get; set; }
}

Функциональность вызова:

{
    MyItem item = new MyItem{ ErrorMessage = "Bla-bla-bla" };
    string text = item.ToString();
}

Я получаю исключение NullReference внутри метода ToString () (каждое свойство переменной элемента равно нулю).

Вопрос:

Q1. какая перегрузка string.Concat будет вызываться в этом случае? У меня есть 9 параметров, поэтому я предполагаю одно из следующего:

public static string Concat(params Object[] args)

или

public static string Concat(params string[] values)

Но кто из них?

Q2. Почему генерируется исключение? Разве «null» не должен преобразовываться во что-то вроде «null» или «» (пустая строка)?

Большое спасибо!

Ответы [ 6 ]

2 голосов
/ 03 января 2011

q1: вы передаете только строки, поэтому он будет использовать строку [] version

q2: в дополнение к тому, что сказал matt, даже если Concat допускает нулевые значения, вы все равно получите исключение изгде вы вызываете Price.ToString (), поскольку Price имеет значение null

1 голос
/ 03 января 2011
  1. Наиболее подходящая перегрузка - если все параметры являются строковыми, то вызывается перегрузка строки. Поскольку это не так, будет вызвана перегрузка Object.

  2. Price может быть нулевым или одним из SKU элементов или даже Code, поэтому вызов ToString для любого из этих (передача объектов Concat вызовет ToString) бросить исключение NullReferenceException.

1 голос
/ 03 января 2011
  1. Я предполагаю, что вызывается перегрузка с помощью 'Object []' (поскольку используются параметры разных типов) (пожалуйста, исправьте меня, если я ошибаюсь).

  2. Price.ToString () вызвал ошибку, если Price равен нулю. И .ToString () здесь вообще не требуется

0 голосов
/ 03 января 2011

Я думаю, вы сами это сказали:

(каждое свойство переменной элемента равно нулю)

Вы, вероятно, должны проверить, что массив InnerItem s (из свойства Skus) содержит любые элементы null.

Их, вероятно, можно было бы избежать с помощью простого Where предложения или аналогичного.

И ответить на ваши вопросы:

  • Q1: будет вызвана перегрузка string[].
  • Q2: Concat будет обрабатывать null как пустую строку.
0 голосов
/ 03 января 2011

Прежде всего, я подозреваю, что вы NullReferenceException потому что вы вызываете ToString для нулевого объекта.

Однако попытка согласовать null также даст вам это исключение.

В этом случае вы можете использовать string.Format.

return string.Format("Code={0}; SKUs=[{1}]; Price={2}{3}", 
    Code ?? "null",
    SKUs != null ? 
        string.Join(",", SKUs.Select(s => "{" + s.ToString() ?? "null" + "}")) :
        string.Empty,
    (Price ?? "null").ToString() ?? "null",
    base.ToString() ?? "null");

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

x.ToString() ?? "null"

логически эквивалентно

x.ToString() == null ? "null" : x.ToString()

Я немного переборщил с тем, как много нулевых проверок, но похоже, что в вашем коде есть много потенциальных ошибок. :)

0 голосов
/ 03 января 2011

Не следует преобразовывать 'NULL' в что-то вроде 'null' или "" (пусто строка)?

Во что его следует преобразовать? Некоторые люди хотели бы пустую строку, другие хотели бы «ноль» и т. Д. Microsoft решила не отвечать на это, так как здесь есть много вещей, которые могли бы дать правильные ответы. Так что MS выбрала более безопасный маршрут и просто выдает исключение.

...