C#如何保护set accessor以避免从另一个类设置属性?

C#如何保护set accessor以避免从另一个类设置属性?,c#,object,C#,Object,标题可能会让人困惑,但我没有找到其他词。最好用一个样本来解释我想要什么。 假设我有两门课。其中一个将另一个类作为属性: public class Order { public int?Id { get; protected set; } public Client Client { get; set; } public void Save() { RequestBLL bll = new RequestBLL(); bll.Save(this);

标题可能会让人困惑,但我没有找到其他词。最好用一个样本来解释我想要什么。 假设我有两门课。其中一个将另一个类作为属性:

public class Order {
   public int?Id { get; protected set; }
   public Client Client { get; set; }

   public void Save() {
      RequestBLL bll = new RequestBLL();
      bll.Save(this);
   }

   public static Order GetBy_Id(int id) {
      RequestBLL bll = new RequestBLL();
      return bll.Get<Order>(id);
   }
}

public class Client {
   public int?Id { get; protected set; }
   public string Name { get; set; }

   public void Save() {
      RequestBLL bll = new RequestBLL();
      bll.Save(this);
   }

   public static Client GetBy_Id(int id) {
      RequestBLL bll = new RequestBLL();
      return bll.Get<Client>(id);
   }
}
我想要一种避免第二次更新客户机名称(通过Order对象)的方法,并且只允许直接使用客户机对象进行第一次更新。 我检查了所有的修改器,没有找到任何可以使用的。我试过:

public Client Client { get; internal set; }
但它只避免将客户机属性设置为客户机对象。仍然可以设置名称:

c.Name = "Some Name"; //Works! It is fine.
o.Client = c; //Fails! The Client accessor does not permit this set. It is fine!
o.Client.Name = "Another Name"; //Works! And it is just what I don't want.
我知道有人会建议不要在应用程序中这样做,但这并不是那么简单。这只是我用来说明情况的一个简单例子。这个问题发生在框架内部的几个对象的循环引用中。应用程序仅保存更新了客户端名称的订单对象。它实际上并没有保存另一个客户机对象。框架中的问题是由于循环引用引起的。因此,我试图解决避免应用程序创建这种情况的问题,强制只使用直接客户端对象更新Client.Name,而不是通过另一个对象中的客户端对象更新。
有什么方法可以实现这一点吗?我正在使用自己创建的实体框架。我想知道同样的问题是否也发生在专业框架上。

我认为最好的解决方法是使用接口。让
Client
类实现
IClient
接口,并将
Client
属性返回类型更改为
IClient

由于
IClient
接口仅公开getter,因此无法在中设置
Name
属性,除非将值转换/转换为
Client
类型

public class Order {
   public int? Id { get; protected set; }
   public IClient Client { get; set; }

   public void Save() {
      RequestBLL bll = new RequestBLL();
      bll.Save(this);
   }

   public static Order GetBy_Id(int id) {
      RequestBLL bll = new RequestBLL();
      return bll.Get<Order>(id);
   }
}

public interface IClient {
   public int? Id { get; }
   public string Name { get; }

   public void Save();
}

public class Client : IClient {
   public int? Id { get; protected set; }
   public string Name { get; set; }

   public void Save() {
      RequestBLL bll = new RequestBLL();
      bll.Save(this);
   }

   public static Client GetBy_Id(int id) {
      RequestBLL bll = new RequestBLL();
      return bll.Get<Client>(id);
   }
}
公共类秩序{
公共int?Id{get;protected set;}
公共IClient客户端{get;set;}
公共作废保存(){
RequestBLL bll=newrequestbll();
全部保存(这个);
}
公共静态命令GetBy_Id(int Id){
RequestBLL bll=newrequestbll();
返回bll.Get(id);
}
}
公共接口客户端{
公共int?Id{get;}
公共字符串名称{get;}
公共作废保存();
}
公共类客户端:IClient{
公共int?Id{get;protected set;}
公共字符串名称{get;set;}
公共作废保存(){
RequestBLL bll=newrequestbll();
全部保存(这个);
}
公共静态客户端GetBy_Id(int Id){
RequestBLL bll=newrequestbll();
返回bll.Get(id);
}
}
希望能有帮助
彼得

谢谢你,彼得。这很有帮助。我执行了你的建议,效果很好。@MarceloTropia:听到这个消息我很高兴!我祝你的项目一切顺利。
public class Order {
   public int? Id { get; protected set; }
   public IClient Client { get; set; }

   public void Save() {
      RequestBLL bll = new RequestBLL();
      bll.Save(this);
   }

   public static Order GetBy_Id(int id) {
      RequestBLL bll = new RequestBLL();
      return bll.Get<Order>(id);
   }
}

public interface IClient {
   public int? Id { get; }
   public string Name { get; }

   public void Save();
}

public class Client : IClient {
   public int? Id { get; protected set; }
   public string Name { get; set; }

   public void Save() {
      RequestBLL bll = new RequestBLL();
      bll.Save(this);
   }

   public static Client GetBy_Id(int id) {
      RequestBLL bll = new RequestBLL();
      return bll.Get<Client>(id);
   }
}