Pratik Gaikwad
Pratik Gaikwad

Reputation: 1568

How to pass var type as parameter to another method

i have below Linq query in my code

var query = (from s in dc.UserContacts
             join g in dc.EmailRecipientInGroups on s.UserEmailRecipient.RID equals g.RID
             join zk in dc.ZeekUsers on s.UserID equals zk.UserId
             where s.aspnet_User.LoweredUserName.Equals(strUserName.ToLower())
             && !g.UserEmailRecipientGroup.IsDeleted
             && !s.UserEmailRecipient.IsDeleted
             select new { s = s, g = g, zk = zk });

where dc is DataContext for Linq to SQL

there are other two conditions which I need to include in the above query but below line will remain same

select new { s = s, g = g, zk = zk });

I have two create two separate methods for those two conditions. but the final code to generate output is going to be same for all 3 functions and output will be generated from query object.

So I am thinking of writing a new private method which I can call after above line in all 3 functions with query as parameter and get the result instead of duplicating code every time. But from internet i found that var type can not be passed as parameter.

Here is my Intellisense from Visual Studio when I hover mouse over the var keyword before query word

interface System.Linq.IQueryable<out T>
T is 'a
Anonymous types:
'a is new { usercontact s, EmailRecipientinGroup g, Zeekuser zk}

Upvotes: 0

Views: 1398

Answers (3)

Paulo Morgado
Paulo Morgado

Reputation: 14856

As others have already said, "variables that are declared at method scope can have an implicit type var. An implicitly typed local variable is strongly typed just as if you had declared the type yourself, but the compiler determines the type."

It is, however, the only way to declare variables of types that are, or involve, anonymous types.

Now to the LINQ part. You can look at LINQ queries as database view definitions (they are only executed when enumerated) but with a great benefit: they are composable.

You can write something like this:

IQueriable<UserContact> userContactsQuery =
    from s in dc.UserContacts
    where s.aspnet_User.LoweredUserName.Equals(strUserName.ToLower())
          && !s.UserEmailRecipient.IsDeleted
    select s;

IQueriable<EmailRecipientInGroup> emailRecipientInGroupsQuery =
    from g in dc.EmailRecipientInGroups
    where !g.UserEmailRecipientGroup.IsDeleted
    select g;

IQueriable<ZeekUser> zeekUsersQuery =
    from z in db.ZeekUsers
    select z;

var query = from s in userContactsQuery
         join g in emailRecipientInGroupsQuery on s.UserEmailRecipient.RID equals g.RID
         join zk in zeekUsersQuery on s.UserID equals zk.UserId
         select new { s = s, g = g, zk = zk });

I'd use var myself but this is only to show that most of your query can be typed.

You might want to consider inserting your other conditions somewhere in the middle of the query instead of the end.

Upvotes: 0

peter
peter

Reputation: 15119

var as such will be defined as an actual type during runtime and can be used normally. However your var is an IQueryable of an Anonymous type, this won't work. To be able to pass them to other functions you can either use a Tuple or have to define the class yourself and use it in the linq query.

Upvotes: 1

Scott Chamberlain
Scott Chamberlain

Reputation: 127593

Your var is a Annonmous Type, you can't pass it out of the scope of the function (Well you can with dynamic or ExpandoObject, but it is not recommended).

If you want to pass the result to another method you will need a concrete type to do it.

//Elsewhere in your code
class Result
{
    public usercontact UserContact {get; set;}
    public EmailRecipientinGroup Group {get; set;}
    public Zeekuser ZeekUser {get; set;}
}



var query = (from s in dc.UserContacts
             join g in dc.EmailRecipientInGroups on s.UserEmailRecipient.RID equals g.RID
             join zk in dc.ZeekUsers on s.UserID equals zk.UserId
             where s.aspnet_User.LoweredUserName.Equals(strUserName.ToLower())
             && !g.UserEmailRecipientGroup.IsDeleted
             && !s.UserEmailRecipient.IsDeleted
             select new Result{ UserContact = s, Group  = g, ZeekUser = zk }); //Only this line changed.

query will now be a IQueryable<Result> which you can pass around to other functions.

Upvotes: 5

Related Questions