我最近在使用一个DateTime对象,并写了这样的东西:
DateTime dt = DateTime.Now;
dt.AddDays(1);
return dt; // still today's date! WTF?
Run Code Online (Sandbox Code Playgroud)
intellisense文档AddDays()说它增加了一天的日期,它没有 - 它实际上返回添加了一天的日期,所以你必须写如下:
DateTime dt = DateTime.Now;
dt = dt.AddDays(1);
return dt; // tomorrow's date
Run Code Online (Sandbox Code Playgroud)
这个曾经多次咬过我,所以我认为编制最糟糕的C#陷阱会很有用.
我遇到了一个关于C#的有趣问题.我有如下代码.
List<Func<int>> actions = new List<Func<int>>();
int variable = 0;
while (variable < 5)
{
actions.Add(() => variable * 2);
++ variable;
}
foreach (var act in actions)
{
Console.WriteLine(act.Invoke());
}
Run Code Online (Sandbox Code Playgroud)
我希望它输出0,2,4,6,8.但是,它实际输出5个10.
似乎是由于所有操作都涉及一个捕获的变量.结果,当它们被调用时,它们都具有相同的输出.
有没有办法解决这个限制,让每个动作实例都有自己的捕获变量?
这显然不是看起来像它不会是一个最佳实践.有人可以解释为什么它不是最佳实践或如何工作?任何提供解释的书籍或文章将不胜感激.
//The constructor
public Page_Index() {
//create a local value
string currentValue = "This is the FIRST value";
//use the local variable in a delegate that fires later
this.Load += delegate(object sender, EventArgs e) {
Response.Write(currentValue);
};
//change it again
currentValue = "This is the MODIFIED value";
}
Run Code Online (Sandbox Code Playgroud)
输出的值是第二个值"已修改".编译器魔术的哪个部分使这个工作?这跟跟踪堆上的值并稍后再次检索它一样简单吗?
[编辑]:鉴于一些评论,改变原来的一些句子......
假设我的对象处于完美的工作状态(即TDD让我觉得它们有效).
我有一个我这样创建的列表(正确缩进除外):
var result = from v in vendors
from p in v.Products
orderby p.Name
select p;
Run Code Online (Sandbox Code Playgroud)
这有效 - 我从所有供应商处获得所有产品.
现在我有一个条件列表,由用户在运行时构建.让我们应用它们:
foreach (Attribute a in requiredAttributes)
{
result = result.Where(p => p.Attributes.Contains(a));
}
Run Code Online (Sandbox Code Playgroud)
这可能是原始的,但我认为它有用.但是,在完成此foreach循环之后,当您枚举"result"时,它将包含其Attributes属性(也是集合)中具有requiredAttributes集合的LAST属性的所有产品.
对我来说,这种气味就像"a"被覆盖在某个地方,每次旅行通过循环,只有最后一个适用.
如果没有以某种方式将扩展方法写入IEnumerable,称为ContainsAll(IEnumerable)或其他类似的东西,我怎么能实现我想要的,这基本上是一个逻辑AND,只给我那些具有所有必需属性的产品?
作为一个相当初级的开发人员,我遇到了一个问题,突出了我缺乏经验和我的知识漏洞.如果这里的序言太长,请原谅.
我发现自己正处于一个涉及我需要学习一些新的(对我而来)技术的项目,包括LINQ(对象来说是OBJECTS和XML).我在这一点上所读到的一切都表明,要利用LINQ,我需要完全理解以下内容(代理,匿名方法和Lambda表达式).
好的,所以现在很有趣.我曾经使用过.NET事件模型,但是我已经消费了代表,但是大多数细节都被隐藏了(感谢Microsoft!).我理解在基本层面上,委托实例是指向方法的指针(我知道这是一个过度简化的过程).
据我所知,匿名方法本质上是一种内联的未命名方法,通常(如果不是唯一的话)创建为委托的目标.
我也理解lambdas以不同的方式用于简化语法,可用于将简单的匿名方法指向委托.
请原谅我,如果我的任何描述都在这里,那么这就是我理解这些主题的基本层面.
所以,挑战:
如果我对这些项目的了解甚至更接近,至少在基本水平上有人能告诉我吗?我不是在寻找复杂的深奥细节,只是基础(现在).
在项目中应用LINQ以达到合理的效果之前,我需要在多大程度上真正理解这些概念?我想完全理解它,并愿意花时间.在我需要完成一些工作之前,我可能没有时间完全理解所有这些东西.
任何人都可以向我指出一些解释这些主题的好文章,并将它们应用到"真实世界"的例子中,这样我就可以了解这些主题和应用的基础知识吗?我的意思是现实世界,我是如何在"客户和发票"的背景下使用它而不是抽象的"矢量和形状"或"动物和奶牛".出于演示目的,这种情况可能有点人为,但希望不是严格的学术性的.我在网上和书中找到了一些例子,但似乎很少有"简单英语"的解释.
提前感谢您的耐心,时间和专业知识.
我在我的Entity Framework repo上创建了这个搜索方法:
public IEnumerable<Person> GetPersonsWithFilter(string filter)
{
var items =
filter.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var query = _personRepo.All(); // Return IQueryable<Person>
foreach (var item in items)
{
query = query.Where(i => i.SearchName.Contains(item.ToLower()));
}
query.TraceSql(i => Logger.Error(i));
return query.Take(50);
}
Run Code Online (Sandbox Code Playgroud)
TraceSql输出生成的sql.如果我的过滤器是"John Landheer",则正确生成sql:
SELECT [Extent1].[PersonId] AS [PersonId] // Other fields deleted for readability
FROM [dbo].[Person] AS [Extent1]
WHERE
(( CAST(CHARINDEX(LOWER(@p__linq__0), [Extent1].[SearchName]) AS int)) > 0)
AND
(( CAST(CHARINDEX(LOWER(@p__linq__1), [Extent1].[SearchName]) AS int)) > 0)
Run Code Online (Sandbox Code Playgroud)
但是,参数是相同的:@p_ linq _0 ='landheer'和@p_ linq …
采取下面的代码,改编自这个问题:
//Borrowed from another question because its a simpler example of what happened to me.
IEnumerable<char> query = "Not what you might expect";
foreach(char vowel in "aeiou")
{
query = query.Where(c => c != vowel);
}
foreach (char Output in query)
{
System.Out.WriteLine(Output);
}
Run Code Online (Sandbox Code Playgroud)
这只会从查询字符集中删除"u".核心问题与第二个foreach c中的Where子句中的变量未被评估的事实有关.我的问题是:
1)为什么第一个foreach生成的委托不会捕获c构建的每个值?是否有一些情况我不知道哪里不是理想的行为?
2)如果它没有捕获值c,那么当查询实际运行时,该值是否仍然在第二个foreach的范围内?在我看来,如果它没有存储传入的变量的值,那么尝试解析第二个foreach的语句将失败,因为该变量c显然超出了范围.
我不明白为什么'在范围内使用我们在这个变量上看到的最后一个值'对于这种情况是一个很好的设计决策,并且希望有人可以对这个问题有所了解.
最近我在深度阅读了C#,它教会了我关于lambda表达式的知识,我一直在使用它来将数据传递给点击事件,例如:
image.MouseDown+=(o ,e)=>MethodToDoSomething(DataNeededForAction);
Run Code Online (Sandbox Code Playgroud)
现在问题是在foreach循环中使用变量捕获(感谢Jon Skeet使这部分非常清楚:),当初始化具有我订阅的事件的几个对象时,我通常遇到变量捕获的问题.考虑以下示例:
foreach (var game in GamesCollection)
{
Image img = new Image();
img.Width = 100;
img.MouseDown+=(o,e) => MyMethod(game.id);
}
Run Code Online (Sandbox Code Playgroud)
为了避免在这种情况下捕获,我必须添加一些变量来分配游戏,然后将该变量传递给方法,这会产生额外的不清楚的代码,主要是额外的混乱.有没有办法绕过这个?什么东西至少看起来更干净?
Thx,Ziv
嗨,谢谢,提前,
我正在尝试实现一个搜索功能,其中结果可以填充到Gridview.我正在使用LINQ在c#中查询我的数据库.
我想弄清楚的问题是,如果用户想要搜索具有多个搜索词的多个列/字段,那么我该怎么做?因此,如果我搜索具有这3个字段的表,并且我有一些数据,例如:
Run Code Online (Sandbox Code Playgroud)firstName | lastname | players#
- 迈克尔| 乔丹| 12
- 迈克尔| 乔丹| 24
- 迈克尔| 乔丹| 45
- 德安德鲁 - | 乔丹| 6
- 杰罗姆| 乔丹| 44
- 乔丹| 火花| 88
现在,如果我搜索乔丹,我会得到一切:
如果我搜索迈克尔乔丹,我应该得到第1,2,3排.
如果我搜索乔丹斯帕克斯88比我应该排#6回来.
所以我的问题是我不知道搜索词可能在表中的哪个位置,所以我必须搜索所有列/字段.在我当前的代码中,我有一些东西,我遍历每个列/字段名称并使用包含()然后|| ("或"),但它只适用于1个搜索词.
是否有一种优雅而简单的方法来搜索和过滤整个linq表,以便最小化列表?从那里我将把结果添加到数据源然后绑定它.
@Sphinxxx我使用的是典型的gridview.它看起来像这样:
<asp:GridView ID="GridView" runat="server" AllowSorting="True" PagerStyle-Mode="NumericPages"
AutoGenerateColumns="false" Width="100%" CssClass="gridView" OnPageIndexChanging="GridView_PageIndexChanging"
AllowPaging="True" DataKeyNames="idPlayersList" OnRowCommand="GridView_RowCommand"
OnRowEditing="GridView_RowEditing" OnRowCancelingEdit="GridView_CancelEditRow"
OnRowUpdating="GridView_UpdateRow" OnRowDataBound="GridView_RowDataBound">
<RowStyle CssClass="rowStyle"></RowStyle>
<asp:BoundField DataField="FirstName" HeaderText="First Name" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" SortExpression="LastName" />
<asp:BoundField DataField="PlayersNumber" HeaderText="Players Number" SortExpression="PlayersNumber" />
<asp:TemplateField HeaderText="Team" SortExpression="Team">
<EditItemTemplate>
<asp:DropDownList ID="ddlTeam" runat="server" CssClass="dropdown" AutoPostBack="True" …Run Code Online (Sandbox Code Playgroud) 我遇到了一个LINQ to SQL非常奇怪的场景.我想知道我做错了什么.但我认为这是一个真正的可能性,这是一个错误.
下面粘贴的代码不是我的真实代码.这是我使用Northwind数据库为这篇文章创建的简化版本.
一点背景:我有接受一个的方法IQueryable的Product和"过滤器对象"(我将在一分钟内描述).它应该运行一些"Where"扩展方法IQueryable,基于"过滤器对象",然后返回IQueryable.
所谓的"过滤器对象"是System.Collections.Generic.List这种结构的匿名类型:{ column = fieldEnum, id = int }
fieldEnum是Products表格的不同列的枚举,我可能希望用于过滤.
而不是进一步解释我的代码如何工作,如果你只是看看它会更容易.这很容易理解.
enum filterType { supplier = 1, category }
public IQueryable<Product> getIQueryableProducts()
{
NorthwindDataClassesDataContext db = new NorthwindDataClassesDataContext();
IQueryable<Product> query = db.Products.AsQueryable();
//this section is just for the example. It creates a Generic List of an Anonymous Type
//with two objects. In real life I get the same kind of collection, but it …Run Code Online (Sandbox Code Playgroud)