Getting out parameter from string [] as IEnumerable <string>
Say we have a method:
public void SomeMethod(out string[] someArray) { // ... } Is there a way to do something similar to this:
IEnumerable<string> result; SomeMethod(out result); Edit: The thing is, I donโt want to bind the value of out to string[] , I would like the code to work even if the method declaration was changed to SomeMethod(out List<string> outputValue) .
It is not possible to change the type of the output parameter, because type safety cannot be guaranteed. This is explained in detail on Eric Lippert Blog .
Here is a code example of how security type could be broken, if allowed:
IEnumerable<string> result; public void Test() { SomeMethod(out result); } public void SomeMethod(out string[] someArray) { someArray = new string[]; ChangeTheType(); int n = someArray.Length; // BANG!! - someArray is now a List<string> } public void ChangeTheType() { result = new List<string>(); } Obviously, this is only a problem if the result is not in the same area as the SomeMethod call, but the compiler does not check this. This is simply not allowed.
Change the method signature to public void SomeMethod(out IEnumerable<string> someStrings) . You can assign string[] to someStrings inside SomeMethod , and if you later decide to use List<string> , you can assign it also without braking the call.
Personally, I would primarily avoid the parameters: public string[] SomeMethod() .
I'm sure this is not the best way, but you can write another method that does this work for you:
public class ClassA { private void SomeMethod(out IEnumerable<string> result) { string[] res; SomeMethod(out res); result = res; } public void SomeMethod(out string[] someArray) { someArray = new string[2]; } void Test() { IEnumerable<string> result; SomeMethod(out result); } } You cannot do this, and it is not. One of the reasons the CLR does not support out is just ref . Thus, out actually represented as ref , with some special rules added by the C # compiler.
The simplest (and obvious) way is to create a separate variable:
string[] resultArray; SomeMethod(out resultArray); IEnumerable<string> result = resultArray; You can create a helper method to perform this casting for you:
public delegate void ActionWithOut<T>(out T result); public static void ConvertOut<TBase, TDerived>( ActionWithOut<TDerived> method, out TBase result) where TDerived : TBase { TDerived derived; method(out derived); result = derived; } Using:
IEnumerable<string> result; ConvertOut<IEnumerable<string>, string[]>(SomeMethod, out result); But for each number of parameters, you need a separate overload (and the type of delegation), and the code doesnโt actually look much better. (Type parameters are required; input type does not work for this code.)