在C#中使用lambda表达式或匿名方法时,我们必须警惕对修改后的闭包陷阱的访问.例如:
foreach (var s in strings)
{
query = query.Where(i => i.Prop == s); // access to modified closure
...
}
Run Code Online (Sandbox Code Playgroud)
由于修改后的闭包,上面的代码将导致Where
查询中的所有子句都基于最终值s
.
正如这里所解释的那样,这是因为上面循环中s
声明的变量foreach
在编译器中被翻译成这样:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
Run Code Online (Sandbox Code Playgroud)
而不是像这样:
while (enumerator.MoveNext())
{
string s;
s = enumerator.Current;
...
}
Run Code Online (Sandbox Code Playgroud)
正如这里所指出的,在循环外声明变量没有性能优势,在正常情况下,我能想到这样做的唯一原因是你计划在循环范围之外使用变量:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
var finalString = s;
Run Code Online (Sandbox Code Playgroud)
但是,foreach
循环中定义的变量不能在循环外使用: …
我发现LINQPad在回答C#或VB.NET的StackOverflow问题时非常有用.它允许我编写一些快速代码,运行它,并且(如果我想的话)看到一个格式良好的结果转储.这样我可以确定我发布的代码实际运行.到目前为止,我还没有看到任何可以用Java实现相同结果的东西.那里有类似的东西吗?
我不是在寻找查询数据源的东西 ; 我只想要一个轻量级的IDE.这些是我特别感兴趣的功能:
我有一个应用程序,允许用户输入他们工作的时间,我正在尝试为此构建一个良好的报告,利用LINQ to Entities.因为每个TrackedTime
都TargetDate
只是a的"Date"部分DateTime
,所以按用户和日期对时间进行分组相对简单(为简单起见,我省略了"where"子句):
var userTimes = from t in context.TrackedTimes
group t by new {t.User.UserName, t.TargetDate} into ut
select new
{
UserName = ut.Key.UserName,
TargetDate = ut.Key.TargetDate,
Minutes = ut.Sum(t => t.Minutes)
};
Run Code Online (Sandbox Code Playgroud)
由于该DateTime.Month
属性,按用户分组和Month只是稍微复杂一点:
var userTimes = from t in context.TrackedTimes
group t by new {t.User.UserName, t.TargetDate.Month} into ut
select new
{
UserName = ut.Key.UserName,
MonthNumber = ut.Key.Month,
Minutes = ut.Sum(t => t.Minutes)
};
Run Code Online (Sandbox Code Playgroud)
现在是棘手的部分.是否有可靠的方式按周分组?我根据对类似LINQ to SQL问题的响应尝试了以下内容:
DateTime firstDay = …
Run Code Online (Sandbox Code Playgroud) 我们的团队使用自定义规则集的代码分析功能,如果我们忘记对方法参数执行null检查,则会导致构建失败.
但是,现在我们创建一个新的.NET Core项目时,它看起来并不像Code Analysis这些新项目的功能."项目属性"区域中没有用户界面,并且按照此处的建议向项目添加自定义规则集只会影响StyleCop Analyzers(SAxxxx
规则).
有没有办法CAxxxx
在.NET Core项目中启用Code Analysis()规则?
玩弄C#7的Local Functions,我最终得到了一些有趣的行为.考虑以下程序:
public void Main()
{
Console.WriteLine("Entered Main");
DoSomething("");
}
private void DoSomething(object obj)
{
Console.WriteLine("Entered DoSomething");
Generic((dynamic)obj);
GenericLocal(obj);
GenericLocal((dynamic)obj); // This breaks the program
void GenericLocal<T>(T val) => Console.WriteLine("GenericLocal");
}
private void Generic<T>(T val) => Console.WriteLine("Generic");
Run Code Online (Sandbox Code Playgroud)
这会产生:
进入Main
......然后抛出一个BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
.堆栈跟踪:
at UserQuery.DoSomething(Object obj)
at UserQuery.Main()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, …
Run Code Online (Sandbox Code Playgroud) 我意识到我没有给大多数人提供足够的信息来阅读我的想法并了解我的所有需求,所以我对此进行了一些改动.
假设我有一个像这样的类的项目列表:
public class Thing
{
int Foo;
int Bar;
string Baz;
}
Run Code Online (Sandbox Code Playgroud)
我想根据Foo的值对Baz字符串进行分类,然后是Bar.对于Foo和Bar值的每种可能组合,最多只有一个Thing,但我不保证每个值都有一个值.将它概念化为表的单元信息可能有所帮助:Foo是行号,Bar是列号,Baz是在那里找到的值,但不一定存在每个单元的值.
IEnumerable<Thing> things = GetThings();
List<int> foos = GetAllFoos();
List<int> bars = GetAllBars();
Dictionary<int, Dictionary<int, string>> dict = // what do I put here?
foreach(int foo in foos)
{
// I may have code here to do something for each foo...
foreach(int bar in bars)
{
// I may have code here to do something for each bar...
if (dict.ContainsKey(foo) && dict[foo].ContainsKey(bar))
{
// I want to …
Run Code Online (Sandbox Code Playgroud) 我有一个触发器,无论何时输入值,它都会自动将给定条目的CreationDate和ModifiedDate设置为当前UTC时间.(之后CreationDate将保持不变,而ModifiedDate将通过另一个触发器在每次更新时更新).
我想确保插入且永不更新的项目对于CreationDate和ModifiedDate具有完全相同的值,所以我使用了这样的变量:
DECLARE @currentTime DATETIME
SELECT @currentTime = GETUTCDATE()
UPDATE dbo.MyTable SET CreationDate = @currentTime, ModifiedDate = @currentTime
...
Run Code Online (Sandbox Code Playgroud)
在我的命令式编程心态中,我假设这可以防止GETUTCDATE()
被调用两次,并可能产生稍微不同的结果.这实际上是必要的吗?如果没有,这将是更昂贵,更便宜,或与以下代码完全相同?
UPDATE dbo.MyTable SET CreationDate = GETUTCDATE(), ModifiedDate = GETUTCDATE()
...
Run Code Online (Sandbox Code Playgroud) 我们正在使用StackOverflow中的此代码片段来生成一个任务,该任务在第一个任务集合成功完成后立即完成.由于其执行的非线性特性,async/await
实际上并不可行,因此此代码使用ContinueWith()
.它没有指定的TaskScheduler,虽然,这一个号码 的 来源都提到可能是危险的,因为它使用TaskScheduler.Current
时,大多数开发人员通常希望TaskScheduler.Default
从延续的行为.
流行的智慧似乎是你应该总是将一个显式的TaskScheduler传递给ContinueWith.但是,我还没有看到关于何时最合适的TaskScheduler的明确解释.
什么是最好TaskScheduler.Current
进入的情况的具体例子ContinueWith()
,而不是TaskScheduler.Default
?做出这个决定时是否有遵循的经验法则?
对于上下文,这是我所指的代码片段:
public static Task<T> FirstSuccessfulTask<T>(IEnumerable<Task<T>> tasks)
{
var taskList = tasks.ToList();
var tcs = new TaskCompletionSource<T>();
int remainingTasks = taskList.Count;
foreach(var task in taskList)
{
task.ContinueWith(t =>
if(task.Status == TaskStatus.RanToCompletion)
tcs.TrySetResult(t.Result));
else
if(Interlocked.Decrement(ref remainingTasks) == 0)
tcs.SetException(new AggregateException(
tasks.SelectMany(t => t.Exception.InnerExceptions));
}
return tcs.Task;
}
Run Code Online (Sandbox Code Playgroud) 我正在创建一个包含两列的表,我想自动增加.一列是主键,因此我在其上使用IDENTITY关键字.另一列将用于跟踪表中用户定义的项目"排序顺序".每当用户移动项目时,其"排序顺序"将交换值与另一个元素的值.但是,当项目插入表格时,应始终自动为插入的项目分配高于表格中任何其他值的排序顺序值.这是表创建脚本的简化版本:
CREATE TABLE [AnswerRow] (
[AnswerRowId] [int] IDENTITY(1,1) NOT NULL,
[SortOrder] [int] NOT NULL,
[IsDeleted] [bit] NOT NULL CONSTRAINT [DF_AnswerRow_IsDeleted] DEFAULT 0,
CONSTRAINT [PK_AnswerRow] PRIMARY KEY CLUSTERED ([AnswerRowId] asc)
)
Run Code Online (Sandbox Code Playgroud)
使SortOrder
列自动递增的最佳方法是什么AnswerRowId
(但仍然能够在之后修改排序顺序值)?
我希望没有人会考虑这个问题。我即将开始在Jupyter笔记本中探索使用C#内核。我看到有几种选择,有些似乎已经过时。我对探索所有内容并没有真正的兴趣,我只想对演示有足够的了解。目的是评估这一点,以教授C#编程中的中学课程-我们现在仅使用Visual Studio,并且我们认为需要一些更有针对性的并且可能适合某些自动化的东西。
问题:在可用的各种替代方法中,应避免使用哪些?哪些似乎使用较少的问题?
我目前使用Jupyter进行Python开发,因此至少我对这项技术有所了解并且可以编写笔记本。