Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从F#中的CSLA对象继承?_F#_Csla - Fatal编程技术网

如何从F#中的CSLA对象继承?

如何从F#中的CSLA对象继承?,f#,csla,F#,Csla,我想从F#那里得到CSLA的好处,但我在继承方面遇到了麻烦。这是ProjectTracker ResourceInfo类。有人能演示一下如何用F#做吗 使用Csla; 使用制度; 使用Csla.Serialization; 命名空间ProjectTracker.Library { [可序列化()] 公共类ResourceInfo:ReadOnlyBase { 私有静态属性info IdProperty=RegisterProperty(c=>c.Id); 公共整数Id { 获取{return G

我想从F#那里得到CSLA的好处,但我在继承方面遇到了麻烦。这是ProjectTracker ResourceInfo类。有人能演示一下如何用F#做吗

使用Csla;
使用制度;
使用Csla.Serialization;
命名空间ProjectTracker.Library
{
[可序列化()]
公共类ResourceInfo:ReadOnlyBase
{
私有静态属性info IdProperty=RegisterProperty(c=>c.Id);
公共整数Id
{
获取{return GetProperty(IdProperty);}
私有集{LoadProperty(IdProperty,value);}
}
私有静态属性info-NameProperty=RegisterProperty(c=>c.Name);
公共字符串名
{
获取{return GetProperty(NameProperty);}
私有集{LoadProperty(NameProperty,value);}
}
公共重写字符串ToString()
{
返回名称;
}
内部资源信息(int-id、string-lastname、string-firstname)
{
Id=Id;
Name=string.Format(“{0},{1}”,lastname,firstname);
}
}
}

这应该很接近-在F#中进行访问控制的标准方法是使用签名文件,我没有提到

module ProjectTracker.Library
open Csla;
open System;
open Csla.Serialization;

  [<Serializable>]
  type  ResourceInfo(id, lastname, firstname) =
    inherit ReadOnlyBase<ResourceInfo>()
    Id <- id
    Name <- sprintf "%s, %s" lastname firstname
    let IdProperty = RegisterProperty<int>(fun c -> c.Id); 
    member x.Id with get() = GetProperty(IdProperty) and set(v) = LoadProperty(IdProperty, v)

   //skipped a property here - similar to above
    override x.ToString() = Name
模块ProjectTracker.Library
开放式Csla;
开放系统;
开放Csla.Serialization;
[]
键入ResourceInfo(id、lastname、firstname)=
继承ReadOnlyBase()

Idjpalmer的解决方案显示了总体结构,但我认为存在两个问题。我没有使用CSLA的经验,所以我没有试过运行它,但我下载了DLL并尝试对示例进行类型检查

首先,
RegisterProperty
方法不采用lambda函数,而是采用表达式(并使用它通过反射获取有关属性的信息)。要使其正常工作,您需要使用F#引号编写一个助手:

open Microsoft.FSharp.Quotations
open System.Linq.Expressions

let prop (q:Expr<'T -> 'R>) = 
  match q with
  | Patterns.Lambda(v, Patterns.PropertyGet(_, pi, _)) -> 
      let v = Expression.Variable(v.Type)
      Expression.Lambda<Func<'T, 'R>>
        (Expression.Property(v, pi), [v])
  | _ -> failwith "wrong quotation"
我通常非常喜欢在代码中直接编写可访问性修饰符的风格(如C#),因此我在代码中用
internal
注释了构造函数。我还添加了构造函数体,它在创建对象时设置
Id
属性。

@Tomas 我很荣幸收到您的回复,也很感动您为此所做的努力——下载CSLA,将表达式确定为一个问题,并创建一个不明显的方法来处理它。我喜欢你的书,这本书超越了语言的特点,探讨了如何将它们应用于重要的现实问题

CSLA在C#拥有lambdas之前就已经退出了,所以我回去看看洛特卡当时是如何使用RegisterProperty的。如果其他用户希望避免使用表达式,那么这样也可以:

static let IdProperty =
  ReadOnlyBase<ResourceInfo>.RegisterProperty
    (typeof<ResourceInfo>, new PropertyInfo<int>("Id"))
static let IdProperty=
ReadOnlyBase.RegisterProperty
(类型,新属性信息(“Id”))
[<Serializable>]
type ResourceInfo internal (id:int, lastname:string, firstname:string) as this =
  inherit ReadOnlyBase<ResourceInfo>()

  // Code executed as part of the constructor    
  do this.Id <- id

  static let IdProperty = 
    ReadOnlyBase<ResourceInfo>.RegisterProperty<int>
      (prop <@ fun (r:ResourceInfo) -> r.Id @>)

  member x.Id 
    with get() = x.GetProperty(IdProperty) |> unbox
    and set(v) = x.LoadProperty(IdProperty, v)
static let IdProperty =
  ReadOnlyBase<ResourceInfo>.RegisterProperty
    (typeof<ResourceInfo>, new PropertyInfo<int>("Id"))