如何从 F# 中的 CSLA 对象继承?
我想从 F# 获得 CSLA 的好处,但我在继承方面遇到了麻烦。这是 ProjectTracker ResourceInfo 类。有人可以展示如何在 F# 中执行此操作吗?
using Csla;
using System;
using Csla.Serialization;
namespace ProjectTracker.Library
{
[Serializable()]
public class ResourceInfo : ReadOnlyBase<ResourceInfo>
{
private static PropertyInfo<int> IdProperty = RegisterProperty<int>(c => c.Id);
public int Id
{
get { return GetProperty(IdProperty); }
private set { LoadProperty(IdProperty, value); }
}
private static PropertyInfo<string> NameProperty = RegisterProperty<string>(c => c.Name);
public string Name
{
get { return GetProperty(NameProperty); }
private set { LoadProperty(NameProperty, value); }
}
public override string ToString()
{
return Name;
}
internal ResourceInfo(int id, string lastname, string firstname)
{
Id = id;
Name = string.Format("{0}, {1}", lastname, firstname);
}
}
}
I would like to get the benefits of CSLA from F#, but I am having trouble with inheritance. Here is the ProjectTracker ResourceInfo class. Can someone please show how to do it in F#?
using Csla;
using System;
using Csla.Serialization;
namespace ProjectTracker.Library
{
[Serializable()]
public class ResourceInfo : ReadOnlyBase<ResourceInfo>
{
private static PropertyInfo<int> IdProperty = RegisterProperty<int>(c => c.Id);
public int Id
{
get { return GetProperty(IdProperty); }
private set { LoadProperty(IdProperty, value); }
}
private static PropertyInfo<string> NameProperty = RegisterProperty<string>(c => c.Name);
public string Name
{
get { return GetProperty(NameProperty); }
private set { LoadProperty(NameProperty, value); }
}
public override string ToString()
{
return Name;
}
internal ResourceInfo(int id, string lastname, string firstname)
{
Id = id;
Name = string.Format("{0}, {1}", lastname, firstname);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
jpalmer 的解决方案显示了一般结构,但我认为存在一些问题。我没有 CSLA 经验,所以我没有尝试运行它,但我下载了 DLL 并尝试对示例进行类型检查。
首先,
RegisterProperty
方法不采用 lambda 函数,而是采用表达式(并使用它通过反射获取有关属性的信息)。要实现此功能,您需要使用 F# 引号编写一个帮助器:这会将带引号的 F# lambda 函数转换为预期格式的 C# 表达式树。然后,您可以使用
prop <@ fun (a:Foo) ->; 之类的内容调用
作为参数。RegisterProperty
a.Bar @>我还看到
IdProperty
应该是静态的,这可以使用static let
来完成(如果它是私有的)。以下应该是使用一个属性定义类型的正确方法:我通常非常喜欢直接在代码中编写可访问性修饰符时的样式(如在 C# 中),因此我使用
internal
将构造函数注释为在你的代码中。我还添加了构造函数主体,用于在创建对象时设置Id
属性。The solution by jpalmer shows the general structure, but I think there are a couple of problems. I don't have experience with CSLA, so I haven't tried running this, but I downloaded the DLL and tried type-checking the sample.
First of all, the
RegisterProperty
method does not take a lambda function, but an expression (and uses it to get information about the property using reflection). To get this working, you need to write a helper using F# quotations:This turns a quoted F# lambda function to a C# expression tree in the expected format. You can then call
RegisterProperty
with something likeprop <@ fun (a:Foo) -> a.Bar @>
as an argument.I also see that
IdProperty
should be static, which can be done usingstatic let
(if it is private). The following should be the right way of defining type with one property:I generally quite like the style when you write accessibility modifiers directly in your code (as in C#), so I annotated the constructor with
internal
as in your code. I also added constructor body that sets theId
property when the object is created.这应该很接近 - 在 F# 中进行访问控制的标准方法是使用签名文件,我省略了它
This should be close - the standard way to do the access control in F# is to use signature files, which I left out
@托马斯
我对您的回复感到荣幸,并对您为此付出的努力感到感动——下载 CSLA、将表达式识别为问题,并创建一种非显而易见的方法来处理它。我喜欢你的书,真实世界函数式编程,它超越了语言功能以及如何将它们应用于重要的现实问题。
CSLA 在 C# 有了 lambda 之前就已经出现了,所以我回去看看 Lhotka 如何使用 RegisterProperty。如果其他用户想要避免表达式,看起来这也有效:
@Tomas
I am honored by your reply and touched by your effort to do so--downloading CSLA, identifying the expression as a problem, and creating a non-obvious way to deal with it. I love your book, Real-World Functional Programming, which goes beyond language features and into how to apply them to important real-world problems.
CSLA was out before C# had lambdas, so I went back to see how Lhotka then used RegisterProperty. If other users want to avoid expressions, it looks like this works, too: