0

I have created a method that is looking at a datagrid and is trying to return the values of each column so that is can be used in various other places.

I started making it as below but have run into the problem that a tuple can only hold 8 values (i have 16 to hold in total.

Is there another way to create a method that would return more than 8 values and if so how do you then use the returned values in other parts of my code?

public Tuple<string,string,string,string,string,string,string,string> CurrentSelectedRecord()
        {
            //Method to find current selected Records

            try
            {
                int rowIndex = dataGridView1.CurrentCell.RowIndex;
                string enquiryIDString = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[0].Value);
                string clientString = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[4].Value);
                string contractManagerString = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[5].Value);
                string receivedDateString = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[1].Value);
                string requiredDateString = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[2].Value);
                string completeDateString = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[3].Value);
                string descriptionString = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[6].Value);
                string actionString = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[7].Value);


                var tuple = new Tuple<string, string, string, string,string,string,string,string>(enquiryIDString, clientString, contractManagerString, receivedDateString, requiredDateString, completeDateString,descriptionString,actionString);

                return tuple;
            }
            catch
            {
                var tuple = new Tuple<string, string, string, string,string,string,string,string>("", "", "", "", "","","","");
                return tuple;
            }

        }

I tired the above code but it errored when i got to 8 variables.

  • 7
    Why not define a named `class` for your result-type? – Dai Mar 29 '22 at 09:52
  • 1
    Can you create a new POCO class? Or replace Tuple<> to Dictionay ? – Bob Mar 29 '22 at 09:53
  • Hello, I recommend you to use one of the "List-like" class for that use case. Because on the finally it is exactly what you have to return, a list of string. Depending on if you need the order of the items or not, you cas choose the appropriate built-in class of .NET. – Dylan El Bar Mar 29 '22 at 09:58
  • @DylanBarquilla - What is a "List-like" class? – Enigmativity Mar 29 '22 at 09:59
  • 1
    How about using Flickr api services? You'd use the System.Drawing namespace to create an image, then train a neural network to read the text from the image with the text of all the values, followed by uploading it to Flickr. Voila, all your method needs to return is a Tuple of the Flickr id and the network you trained as a COM object. – Yuriy Faktorovich Mar 29 '22 at 10:03
  • 2
    @YuriyFaktorovich I think you might be interpreting "looking at" a little too literally. – ProgrammingLlama Mar 29 '22 at 10:06
  • @DiplomacyNotWar woops, if only I had a nickel for every time that happened. – Yuriy Faktorovich Mar 29 '22 at 10:07
  • @YuriyFaktorovich :D – ProgrammingLlama Mar 29 '22 at 10:08
  • @Enigmativity I speak about this kind of class: https://learn.microsoft.com/fr-fr/dotnet/api/system.collections.generic.list-1?view=net-6.0 – Dylan El Bar Mar 29 '22 at 11:46
  • @Dai thank you for your reply, are you able to elaborate on this? I have no experience with classes so I am not sure exactly what that means or how to implement it? – Yippiekaiaii Mar 29 '22 at 12:27
  • @Yippiekaiaii First, let me ask you, what is your level of programming experience? How did you write the code you already have? I'm skeptical that you "have no experience with classes" if you're able to write that `CurrentSelectedRecord()` method... – Dai Mar 29 '22 at 12:28
  • @Dai , I am self teaching myself so all my knowledge has mainly come from the internet. The code i have written already has been learned through a process of working out what i want to do and then looking for guides/tutorial etc that help or asking question here. I have been doing this though for a year or so on and off. Maybe i have experience with classes but dont know that that is what they are called? – Yippiekaiaii Mar 29 '22 at 12:51
  • @Yippiekaiaii In that case I recommend you avoid writing any code for a bit and get a copy of [CLRS](https://www.amazon.com/Introduction-Algorithms-fourth-Thomas-Cormen/dp/026204630X) and work your way through that _first_. – Dai Mar 29 '22 at 13:42
  • @DylanBarquilla - That is a list class, it's not "List-like". – Enigmativity Mar 29 '22 at 20:43
  • I've re-opened because the OP clearly knows how to return multiple values in a tuple. The duplicate seemed to show how to do that. – Enigmativity Mar 29 '22 at 20:44
  • A ridiculous way to circumvent an 8-tuple limit is to return a `Tuple>>` – Wyck Mar 29 '22 at 20:59
  • Wow, this seems like a lot of work. Why not just return a [copy of the DataRow](https://stackoverflow.com/questions/12025012/simple-way-to-copy-or-clone-a-datarow)? – John Wu Mar 29 '22 at 21:21
  • @Wyck - It's not ridiculous. It's how a lot of functional languages do it. It's like a linked list. – Enigmativity Mar 29 '22 at 21:32
  • 1
    `try { ... } catch { return default; }` is an awful pattern. – Enigmativity Mar 29 '22 at 21:48
  • @Enigmativity I said a "list-like" class. Because there are other classes that could be helpful for the requester. You can use the classic List class, but there are other implementations. I just wanted to tell the global idea of using a list of string. – Dylan El Bar Mar 30 '22 at 07:52
  • So I would have dropped the double-quotes and the "-like". – Enigmativity Mar 30 '22 at 08:51

1 Answers1

1

As others have pointed out, you could create a class to hold the values you need to return

public class CurrentRecord
{
    public int Index { get; set; }
    public string EnquiryId { get; set; }
    public string Client { get; set; }
    public string ContractManager { get; set; }
    public string ReceivedDate{ get; set; }
    public string RequiredDate { get; set; }
    public string CompleteDate { get; set; }
    public string Description { get; set; }
    public string Action { get; set; }

    public CurrentRecord(int index, string enquiryId, string client,
        string contractManager, string receivedDate, string requiredDate, 
        string completeDate, string description, string action)
    {
        Index = index;
        EnquiryId = enquiryId;
        Client = client;
        ContractManager = contractManager;
        ReceivedDate = receivedDate;
        RequiredDate = requiredDate;
        CompleteDate = completeDate;
        Description = description;
        Action = action;
    }
}    

Your method then becomes

public CurrentRecord CurrentSelectedRecord()
{
    try
    {
        var rowIndex = dataGridView1.CurrentCell.RowIndex;
        var enquiryId = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[0].Value);
        var client = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[4].Value);
        var contractManager = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[5].Value);
        var receivedDate = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[1].Value);
        var requiredDate = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[2].Value);
        var completeDate = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[3].Value);
        var description = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[6].Value);
        var action = Convert.ToString(dataGridView1.Rows[rowIndex].Cells[7].Value);

        return new CurrentRecord(rowIndex, enquiryId, client, contractManager, 
            receivedDate, requiredDate, completeDate, description, action);
    }
    catch
    {
        return default;
    }
}

That you can use like so

var currentRecord = CurrentSelectedRecord();

if (currentRecord is not null)
{
    // You can do whatever you need with currentRecord object
    // currentRecord.Client
    // currentRecord.Action
}
Arthur Rey
  • 2,990
  • 3
  • 19
  • 42
  • 1
    Personally I don't like properties with "Date" in their name having a string type, but that is what the OP was using – Hans Kesting Mar 29 '22 at 21:30
  • `try { ... } catch { return default; }` is an awful pattern. – Enigmativity Mar 29 '22 at 21:42
  • 1
    @Enigmativity I agree, I'd do it completely differently if it was my own code, I tried to stay close to returning an empty `Tuple` as I didn't want to make the code more complex given that the OP said he didn't know what a class was... – Arthur Rey Mar 29 '22 at 21:52
  • 1
    @HansKesting Neither do I, but again I wanted to show how to create a POCO and return it. – Arthur Rey Mar 29 '22 at 21:55
  • You shouldn't mix mutable-properties (`{ get; set; }`) with constructors because it's unclear if your _intent_ is for `CurrentRecord` to be mutable or not. As the `CurrentSelectedRecord()` method is using the ctor I'd just remove the `set;` from all the properties. – Dai Mar 30 '22 at 01:19