[英]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.