Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I assign a var to be one of two difference types based on a conditional?

I have two dictionaries, one for my file transfers I have as a host, and one for my file transfers I have as a client.

The code I'm doing for one of the areas of my program is entirely similar, with exception of referencing one of these items or the other. For this reason, I'm trying to prevent duplicating code if I can.

public void UpdateFileTransferItems(FileTransferItem.FileTransferRole role)
{
    // If the role is Sender then the variable is fileTransferSessionsAsHost, otherwise it is fileTransferSessionsAsClient.
    var fileTransferSessions = role == FileTransferItem.FileTransferRole.Sender ? fileTransferSessionsAsHost : fileTransferSessionsAsClient;


    foreach (var hostSession in fileTransferSessions)
    {
         Do Work in here.
    }
}

Obviously the ternary operator doesn't work, but how can I create code that will do what I am trying to do? If the role is of a sender, I want the variable to be a reference to fileTransferSessionsAsHost, otherwise I want it to be fileTransferSessionsAsClient.

Am I going about this in an obtuse way? Should I just duplicate the code and have two if statements?

EDIT:

This is what I'm having to do right now, if I can't figure out a better way. If you look, the code is identical for each one, with exception of the names and dictionary items reference.

        public void UpdateFileTransferItems(FileTransferItem.FileTransferRole role)
    {
        if (role == FileTransferItem.FileTransferRole.Sender)
        {
            foreach (var hostSession in fileTransferSessionsAsHost)
            {
                var fileTransferItem = activeFileTransfers.FirstOrDefault(fti => fti.SessionId == hostSession.Key.SessionId);
                if (fileTransferItem == null)
                {
                    activeFileTransfers.Add(new FileTransferItem(hostSession.Key.FileName,
                                                                 hostSession.Key.FileExtension,
                                                                 hostSession.Key.FileLength,
                                                                 FileTransferItem.FileTransferRole.Sender,
                                                                 hostSession.Key.SessionId));
                }
                else
                {
                    fileTransferItem.Update(hostSession.Value.TotalBytesSent,
                                            hostSession.Value.TransferSpeed,
                                            hostSession.Value.TotalBytesSent == hostSession.Key.FileLength);
                }
            }
        }
        else
        {
            foreach (var clientSession in fileTransferSessionsAsClient)
            {
                var fileTransferItem = activeFileTransfers.FirstOrDefault(fti => fti.SessionId == clientSession.Key.SessionId);
                if (fileTransferItem == null)
                {
                    activeFileTransfers.Add(new FileTransferItem(clientSession.Key.FileName,
                                                                 clientSession.Key.FileExtension,
                                                                 clientSession.Key.FileLength,
                                                                 FileTransferItem.FileTransferRole.Sender,
                                                                 clientSession.Key.SessionId));
                }
                else
                {
                    fileTransferItem.Update(clientSession.Value.TotalBytesSent,
                                            clientSession.Value.TransferSpeed,
                                            clientSession.Value.TotalBytesSent == clientSession.Key.FileLength);
                }
            }
        }
    }
like image 715
Cowman Avatar asked Oct 22 '22 20:10

Cowman


1 Answers

In order for what you want, both classes need to derive from the same base class or interface. For instance, if you have a common interface called IFileTransferSessions, then the following code should work:

IFileTransferSessions fileTransferSessions = role == FileTransferItem.FileTransferRole.Sender ? fileTransferSessionsAsHost : fileTransferSessionsAsClient;

or if you really want to keep the var syntax:

var fileTransferSessions = role == FileTransferItem.FileTransferRole.Sender ? fileTransferSessionsAsHost as IFileTransferSessions : fileTransferSessionsAsClient;

Note, you only need to cast the first tertiary result to the interface, or you can do both.

The var keyword is not like Variant from VB where it doesn't care what the type is at compile time. (that's closer to dynamic in C#) All it does is derive the type from the following usage. For two different classes to be derived, they must share a common base class or interface, and even then var needs to know about that base definition to work properly.

like image 172
Steve Py Avatar answered Oct 27 '22 00:10

Steve Py