我一直在努力理解Scott Wlaschin在RoP文章中的代码:
http://fsharpforfunandprofit.com/posts/railway-oriented-programming-carbonated/
他在F#中使用了Choice1Of2和Choice2Of2类型.当我遇到以下情况时,我试图通过调试它们来研究如何利用这些东西:
module TestModule
open Microsoft.VisualStudio.TestTools.UnitTesting
// generic union type (like Choice1Of2, I think)
type Things<'a> =
| Thing of 'a
// explicit union type (for comparison)
type Numbers =
| Integer of int
[<TestClass>]
type Tests() =
// method to make a Choice1Of2 (from the article)
let makeChoice (a : string) : Choice<string, 'a> =
Choice1Of2 a
[<TestMethod>]
member public this.WhyYouNoHaveItemValueAndStuff() =
let choice1 = Thing "test" // debug = Thing "this"
let choice2 = Integer 3 …Run Code Online (Sandbox Code Playgroud) 我一直在寻找能够提供同一类的线程安全和不安全版本的模式.这方面的技术方面非常明显.我想是希望找到命名/访问约定等...
所以我在'Systems.Collections'命名空间中到处找到这个模式:
public class WhatEv
{
private class SyncWhatEv : WhatEv
{
// overrides IsSyncronized = true
// overrides whatever else to make it thread safe
}
public virtual bool IsSynchronized
{
get { return false; }
}
public static WhatEv Synchronized(WhatEv whatEv)
{
return new SyncWhatEv(whatEv);
}
}
Run Code Online (Sandbox Code Playgroud)
有许多类实现了这个:HashTable,Queue,ArrayList,Stack等......我理解继承.但是为什么要把它变成一个私有的嵌套类,并让用户跳过一个环节去实现呢?这样做有什么好处吗?
这些类型的方法一直困扰着我.没有挖掘代码,我不知道这个字典中的键或子值应该是什么.我已经做了大约一千次,我敢肯定.但它一直困扰着我,因为它缺乏如此多的信息.
IDictionary<int,HashSet<int>> GetExportedCharges()
{
...
}
void GetVisitStatuses(IDictionary<int,HashSet<int>> exportedCharges)
{
...
}
Run Code Online (Sandbox Code Playgroud)
将材料放在字典中是有意义的,但所有IDictionary方法都有非常抽象的参数.我想我可以创建一个新类,实现IDictionary,并重命名所有参数.这看起来有点矫枉过正.希望c#有一个'typdef'指令.
你怎么避免像这样回复词典?或者你完全避免这种情况?
我似乎无法找到足够直接的答案.我无法理解为什么有人会选择"Get"而不是"Get2".
除非有技术原因,否则我总是选择"Get2".这样我的代码可以在应用程序的io边缘异步,而不是在任何地方.有人可以帮助我理解为什么你会选择一个而不是另一个.还是两者的情况?我理解在C#中async/await的线程和执行模型,但不知道如何确保我在f#中做同样的事情.
member this.Get (url : string) : Async<'a> = async {
use client = new HttpClient()
let! response = client.GetAsync(url) |> Async.AwaitTask
response.EnsureSuccessStatusCode() |> ignore
let! content = response.Content.ReadAsStringAsync() |> Async.AwaitTask
return this.serializer.FromJson<'a>(content)
}
member this.Get2 (url : string) : 'a =
use client = new HttpClient()
let response = client.GetAsync(url) |> Async.AwaitTask |> Async.RunSynchronously
response.EnsureSuccessStatusCode() |> ignore
let content = response.Content.ReadAsStringAsync() |> Async.AwaitTask |> Async.RunSynchronously
this.serializer.FromJson<'a>(content);
Run Code Online (Sandbox Code Playgroud) 根据本文,我有一个策略问题:
https://docs.microsoft.com/zh-cn/azure/cosmos-db/partition-data
A)我是否应该对分区键进行结构设计,以使查询(理想情况下)最终集中在一个分区上?例如,PartitionKey = CustomerId
要么
B)文档是否仍然有效地处理跨越多个(许多)分区的查询?例如。PartitionKey =“客户编号+上下文名称+类型名称”
我们目前已经实现了“ A”,但是由于本文中引用了以下内容,因此我们已经讨论了“ B”:
最好的做法是使分区键具有许多不同的值(最小为100s-1000s)。
强调“至少”。我们的CustomerIds不能产生超过2-300个分区键。如果我们向其中添加更多信息(“ B”),则知道一个查询可能会命中30-50个分区(即专门添加“ TypeId”)
SELECT * FROM c
WHERE(MyPartition = "1+ContextA+TypeA"
OR MyPartition = "1+ContextA+TypeB"
OR MyPartition = "1+ContextA+TypeC"
...)
AND <some other conditions>
Run Code Online (Sandbox Code Playgroud)
本文中介绍的方案似乎假定客户或用户将生成大量密钥。这对我们来说不是真的。
我刚读完"使用C#进行专业测试驱动开发",并一直试图找到一种方法来实现我的代码100%的覆盖率.这一切都很好,直到我找到一个充满了这样实现的方法的存储库类:
public IEnumerable<MyDataContract> LoadConditional(bool isCondition)
{
const string QUERY = @"SELECT ...fields... FROM MyData WHERE [IsCondition] = @IsCondition";
return DataAccessor.ReadMyContracts(QUERY, isCondition); // something, something...
}
Run Code Online (Sandbox Code Playgroud)
我一直在考虑这个问题,并且无法在互联网上找到直接回答这个问题的答案.
我阅读的内容表明SQL相关业务将存在于另一个程序集中.我不需要这个,但不相信我应该去那里.从代码覆盖的角度来看,这是一个非常肤浅的变化.
我已经读过你可以为你的单元测试连接数据库(我以前做过).但这很好......我不知道,感觉不对.测试很慢并且维护量显着增加.
我的直觉是没有我提到的最后一点,这种方法不能进行单元测试.我该如何看待这个问题?
在Visual Studio 2012中,为什么此代码在交互模式下如此快速地执行,并且在作为控制台应用程序运行时如此缓慢?我有一台快速计算机,但在运行时功能完成之前我可以数到4,在交互式工作室窗口中甚至不能达到1.
令我烦恼的另一部分是,当我测试其他人的Project Euler#4的F#代码时,它们都运行良好.所以它让我相信这段代码有一些不是最优的.(它也很整洁干净>:P)
let reverse(digits:string) =
digits.ToCharArray() |> Array.rev |> System.String.Concat
let isPalindrome(number:int) =
let text = number.ToString()
if text.Length % 2 = 0 then
text = reverse(text)
else
false
let palindromes(floor:int, ceiling:int) =
seq {
for i1 = floor to ceiling do
for i2 = floor to ceiling do
let result = i1 * i2
if isPalindrome result then
yield result
}
let run =
palindromes(100, 999)
|> Seq.max
Run Code Online (Sandbox Code Playgroud)
摘要
为了后人,我将列出最有效的性能变化.
它仍然没有解释我的原始问题.但现在它可以忽略不计,很难说服自己花更多的时间在上面.我感谢大家的投入.谢谢!