我今天正在浏览.NET Core源代码树,并在以下模式中运行System.Collections.Immutable.ImmutableArray<T>:
T IList<T>.this[int index]
{
get
{
var self = this;
self.ThrowInvalidOperationIfNotInitialized();
return self[index];
}
set { throw new NotSupportedException(); }
}
Run Code Online (Sandbox Code Playgroud)
这种模式(存储this在局部变量中)似乎始终在此文件中应用,this否则将在同一方法中多次引用,但在仅引用一次时则不会.所以我开始思考这样做的相对优势是什么; 在我看来,优势可能与性能有关,所以我走了这条路线更远......也许我忽略了别的东西.
为" 本地存储"模式发出的CILthis似乎看起来像a ldarg.0,然后ldobj UnderlyingType,stloc.0以便后来的引用来自ldloc.0而不是ldarg.0像只使用this多次一样.
对于C#-to-CIL转换或者JITter寻找机会为我们优化这一点可能ldarg.0要慢得多ldloc.0,但是不够,这样在C#代码中随时编写这种奇怪的模式更有意义否则我们会ldarg.0在struct实例方法中发出两条指令?
考虑一个针对以下框架的.NET类库:
让我们不要立即担心为什么这是目标框架的确切列表.
假设所有目标框架中的外部API是相同的,但每个单独的目标框架都有一些该框架独有的代码,我如何正确编写涵盖所有目标框架代码的单元测试?
我正在运行Visual Studio 2017社区.
我已经在GitHub上制作了一个随时可用的最小样本,我到目前为止发现的可能是我现在能做的最好的:https://github.com/airbreather/MultiTargetDemo,但这不是感觉这是正确的做法.一些缺陷:
ReferringTargetFrameworkForProjectReferences.
System.IO.FileSystem)上面链接的库只有一个公共类,其上只有一个公共实例方法.该方法在合同上有义务只返回32位整数值3,但它在每个目标上计算3一个实质上不同的方式.显然,实际用例围绕实现更多"有趣"的方法,但这足以进行对话.
此外,请注意该库中的测试类实际上使用了一些在所有目标平台上都不可用的东西:System.Threading.Tasks.Task<TResult>在.NET Framework 2.0上不可用...这可以作为测试本身可能的任何内容的代理.用于其自身目的,可能不一定在正在测试的目标框架中可用.
实际用例是NetTopologySuite,它已经针对多个完整框架平台和一些PCL; 有一个长达一年的问题,要求它使用.NET Core.我一直在努力尝试将这种情况发生在一个月左右,我终于遇到了这个问题.
我发现了另一个问题:使用.NET Core和xUnit同时针对几个框架的单元测试代码,这确实与此类似.出于以下几个原因,这是不同的:
project.json).这个问题是指VS2017时代的非预览工具与漂亮的.csproj文件和所有.TargetFrameworks像test1;test2;test3;test4;test5,然后迫使TargetFrameworkIdentifier+ TargetFrameworkVersion到.NETFramework + 4.6,但我并没有多少成功的(它试图抓住时失败xunit包).我还没有尝试 ….net unit-testing .net-core visual-studio-2017 .net-standard
System.Runtime.Caching.MemoryCache是.NET Framework(版本4+)中的一个类,它使用字符串作为键来缓存内存中的对象.除了System.Collections.Generic.Dictionary <string,object>之外,这个类还有各种各样的铃声和口哨声,可以让你配置缓存增长到多少(绝对或相对术语),设置不同的过期策略不同的缓存项目,以及更多.
我的问题与记忆限制有关.MSDN上的所有文档似乎都没有令人满意地解释这一点,并且Reference Source上的代码相当不透明.很抱歉将所有这些都写成一个"问题",但我无法弄清楚如何将一些问题纳入他们自己的问题,因为他们只是对一个整体问题的不同观点:"你如何调和惯用的C# /.NET有一个通常有用的内存缓存的概念,它有可配置的内存限制几乎完全在托管代码中实现?"
Player. Player有一些特定于玩家的状态被封装在一个public PlayerStateData PlayerState { get; }属性中,该属性封装了玩家正在看的方向,他们持有的链轮数等等,以及对整个游戏状态的引用public GameStateData GameState { get; },可以用来回到游戏(更大)状态来自只知道玩家的方法.PlayerState以及GameState何时考虑缓存贡献的大小?GameState仅仅因为5个玩家被缓存而将大小的贡献大小乘以5 是愚蠢的......但是再一次,一个可能的实现可能就是这样,并且很难计算PlayerState而不计算GameState.我自己的研究使我SRef.cs,我放弃了在试图让后了解这里,后来导致这里.猜测所有这些问题的答案将围绕寻找和冥想最终填充存储在该句柄中的INT64的代码.
很抱歉标题令人困惑,但我想不出更好的方法来解释它。
最近在浏览源码BitConverter时,发现了一段奇怪的代码:
public static unsafe int ToInt32(byte[] value, int startIndex)
{
fixed (byte* pbyte = &value[startIndex])
{
if (startIndex % 4 == 0) // data is aligned
return *((int*)pbyte);
else
{
if (IsLittleEndian)
{
return (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24);
}
else
{
return (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3)); …Run Code Online (Sandbox Code Playgroud) 我正在寻找类似于这样的签名的东西:
static bool TryCreateFile(string path);
Run Code Online (Sandbox Code Playgroud)
这需要避免跨线程,进程甚至访问相同文件系统的其他机器的潜在竞争条件,而不要求当前用户拥有超出其所需的任何权限File.Create.目前,我有以下代码,我不是特别喜欢:
static bool TryCreateFile(string path)
{
try
{
// If we were able to successfully create the file,
// return true and close it.
using (File.Open(path, FileMode.CreateNew))
{
return true;
}
}
catch (IOException)
{
// We want to rethrow the exception if the File.Open call failed
// for a reason other than that it already existed.
if (!File.Exists(path))
{
throw;
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
还有另一种方法可以做到这一点,我错过了吗?
这适用于以下帮助器方法,旨在为目录创建"下一个"顺序空文件并返回其路径,再次避免跨线程,进程甚至访问同一文件系统的其他计算机的潜在竞争条件.所以我想一个有效的解决方案可能涉及到不同的方法:
static string GetNextFileName(string directoryPath)
{ …Run Code Online (Sandbox Code Playgroud)