小编Dan*_*iel的帖子

使用循环引用设计的不可变类的批判,以及更好的选项

我有一个工厂类,用于创建带有循环引用的对象.我希望它们也是不变的(在某种意义上说).所以我使用以下技术,使用一种类型的闭包:

[<AbstractClass>]
type Parent() =
  abstract Children : seq<Child>
and Child(parent) =
  member __.Parent = parent

module Factory =

  let makeParent() =
    let children = ResizeArray()
    let parent = 
      { new Parent() with
        member __.Children = Seq.readonly children }
    [Child(parent); Child(parent); Child(parent)] |> children.AddRange
    parent
Run Code Online (Sandbox Code Playgroud)

我比一种internal AddChild方法更喜欢这个,因为它有更强的不变性保证.也许它是神经质的,但我更喜欢关闭访问控制.

这个设计有什么陷阱吗?有没有更好的,也许不那么繁琐的方法来做到这一点?

f# closures class-design circular-dependency immutability

6
推荐指数
1
解决办法
507
查看次数

只读与自动(只读)属性

使用只读属性之间有区别吗:

type T(arg) =
  member x.M = arg
Run Code Online (Sandbox Code Playgroud)

并使用自动实现的属性:

type T(arg) =
  member val M = arg
Run Code Online (Sandbox Code Playgroud)

假设arg没有副作用?有理由偏爱一个吗?

f# f#-3.0

6
推荐指数
1
解决办法
754
查看次数

共享范围等待

我有一个UserScope类似于TransactionScope它的类,即它将当前状态存储在本地线程中.这当然不适用于调用await,TransactionScope直到TransactionScopeAsyncFlowOption.NET 4.5.1中都没有添加.

我可以使用什么替代线程本地,以便UserScope在单线程和多线程场景中使用相同的?(如果我安装了4.5.1,我会反编译以查看TransactionScope它是如何做的.)这是我所拥有的简化版本:

class User {
    readonly string name;

    public User(string name) {
        this.name = name;
    }

    public string Name {
        get { return this.name; }
    }
}

class UserScope : IDisposable {
    readonly User user;

    [ThreadStatic]
    static UserScope currentScope;

    public UserScope(User user) {
        this.user = user;
        currentScope = this;
    }

    public static User User {
        get { return currentScope != null ? currentScope.user : null; …
Run Code Online (Sandbox Code Playgroud)

c# multithreading task-parallel-library async-await

6
推荐指数
1
解决办法
561
查看次数

使用受歧视的联合建模多级继承

是否有推荐的方法来模拟F#中的多个继承级别,可能是使用区分联合?

在C#中使用以下内容:

class Expr { }
class SourceExpr : Expr { }
class JoinExpr : SourceExpr { }
class TableExpr : SourceExpr { }
Run Code Online (Sandbox Code Playgroud)

我在F#中做到了这一点:

type SourceExpr =
    | Join of JoinExpr
    | Table of TableExpr

type Expr = 
    | Source of SourceExpr
    | ...
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?这是否提供与继承相同的多态行为?

f#

5
推荐指数
1
解决办法
636
查看次数

F#中的IDelegateEvent和IEvent有什么区别?

文档说:

F#为与类型IDelegateEvent兼容的非虚拟实例成员属性提供特殊状态,生成适当的.NET元数据以使该成员作为.NET事件显示给其他.NET语言.

但是,无论有没有CLIEvent属性,IDelegateEvent和IEvent的行为都是相同的.

我正在使用1.9.7.8.

f#

5
推荐指数
1
解决办法
275
查看次数

OPENXML与OPENROWSET和xml数据类型

为什么要使用OPENXML而不是OPENROWSET(BULK'file',SINGLE_BLOB)并转换为xml数据类型?

xml sql-server

5
推荐指数
1
解决办法
1760
查看次数

完整,高效的NumericLiteral模块实现

基于这个问题的讨论,任何人都可以提供代码或代码链接,显示NumericLiteralX模块的完整实现(例如这个)吗?我特别感兴趣的是有效实现FromInt32/ 64用于NumericLiteralX促进通用数字运算的模块.这是从上述问题中得出的可能效率低下的实现:

module NumericLiteralG = 
    let inline FromZero() = LanguagePrimitives.GenericZero
    let inline FromOne() = LanguagePrimitives.GenericOne
    let inline FromInt32 (n:int) =
        let one : ^a = FromOne()
        let zero : ^a = FromZero()
        let n_incr = if n > 0 then 1 else -1
        let g_incr = if n > 0 then one else (zero - one)
        let rec loop i g = 
            if i = n then g
            else …
Run Code Online (Sandbox Code Playgroud)

generics f# literals

5
推荐指数
1
解决办法
612
查看次数

如何获取CRTP类型的泛型类型定义

在C#中给出以下CRTP类型:

public abstract class DataProviderBase<TProvider>
    where TProvider : DataProviderBase<TProvider> { }
Run Code Online (Sandbox Code Playgroud)

我如何在F#中获得其泛型类型定义?

let typeDef = typedefof<DataProviderBase<_>>
Run Code Online (Sandbox Code Playgroud)

产生错误:

对类型推断变量应用默认类型"DataProviderBase <'a>"时,键入约束不匹配.统一''a'和'DataProviderBase <'时,结果类型将是无限的'a>考虑添加更多类型约束

在C#中,它将是:

var typeDef = typeof(DataProviderBase<>);
Run Code Online (Sandbox Code Playgroud)

UPDATE

我找到了一个解决方法:

[<AbstractClass>]
type DummyProvider() =
  inherit DataProviderBase<DummyProvider>()

let typeDef = typeof<DummyProvider>.BaseType.GetGenericTypeDefinition()
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以做到这一点,没有额外的类型?

reflection f# crtp

5
推荐指数
1
解决办法
577
查看次数

F#中的数组协方差

由于.NET数组是协变的,因此以下代码可在C#中工作:

var strArray = new string[0];
object[] objArray = strArray;
Run Code Online (Sandbox Code Playgroud)

在F#中,给定数组,'T[]将其转换为的最佳方法是什么obj[],而无需重新创建数组(例如Array.map box)?我正在使用(box >> unbox),但感觉很草率。

.net arrays f# covariance

5
推荐指数
2
解决办法
1115
查看次数

简明地创建一个IDictionary <_,obj>

是否有更短的方式来创建一个IDictionary<_,obj>,可能没有拳击每个值?这就是我所拥有的.

let values =
  [ "a", box 1
    "b", box "foo"
    "c", box true ]
  |> dict
Run Code Online (Sandbox Code Playgroud)

Dictionary<_,obj>.Add 可以在没有拳击的情况下进行调用,但我无法找到一种方法来使用它比我的更短.

我希望除了定义拳击操作员之外的其他东西.

编辑

根据Brian的建议,这是一种方法,但它有自己的问题.

let values =
  Seq.zip ["a"; "b"; "c"] ([1; "foo"; true] : obj list) |> dict
Run Code Online (Sandbox Code Playgroud)

f#

5
推荐指数
1
解决办法
392
查看次数