可以通过访问Type来限制对Object的属性的访问

时间:2009-04-18 05:29:02

标签: c#

我想只读取一个对象的属性,除了我想允许访问更改属性值的某些类。我该怎么做呢?

class Restricted ()
{ 

public int Property1{get; }
public int Property2{get; }

}

如果我这样做:

public int Property1{ get; private set;}

如何选择允许设置此属性的类?检查typeof?这是一种有效的方法吗?

5 个答案:

答案 0 :(得分:1)

你不能,至少不能单独使用这种语言。 C#中的访问修饰符是:

  • public:任何人都可以设置属性
  • private:此类中只有代码可以设置属性
  • protected:只有此类或子类中的代码可以设置属性
  • internal:此程序集中只有代码(或InternalsVisibleTo程序集)可以设置属性
  • protected internal:只有此类或子类中的代码或此程序集(或InternalsVisibleTo程序集)中的代码才能设置属性

“特定类可以设置属性”没有修饰符,类似于C ++中的友元声明。

答案 1 :(得分:1)

您可以创建friend assemblies。也就是说,允许访问类的内部方法到另一个程序集中的所有类。我不认为你可以逐类进行。

答案 2 :(得分:0)

如果您控制要授予setter访问权限的类,则可以将属性的设置标记为“internal”,然后将所有类编译到同一个程序集中。这样,使用你的类的任何其他东西都将无法使用setter。

答案 3 :(得分:0)

使用通常只允许读取访问的接口。

public interface IPublicProperties
{
  int Property1 { get; }
  int Property2 { get; }
}

internal class Restricted : IPublicProperties
{ 
  public int Property1 { get; set; }
  public int Property2 { get; set; }
}

缺点是,使用setter的类需要将接口强制转换为实际的类。好处是,在大多数情况下,长期使用接口都有好处。

答案 4 :(得分:0)

这些方法适用于C ++,不使用friend访问说明符。我不确定他们是否会在C#中工作。此外,经过漫长的一天看到你的问题后,这只是我的头脑,所以它可能会出错。

一种方法:该类将自身强制转换为成员可变的私有基础。缺点:任何其他类都可以调用unlock。

  #include <iostream>

  struct unlocked { 
      int a;
      int b;
      //virtual ~unlocked(); // don't call delete on a unlocked
  };

  class locked : private unlocked {

     public:
     locked() {
        a = 0 ;  // accessible within locked
        b = 1 ;
    }

     unlocked& unlock( ) {
        return *this ;
     } 

     void print( std::ostream& o ) {
        o << " a = " << a << ", b = " << b << std::endl ;
     }

  } ;

用法:

  int main() {

     locked foo ;
     foo.print( std::cout );
     // foo.a = 1 ; illegal
     foo.unlock().a = 1 ;
     foo.print( std::cout ) ;
     std::cout << &foo << " " << &(foo.unlock()) << std::endl;
  }

另一种方式:调用unlock,类key' must be passed. Classis a protected inner class of public class 'keyed'. Only class的实例键入can mutate class 'locked。缺点:locked必须私下继承keyed,才能使keyed::keylocked可见。但是因为keyedkey都没有成员,所以继承它们的开销很小。您可以按原样使用keyed,或者更好地继承它。

  #include <iostream>

  class locked ;

  class keyed ;

  class keyed {
     protected:
      struct key{};

     public:
     void mutateLocked( locked& );
  };


  struct unlocked { 
      int a;
      int b;
      void print( std::ostream& o ) {
        o << this << " a = " << a << ", b = " << b << std::endl ;
      }
  };

  class locked : private unlocked, private keyed {

     public:
     locked() {
        a = 0 ;
        b = 1 ;
    }

     unlocked& unlock( keyed::key& k) {
        return *this ;
     } 

     using unlocked::print; 
  } ;

  void keyed::mutateLocked(locked& m ) {
     key k ;
     m.print(std::cout) ;
     unlocked& n = m.unlock( k ) ;
     n.a = 55;
     n.b = 77;
     n.print(std::cout);
  }

用法:

  int main() {

     keyed k ;
     //keyed::key kk; // not accessible

     locked foo ;
     //unlocked& bar = (unlocked) foo; // not accessible
     foo.print( std::cout );
     //foo.a = 1 ;  // not accessible
     //foo.unlock(kk).a = 1 ;
     k.mutateLocked(foo);
     foo.print( std::cout ) ;
 }