2009-12-11 63 views
0

我有一個公共類,我定義它最終將成爲API的一部分,所以它必須具有某些公共屬性。然而,我還希望一些屬性是隻讀的,除非它們是在我自己的項目中創建的(例如,如果用戶有我們的API,他們可以創建一個用戶對象,但他們不能寫入其ID字段,只有從數據庫中提取時纔會填寫)。使用部分類來添加私有屬性?

我的想法是有兩個獨立的程序集使用相同的命名空間,「公共」DLL和「私人」DLL。公共DLL原型看起來像:

namespace CompanyName 
{ 
    public partial class User 
    { 
    public Id { get; } 
    public Name { get; set; } 
    } 
} 

和私營DLL都會有這樣的:

namespace CompanyName 
{ 
    public partial class User 
    { 
    public Id { set; } 
    } 
} 

將這項工作?如果不是,有什麼更好的方法來做到這一點?

+1

即將喊出內部...但那不是你真正想要的... – LorenVS 2009-12-11 23:06:53

回答

9

部分類不能跨越程序集,所以這不起作用。

你可以定義你的類爲:

namespace CompanyName 
{ 
    public class User 
    { 
     public Id {get;internal set;} 
     public Name {get;set;} 
    } 
} 

這將意味着,只有具有內部訪問你的類的代碼可以設置Id屬性的值。如果您需要從裝配外部進行設置,請確保裝配名稱是強名稱的,然後可以使用InternalsVisibleTo屬性將裝配的內部訪問權限授予另一個裝配(設置值爲Id的裝配)。


我最近不得不做一些非常類似於我工作的API的東西。我們的API主要是使用接口定義的,所以我可以通過使用公共API的公共API項目和一個內部API項目來實現這個目標,該API項目構成了我們內部代碼使用的API,其內部接口來源於公共API 。 API接口的實現實現了兩個接口,這意味着我們的內部代碼可以訪問不公開的部分API。

+0

我從來不知道你可以使任何內部... – 2009-12-11 23:19:27

+0

我喜歡內部接口擴大公衆的想法...尤其是如果它明確完成,因爲(如果我沒有弄錯),即使有反射,也沒有辦法調用這些方法,而沒有參考接口類型... – LorenVS 2009-12-11 23:57:21

+0

是的。我遇到的唯一缺點是你必須做((IInternalInterface)接口)來獲得內部接口 - 但是它確實使得它明確表示你正在使用內部功能。 – adrianbanks 2009-12-12 00:02:14

2

我懷疑這會奏效。我想可以將部分類一起編譯到相同的程序集中,而不是由CLR處理。您可能想要查看internal關鍵字。

也許做這樣的事情

abstract internal class UserPrototype 
{ 
    protected Property.... 
} 


sealed class User : UserPrototype 
{ 
    public ... 
} 
5

不,這是行不通的。部分類在編譯時被合併:不能將成員添加到編譯類中。

這依賴於你的代碼是如何佈局,更好的方法是提供一個內部setter:

public int Id { get; internal set; } 

如果您需要能夠做到從另一個組件集,但只有一個你控制,您可以使用InternalsVisibleToAttribute將該程序集訪問授予內部設置員。

+0

InternalsVisibleToAttribute可能是我正在尋找的。謝謝! – 2009-12-11 23:12:21

0

即使你能做到這一點,你的私人財產和領域仍然可以通過反思發現。從MSDN page for GetProperty

以下BindingFlags過濾標誌可用於定義在搜索中包括哪些屬性:

您必須指定任一BindingFlags.InstanceBindingFlags.Static到得到回報。

指定BindingFlags.Public在搜索中包含公共屬性。

指定BindingFlags.NonPublic在搜索中包含非公共屬性(即私有屬性和受保護屬性)。

+1

確實如此,但是僅僅通過使用API​​和使用Intellisense就可以設置Id的值,並積極地使用反射來「破解」API的使用。 – adrianbanks 2009-12-11 23:17:00

0

設計API的技巧是在接口的類別中進行思考(本例中爲抽象類)。請在這個代碼看看:

public abstract class User 
{ 
    protected String _name; 
} 

public sealed class PublicUser : User 
{ 
    public String Name 
    { 
     get{ return this._name; } 
    } 
} 

public class PrivateUser : User 
{ 
    public String Name 
    { 
     get { return this._name; } 
     set { this._name = value; } 
    } 
} 

很明顯,你可以使用任何類/命名空間名稱,這只是爲了澄清事情。正如你所看到的,所有的類都是公共的,所以現在由你決定哪個DLL可用於你的客戶端。