简体   繁体   中英

Passing lambdas into a method to compare members of two lists

I'm doing alot of test of data integrity after copying data from db1 to db2.

I keep writing tests that are almost identical, here is the pseudo code

Get db1List
Get db2list

for each db2poco in db2list
 linq to get list of db1pocos.membervaribale1 matches db2poco.membervaribale1
  if db1pocos.membervaribale2 == db2poco.membervaribale2
     return false

return true

I'd like to convert it into a generic method that takes generics and lambdas for the compareisons... something kindof like this, except it does not compile...

private bool GenericCompareLists<T1, T2>(List<T1> cdssList, List<T2> spamisList, object sender, Func<bool, T1, T2> filterLambda ,  Func<bool, T1, T2> compareLambda )
{
    bool passed = true;
    foreach ( T2 spamisCv in spamisList )
    {
        List<T1> cdssSubList = ( from l in cdssList where filterLambda( l, spamisCv ) select l ).ToList();// should alwasy be one, 
        if ( cdssSubList.Count != 1 )
        {
            log.Error( "..." );
            passed = false;
        }
        else
        {
            T1 cdssCv = cdssSubList.First();

            if ( compareLambda( cdssCv, spamisCv) )// comparing the sum of all check_amt for this type, cdss vs spamis - EWB
            {
                log.Error( "Failed in comparison f" + sender.ToString()  );
                passed = false;
            }
        }
    }
    return passed;
}

But I can't figure outsytnax how to make it acutally work/ call it.

Could somone please give me a hand? or point me to good refernces that will bump up my lambda fu...

Most certainly

Func<bool, T1, T2> 

should be

Func<T1, T2, bool>

and that's because the definition of Func is:

public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);

notice that the third generic argument is the one that defines the return value of the method prototype / delegate.

Try that and see how it goes. I'm not sure that's the only one (is log a properly defined field in the surrounding class ?)

The Func delegate return value is the last generic parameter, not the first. (you can tell by the in/out variance markers). So if you move the bool to the last generic parameter it should compile.

ie change the signiture to (noting the position of the type parameters in the func types):

    private bool GenericCompareLists<T1, T2>(List<T1> cdssList, List<T2> spamisList, object sender, Func<T1, T2, bool> filterLambda, Func<T1, T2, bool> compareLambda)

That makes it compile for me. Discounting the missing 'log' variable.

Your Func parameters are in the wrong order, and you can't use the query syntax when using your own filter functions. It looks like you want:

private bool GenericCompareLists<T1, T2>(List<T1> cdssList, List<T2> spamisList, object sender, Func<T1, T2, bool> filterLambda ,  Func<T1, T2, bool> compareLambda )
{
    bool passed = true;
    foreach ( T2 spamisCv in spamisList )
    {
        List<T1> cdssSubList = cdssList.Where(l => filterLambda(l, spamisCv)).ToList();
        if ( cdssSubList.Count != 1 )
        {
            log.Error( "..." );
            passed = false;
        }
        else
        {
            T1 cdssCv = cdssSubList.First();

            if ( compareLambda( cdssCv, spamisCv) )// comparing the sum of all check_amt for this type, cdss vs spamis - EWB
            {
                log.Error( "Failed in comparison f" + sender.ToString()  );
                passed = false;
            }
        }
    }
    return passed;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM