4

I am trying to call a function which returns a tuple with two arrays. The content of the arrays are based on checked items in a checkedListBox. I define the arrays and call the function "storeParametersInArrays" as shown below.

string[] allowedObjects = new string[checkedListObjects.CheckedItems.Count]; // All allowed objects
string[] notallowedObjects = new string[checkedListObjects.Items.Count - checkedListObjects.CheckedItems.Count]; // All not allowed objects

Tuple<string[], string[]> ObjParameters = storeParametersInArrays(notallowedObjects, allowedObjects, checkedListObjects);
allowedObjects = ObjParameters.Item1;
notallowedObjects = ObjParameters.Item2;

The function called is defined as:

private Tuple<string[], string[]> storeParametersInArrays(string[] notallowed, string[] allowed, CheckedListBox checkedListBox)
{
    int i = 0; // allowed objects
    int j = 0; // not allowed objects
    int k = 0; // item counter

    foreach (object item in checkedListBox.Items)
    {
        if (!checkedListBox.CheckedItems.Contains(item))
        {
            notallowed[j++] = checkedListBox.Items[k].ToString();
        }
        else
        {
            allowed[i++] = checkedListBox.Items[k].ToString();
        }
        k++;
    }
    return Tuple.Create<allowed, notallowed>;
}

I am unable to return the Tuple in the above code sample. I get the error "Cannot convert method group 'Create' to non-delegate type 'Tuple'".

It is my first time working with tuples, how can I return the two arrays without having to call the function twice?

I have looked at slightly similar problems, so if the question is already answered somewhere else, I will be glad to be pointed in the right direction.

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
ChrisRun
  • 131
  • 1
  • 9

4 Answers4

4

Just change

return Tuple.Create<allowed, notallowed>;

to

return Tuple.Create(allowed, notallowed);

The first syntax is for generics: <

The second for method calls: (

Flat Eric
  • 7,971
  • 9
  • 36
  • 45
2

You have to correct your method call Tuple.Create:

private Tuple<string[], string[]> storeParametersInArrays(string[] notallowed, string[] allowed, CheckedListBox checkedListBox)
{
    int i = 0; // allowed objects
    int j = 0; // not allowed objects
    int k = 0; // item counter

    foreach (object item in checkedListBox.Items)
    {
        if (!checkedListBox.CheckedItems.Contains(item))
        {
            notallowed[j++] = checkedListBox.Items[k].ToString();
        }
        else
        {
            allowed[i++] = checkedListBox.Items[k].ToString();
        }
        k++;
    }
    return Tuple.Create(allowed, notallowed);
}
Code Pope
  • 5,075
  • 8
  • 26
  • 68
2

This line

return Tuple.Create<allowed, notallowed>;

replace with

return Tuple.Create<string[], string[]>(allowed, notallowed);

Or simple

return Tuple.Create(allowed, notallowed);

The static method Create is a generic method and the error is that you are using the values like the types that the Create method will return.

julian zapata
  • 89
  • 1
  • 8
1

You placed the values where the type parameters should be. But I think that the type parameters can be inferred here:

return Tuple.Create(allowed, notallowed);

However, you could use new ValueTuples. A simplified tuple syntax was introduced in C# 7.0.

private (string[], string[]) storeParametersInArrays(
    string[] notallowed, string[] allowed, CheckedListBox checkedListBox)
{
    ...
    return (allowed, notallowed);
}

You can then get the result stored directly into your existing variables with:

(allowedObjects, notallowedObjects) = storeParametersInArrays(
    notallowedObjects, allowedObjects, checkedListObjects);

But since arrays are reference types, you don't even have to return them from the method. You are not passing copies of the arrays to the method - only references. Therefore the method fills the original arrays.

private void storeParametersInArrays(
    string[] notallowed, string[] allowed, CheckedListBox checkedListBox)
{
    // Fill the arrays here.

    // No need for a return statement.
}

Now you can write

storeParametersInArrays(notallowedObjects, allowedObjects, checkedListObjects);

// allowedObjects and notallowedObjects are now filled. Example
string firstAllowed = allowedObjects[0];

You can even go a step further and use the Local functions introduced in C# 7.0. They have access to the variables of the surrounding method and therefore don't require the parameters in this case.

void myButton_Click(object sender, RoutedEventArgs e)
{
    string[] allowedObjects = new string[...];
    string[] notallowedObjects = new string[...];

    storeParametersInArrays();

    // Use the result
    string firstAllowed = allowedObjects[0];

    // Nested local function
    void storeParametersInArrays()
    {
        // You can access allowedObjects, notallowedObjects and checkedListObjects here.
        // Fill the arrays.
    }
}
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188