user3118189
user3118189

Reputation: 131

How to make a property set once and cannot be changed?

I have a Message class, which has three properties Content, Type, and UniqueId. When a Message object is created, Content and Type are known, so I can pass them to the constructor of the class, and make the Content and Type properties read only so that their value cannot be changed anymore. However, for the UniqueId, I need to calculate it in my code after the object has been created, and give the value to the UniqueId property. As I cannot pass the UniqueId to the constructor and make this property read only, I wonder is there such a way that once the property UniqueId has been set, its value cannot be changed anymore?

public class Message
{
    private readonly string content;
    private readonly AuditMessageType type;
    private Guid messageUId;

    public Message(string syslogMessage, AuditMessageType messageType, Guid messageUniqueId = new Guid())
    {
        content = syslogMessage;
        type = messageType;
        messageUId = messageUniqueId;
    }

    public string Message
    {
        get { return message; }
    }

    public AuditMessageType Type
    {
        get { return type; }
    }

    public Guid MesageUniqueId
    {
        get { return messageUId; }
        set { messageUId = value; } // How to make UniqueId property set once here? It cannot be pass in the constructor, as it needs to computed in the code after the object has been created. 
    }
}

Upvotes: 3

Views: 5037

Answers (4)

Neel
Neel

Reputation: 11741

No such direct feature in c# but you can code it yourself as shown below :-

private Guid? messageUId;
 public Guid MesageUniqueId
    {
        get { return messageUId; }
        set {   
              if (null == messageUId ) 
              { 
                   messageUId = value;              
              }
              else  
              { 
                  throw new InvalidOperationException("Message id can be assigned only once");
              }
     }
    }

Upvotes: 0

Perfect28
Perfect28

Reputation: 11327

Ways to do it :

If Guid.Empty is invalid state of MessageUniqueId

  public Guid MesageUniqueId
    {
        get { return messageUId; }
        set {
             if (messageUId  == Guid.Empty) 
                messageUId = value; 
        } 
    }

If you can use Nullable Guid instead of Guid

 public Guid ? MesageUniqueId
        {
            get { return messageUId; }
            set {
                 if (messageUId  == null) 
                    messageUId = value; 
            } 
        }

If you can't do both above , use a private variable :

  private bool messageUniqueIdhasBeenSet = false ; 
 public Guid  MesageUniqueId
        {
            get { return messageUId; }
            set {
                 if (!messageUniqueIdhasBeenSet ) 
                  {
                    messageUId = value;
                    messageUniqueIdhasBeenSet = true ; 
                   } 
            } 
        }

Upvotes: 1

user2160375
user2160375

Reputation:

Can't you simple create a guard flag?

bool wasSetMessageId = false;
public Guid MesageUniqueId
{
    get { return messageUId; }
    set 
    {
       if (!wasSetMessageId) 
       {
          messageUId = value;
          wasSetMessageId = true;
       } 
       else
       {
          throw new InvalidOperationException("Message id can be assigned only once");
       }
    } 
}

Upvotes: 5

Dennis_E
Dennis_E

Reputation: 8904

private bool idHasBeenSet = false;
public Guid MessageUniqueId
{
    get { return messageUId; }
    set {
        if (idHasBeenSet) return; //or throw an exception if you need to
        messageUId = value;
        idHasBeenSet = true;
    }
}

Upvotes: 0

Related Questions