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.

4
  • 6
    Tuple.Create is a method. See this page for proper usage: learn.microsoft.com/en-us/dotnet/api/… Commented Mar 29, 2019 at 13:34
  • 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); Commented Mar 29, 2019 at 13:37
  • You´re just missing brackets behing Tuple.Create. Commented Mar 29, 2019 at 13:37
  • Tuple.Create(a,b); Commented Mar 29, 2019 at 13:39

4 Answers 4

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: (

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! That was easier than I thought :)
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);
}

Comments

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.

Comments

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.
    }
}

1 Comment

That is simply amazing! Much easier to look at - thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.