简体   繁体   English

在类型中使用F#索引属性

[英]Using F# Indexed Properties in a Type

I'm trying to convert the following C# into F#: 我正在尝试将以下C#转换为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]

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[,]. 第一个是那个矩阵。[(x,y)]的类型应为a [],但类型为double [,]。 The second is type definitions must have let/do bindings preceding member and interface definitions. 第二个是类型定义必须在成员和接口定义之前具有let / do绑定。 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. 这样做的问题是我试图在do块中填充索引属性,这意味着我必须先创建它。

Thanks in advance, 提前致谢,

Bob 鲍勃

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). 关于第一个问题,您想使用matrix.[x,y]而不是matrix.[(x,y)] -您的矩阵由两个整数索引,而不是由整数元组索引(尽管在概念上相似)。

Here's something roughly equivalent to your C#: 这大致相当于您的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

This assumes that your matrix can't actually be reassigned (eg in the C# you've posted, you could have made your matrix field readonly - unless there's additional code that you've hidden). 这假设您的矩阵实际上无法重新分配(例如,在您发布的C#中,您可以将matrix字段设置为readonly -除非您隐藏了其他代码)。 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. 因此,由于矩阵的条目可能会更改,但矩阵的大小不会更改,因此可以在构造函数中一次计算行数和列数。

However, if you want a more literal translation of your code, you can give your newly constructed instance a name ( this in this case): 但是,如果你希望你的代码更直译,你可以给你的新构造实例的名称( this在这种情况下):

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
type Matrix(sourceMatrix:double[,]) =
    let matrix = Array2D.copy sourceMatrix
    member this.Item
        with get(x, y) = matrix.[x, y]
        and set(x, y) value = matrix.[x, y] <- value

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM