2012-09-13 37 views
6

我知道這是可能的C#,它產生簡單和高效的代碼。 ---同一班級的兩個對象可以訪問彼此的私人部分。對象是否可以訪問同一類的另一個對象的私有字段/函數?

class c1 
{ 
    private int A; 

    public void test(c1 c) 
    { 
     c.A = 5; 
    } 
} 

但在F#中似乎是不可能的,這是真的嗎?

type c1() 
    let A = 0 
    member test (c: c1) = c.A 
+0

你c1'的'定義有一些語法錯誤和不能編譯,無效嘗試在訪問'放在一邊。 –

回答

5

有趣的問題。它似乎有一個明確的領域工作,但不是使用let綁定:

// Works 
type c1 = 
    val private A : int 
    new(a) = { A = a } 
    member m.test(c : c1) = c.A 

let someC1 = new c1(1) 
let someMoreC1 = new c1(42); 
let theAnswer = someC1.test someMoreC1 

// Doesn't work 
type c2() = 
    let mutable A = 42 
    // Compiler error: The field, constructor or member 'A' is not defined 
    member m.test(c : c2) = c.A 
1

你只在實例方法

type c1() 
    let A = 0 
    member x.test = A 

使用a直接對一個靜態方法,這並不工作爲讓綁定略有不同 - 那麼你需要一個類定義像

type c1() 
    private member x.A = 0 
    static member test (A:c1) = A.A 
+0

第二個示例中的問題:您無法從靜態方法訪問成員。 –

+0

@JohnReynolds - 固定 –

2

是的,但在您的示例中A在語義上不是c1的私有成員,它更像是構造函數的局部變量。

@afrischke舉例說明如何使用實際私人成員A(使用val字段)定義c1

+0

不,A不是本地構造函數的值。實際上,它是一個私人成員,請參閱http://msdn.microsoft.com/en-us/library/dd483470。 –

+1

@JohnReynolds - 我說它更像是一個本地的構造函數值,並不是它「是」一個。 「事實上,它是一個私人成員」:MSDN在這裏有誤導性,它*被編譯成專用字段,但這是一個實現細節。從語義上講,它與私有可訪問性的CLI定義不兼容(請參閱http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf,第I.8.5.3.2節) –

+0

當然,我們可以對「更像構造函數的局部變量」的含義有不同的看法。我解釋的方式是''A'只能在構造函數內部訪問。在這裏不是這種情況,因爲''可以被'c1'的同一個實例的所有成員函數訪問(儘管不是'c1'的其他實例)。 –

1

由於部分8.6.1 .3 F#規範狀態:

通過實例定義定義的功能和價值是詞法範圍的(因此隱含私有)到被定義的對象。

1

這是可能的,它被廣泛使用,例如,用於檢查按成員平等:

type c1 = 
    member private this.A = 0 
    interface IEquatable<c1> with 
     member this.Equals (that: c1) = this.A = that.A 
    // of course, it can be done in a regular method as well 
    member this.Equals (that: c1) = this.A = that.A 
+1

這是一種解決方法,但這裏'A'是屬性,而不是字段。 – Daniel

+0

@Daniel沒有證據表明OP是否需要字段。 :)'讓A = 0'可能只是一個錯誤。另外@ afrischke的答案似乎足以顯式字段。 – bytebuster

+1

標題詢問是否可以訪問私人領域。他的C#示例也使用字段。 – Daniel

相關問題