2

Case

This morning I refactored some Logging method and needed to change a method's 'params' parameter in a normal array. Consequently, the call to the method had to change with an array parameter. I'd like the method call to change as less as possible, since it's a heavily used utility method.

I assumed I should be able to use the collection initializer to call the method, but it gave me a compile-error. See the second call in the example below. The third call would be fine too, but also results in an error.

Example

void Main()
{
    // This works.
    object[] t1 = { 1, "A", 2d };
    Test(t1);

    // This does not work. Syntax error: Invalid expression term '{'.
    Test({1, "A", 2d });

    // This does not work. Syntax error: No best type found for implicitly-typed array.
    Test(new[] { 1, "A", 2d });

    // This works.
    Test(new object[] { 1, "A", 2d });
}

void Test(object[] test)
{
    Console.WriteLine(test);
}

Question

  • Is there any way to call Test() without initializing an array first?
Herman Cordes
  • 4,628
  • 9
  • 51
  • 87
  • If option 3 works, why not use that? – Sam Axe Mar 24 '14 at 09:56
  • 3
    Well even if the second version worked, it would still be initializing the array. For example, `new[] { "a", "b" }` is precisely equivalent to `new string[] { "a", "b" }` in terms of the code generated. Note that `new[]` is *not* a collection initializer - it's just a normal array initializer, with an inferred array type. – Jon Skeet Mar 24 '14 at 09:56
  • 1
    Here's an explanation *why* option 2 does not work: [Why Compiler cannot infer the object array type?](http://stackoverflow.com/q/22466251/87698) – Heinzi Mar 24 '14 at 10:00
  • @Dan-o, I updated the case. I'd like the method call to change as less as possible, because I'd have to do a lot of refactoring. – Herman Cordes Mar 24 '14 at 10:01
  • I feel compelled to ask this: why do you want to change the signature if you want to affect usage as little as possible; what does your refactoring achieve? Was this a `params object[] args` method before? – aevitas Mar 24 '14 at 10:04
  • @aevitas Yes, this was a `params object[] args` before. I had to add the parameter `[CallerMemberName]string memberName = null` to the signature of the method for logging purposes. Therefore it's no longer possible to use params. – Herman Cordes Mar 24 '14 at 10:11

1 Answers1

4

The problem is that C# is trying infer the type of the array. However, you provided values of different types and thus C# cannot infer the type. Either ensures that all you values are of the same type, or explicitly state the type when you initialize the array

var first = new []{"string", "string2", "string3"};
var second = new object[]{0.0, 0, "string"};

Once you stop using params there is no way back. You will be forced to initialize an array.

Alternative continue using params:

public void Test([CallerMemberName]string callerMemberName = null, params object[] test2){}
Kasper Holdum
  • 12,993
  • 6
  • 45
  • 74