代码之家  ›  专栏  ›  技术社区  ›  Adam V

使用分部类添加私有属性?

  •  0
  • Adam V  · 技术社区  · 15 年前

    我定义了一个公共类,它最终将成为API的一部分,因此它必须具有某些公共属性。但是,我也希望某些属性是只读的,除非它们是从我自己的项目中创建的(例如,如果用户有我们的API,他们可以创建一个用户对象,但他们不能写入其ID字段,只有从数据库中提取它,才会填充该字段)。

    我认为有两个使用相同名称空间的独立程序集,“public”dll和“private”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; }
      }
    }
    

    这行吗?如果不是,有什么更好的方法可以做到这一点?

    5 回复  |  直到 15 年前
        1
  •  9
  •   adrianbanks    15 年前

    分部类不能跨越程序集,因此这不起作用。

    您可以将类定义为:

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

    这意味着只有具有类内部访问权限的代码才能设置 Id 财产。如果需要从程序集外部进行设置,请确保程序集具有强名称,然后可以使用 InternalsVisibleTo 属性,以将对程序集的内部访问权授予另一个程序集(设置 身份证件 )


    我最近不得不为我所研究的一个API做与此非常类似的事情。我们的API主要是使用接口来定义的,所以我可以通过一个公共的API项目(公共部分)和一个内部的API项目(构成我们内部代码使用的API)来实现这一点,内部接口是从公共接口派生的。API接口的实现实现了这两个接口,这意味着我们的内部代码可以访问API中不公开的部分。

        2
  •  5
  •   itowlson    15 年前

    不,这样不行。部分类在编译时合并:不能向已编译类添加成员。

    根据代码的具体布局,更好的方法是提供一个内部setter:

    public int Id { get; internal set; }
    

    如果需要能够从另一个程序集进行设置,但只能控制一个程序集,则可以使用InternalsVisibleToAttribute授予该程序集对内部setter的访问权限。

        3
  •  2
  •   Daniel A. White    15 年前

    我怀疑这是否可行。我可以想象部分类被编译到同一个程序集中,而不是由clr处理。你可能想看看 internal 关键字。

    也许可以这样做

    abstract internal class UserPrototype
    {
        protected Property....
    }
    
    
    sealed class User : UserPrototype
    {
        public ...
    }
    
        4
  •  0
  •   ChrisF    15 年前

    即使您可以这样做,您的私有属性和字段仍然可以通过反射来发现。来自 MSDN page for GetProperty :

    以下 BindingFlags 筛选标志可用于定义要包含在搜索中的属性:

    必须指定 bindingFlags.instance bindingFlags.static 为了得到回报。

    指定 bindingFlags.public 在搜索中包含公共属性。

    指定 绑定标志.nonpublic 在搜索中包含非公共属性(即私有和受保护属性)。

        5
  •  0
  •   Piotr Justyna    15 年前

    设计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可用于您的客户机。