简体   繁体   English

如何将var类型作为参数传递给另一种方法

[英]How to pass var type as parameter to another method

i have below Linq query in my code 我的代码中有下面的Linq查询

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 其中dc是Linq to SQL的DataContext

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. 因此,我正在考虑编写一个新的私有方法,该方法可以在所有3个函数的上述行之后以查询作为参数进行调用,并获取结果,而不是每次都重复代码。 But from internet i found that var type can not be passed as parameter. 但是从互联网上我发现var类型不能作为参数传递。

Here is my Intellisense from Visual Studio when I hover mouse over the var keyword before query word 这是我将鼠标悬停在查询词之前的var关键字上时来自Visual Studio的Intellisense

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

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). 您的var是一个匿名类型,您不能将其传递到函数范围之外(可以使用dynamicExpandoObject ,但不建议这样做)。

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. 现在, query将是IQueryable<Result> ,您可以将其传递给其他函数。

var as such will be defined as an actual type during runtime and can be used normally. var将在运行时定义为实际类型,并且可以正常使用。 However your var is an IQueryable of an Anonymous type, this won't work. 但是,您的var是一个Anonymous类型的IQueryable ,这将无法工作。 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. 为了能够将它们传递给其他函数,您可以使用Tuple或必须自己定义类并在linq查询中使用它。

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." 正如其他人已经说过的那样, “在方法范围内声明的变量可以具有隐式类型var。对隐式类型的局部变量进行强类型化,就像您自己声明了该类型一样,但是编译器确定该类型。”

It is, however, the only way to declare variables of types that are, or involve, anonymous types . 但是,这是声明属于或涉及匿名类型的类型的变量的唯一方法。

Now to the LINQ part. 现在到LINQ部分。 You can look at LINQ queries as database view definitions (they are only executed when enumerated) but with a great benefit: they are composable. 您可以将LINQ查询视为数据库视图定义(它们仅在枚举时执行),但有很大的好处:它们是可组合的。

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. 我会自己使用var但这只是为了表明您可以查询大多数查询。

You might want to consider inserting your other conditions somewhere in the middle of the query instead of the end. 您可能需要考虑将其他条件插入查询的中间而不是结尾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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