在类型中使用F#索引属性 [英] Using F# Indexed Properties in a Type

查看:65
本文介绍了在类型中使用F#索引属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将以下C#转换为F#:

I'm trying to convert the following C# into F#:

    public class Matrix
    {
       double[,] matrix;

public int Cols
        {
            get
            {
                return this.matrix.GetUpperBound(1) + 1;
            }
        }

public int Rows
        {
            get
            {
                return this.matrix.GetUpperBound(0) + 1;
            }
        }

       public Matrix(double[,] sourceMatrix)
       {
        this.matrix = new double[sourceMatrix.GetUpperBound(0) + 1, sourceMatrix.GetUpperBound(1) + 1];
        for (int r = 0; r < this.Rows; r++)
        {
            for (int c = 0; c < this.Cols; c++)
            {
                this[r, c] = sourceMatrix[r, c];
            }
        }
       }

       public double this[int row, int col]
       {
         get
         {
             return this.matrix[row, col];
         }
         set
         {
             this.matrix[row, col] = value;
         }
       }
     }

这是我到目前为止所拥有的:

This is what I have so far:

type Matrix(sourceMatrix:double[,]) =
let mutable (matrix:double[,]) = Array2D.create (sourceMatrix.GetUpperBound(0) + 1) (sourceMatrix.GetUpperBound(1) + 1) 0.0
member this.Item
    with get(x, y) = matrix.[(x, y)]
    and set(x, y) value = matrix.[(x, y)] <- value
do
    for i = 0 to matrix.[i].Length - 1 do
    for j = (i + 1) to matrix.[j].Length - 1 do
        this.[i].[j] = matrix.[i].[j]

我的上述类型似乎有两个问题,我不确定该如何解决.第一个是那个矩阵.[(x,y)]的类型应为a [],但类型为double [,].第二个是类型定义必须在成员和接口定义之前具有let/do绑定.这样做的问题是我试图在do块中填充索引属性,这意味着我必须先创建它.

My type above seems to have two problems I'm not sure how to resolve. The first one is that matrix.[(x, y)] is expected to have type `a[] but has type double[,]. The second is type definitions must have let/do bindings preceding member and interface definitions. The problem with that is I'm trying to populate an indexed property in the do block, which means I have to create it first.

预先感谢

鲍勃

推荐答案

关于您的第一个问题,您想使用matrix.[x,y]而不是matrix.[(x,y)]-您的矩阵是由两个整数而不是由整数元组(尽管它们在概念上相似).

Regarding your first problem, you want to use matrix.[x,y] instead of matrix.[(x,y)] - your matrix is indexed by two integers, not by a tuple of integers (although these are conceptually similar).

这里大致相当于您的C#:

Here's something roughly equivalent to your C#:

type Matrix(sourceMatrix:double[,]) =
  let rows = sourceMatrix.GetUpperBound(0) + 1
  let cols = sourceMatrix.GetUpperBound(1) + 1
  let matrix = Array2D.zeroCreate<double> rows cols
  do
    for i in 0 .. rows - 1 do
    for j in 0 .. cols - 1 do
      matrix.[i,j] <- sourceMatrix.[i,j]
  member this.Rows = rows
  member this.Cols = cols
  member this.Item
    with get(x, y) = matrix.[x, y]
     and set(x, y) value = matrix.[x, y] <- value

这假设您的矩阵实际上无法重新分配(例如,在您发布的C#中,您可以将matrix字段设置为readonly-除非您隐藏了其他代码).因此,由于矩阵的条目可能会更改,但矩阵的大小不会改变,因此在构造函数中只能计算一次行和列的数量.

This assumes that your matrix can't actually be reassigned (e.g. in the C# you've posted, you could have made your matrix field readonly - unless there's additional code that you've hidden). Therefore, the number of rows and columns can be calculated once in the constructor since the entries of the matrix may change but its size won't.

但是,如果您想对代码进行更直接的翻译,则可以为新构造的实例命名(在本例中为this):

However, if you want a more literal translation of your code, you can give your newly constructed instance a name (this in this case):

type Matrix(sourceMatrix:double[,]) as this =
  let mutable matrix = Array2D.zeroCreate<double> (sourceMatrix.GetUpperBound(0) + 1) (sourceMatrix.GetUpperBound(1) + 1)
  do
    for i in 0 .. this.Rows - 1 do
    for j in 0 .. this.Cols - 1 do
      this.[i,j] <- sourceMatrix.[i,j]
  member this.Rows = matrix.GetUpperBound(0) + 1
  member this.Cols = matrix.GetUpperBound(1) + 1
  member this.Item
    with get(x, y) = matrix.[x, y]
     and set(x, y) value = matrix.[x, y] <- value

这篇关于在类型中使用F#索引属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆