What causes exception in string.concat
Here are few classes:
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; }
}
Here is calling functionality:
{
MyItem item = new MyItem{ ErrorMessage = "Bla-bla-bla" };
string text = item.ToString();
}
I am getting NullReference exception inside of 'ToString()' method (each property of item variable is null).
Question:
Q1. what overload of string.Concat will be called in this case? I have 9 parameters, so I guess one of the following:
public static string Concat(params Object[] args)
or
public static string Concat(params string[] values)
But which of them?
Q2. Why exception is generated? Shouldn't 'null' be converted into something like 'null' or "" (empty string)?
Thanks a lot!
q1: you are only passing in strings so it will use the string[] version
q2: in addition to what matt said, even if Concat allowed null values, you'd still get the exception from where you call Price.ToString() since Price is null
I guess, that the overload with 'Object[]' is called (as parameters of different types are used) (please correct me if I wrong).
Price.ToString() caused an error if Price is null. And .ToString() is not required here at all
The most appropriate overload - if all parameters are string then the string overload will be called. Since they are not, the
Object
overload will be called.The
Price
might be null or one of theSKU
items or evenCode
, so callingToString
on any of these (passing objects toConcat
will callToString
) will throw the NullReferenceException.
Shouldn't 'null' be converted into something like 'null' or "" (empty string)?
What should it be converted to? Some people would like the empty string, others would like "null", etc. Microsoft decided to not answer that, as there are many things that would be valid answers here. So MS took the safer route and just throws an exception.
First off, I suspect your NullReferenceException
is because you're calling ToString
on a null object.
However, trying to concat null
will also give you that Exception.
In this case, you might prefer to use 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");
You can see the use of the null-coalescing operator (??) wherever you might be dealing with a null value.
x.ToString() ?? "null"
is logically equivalent to
x.ToString() == null ? "null" : x.ToString()
I've gone a bit over the top with how many null checks there are, but it looks like there are a lot of potential gotchas in the code you have there. :)
I think you said it yourself:
(each property of item variable is null)
You should probably check that the array of InnerItem
s (from the Skus
property) contains any null
elements.
They could probably be avoided with a simple Where
-clause, or similar.
And to answer your questions:
- Q1: The
string[]
overload will be called. - Q2:
Concat
will treatnull
as an empty string.
精彩评论