• Home   /  
  • Archive by category "1"

Readonly Property Cannot Be Used As An Assignment Target Jobs

This chapter is from the book 


The preceding section, “Access Modifiers,” demonstrated how you can use the keyword to encapsulate a password, preventing access from outside the class. This type of encapsulation is often too strict, however. For example, sometimes you might need to define fields that external classes can only read, but whose values you can change internally. Alternatively, perhaps you want to allow access to write some data in a class, but you need to be able to validate changes made to the data. In yet another scenario, perhaps you need to construct the data on the fly. Traditionally, languages enabled the features found in these examples by marking fields as private and then providing getter and setter methods for accessing and modifying the data. The code in Listing 5.16 changes both and to private fields. Public getter and setter methods for each field allow their values to be accessed and changed.

LISTING 5.16: Declaring Getter and Setter Methods

Unfortunately, this change affects the programmability of the class. No longer can you use the assignment operator to set data within the class, nor can you access the data without calling a method.

Declaring a Property

Recognizing the frequency of this type of pattern, the C# designers provided explicit syntax for it. This syntax is called a property (see Listing 5.17 and Output 5.5).

LISTING 5.17: Defining Properties


The first thing to notice in Listing 5.17 is not the property code itself, but rather the code within the class. Although you no longer have the fields with the and identifiers, you cannot see this by looking at the class. The API for accessing an employee’s first and last names has not changed at all. It is still possible to assign the parts of the name using a simple assignment operator, for example ().

The key feature is that properties provide an API that looks programmatically like a field. In actuality, no such fields exist. A property declaration looks exactly like a field declaration, but following it are curly braces in which to place the property implementation. Two optional parts make up the property implementation. The part defines the getter portion of the property. It corresponds directly to the and functions defined in Listing 5.16. To access the property, you call . Similarly, setters (the portion of the implementation) enable the calling syntax of the field assignment:

  • employee.FirstName = "Inigo";

Property definition syntax uses three contextual keywords. You use the and keywords to identify either the retrieval or the assignment portion of the property, respectively. In addition, the setter uses the keyword to refer to the right side of the assignment operation. When calls , therefore, is set to inside the setter and can be used to assign . Listing 5.17’s property implementations are the most commonly used. When the getter is called (such as in ), the value from the field () is obtained and written to the console.

Automatically Implemented Properties

In C# 3.0, property syntax includes a shorthand version. Since a property with a single backing field that is assigned and retrieved by the get and set accessors is so trivial and common (see the implementations of and ), the C# 3.0 compiler (and higher) allows the declaration of a property without any accessor implementation or backing field declaration. Listing 5.18 demonstrates the syntax with the and properties, and Output 5.6 shows the results.

LISTING 5.18: Automatically Implemented Properties


Auto-implemented properties provide for a simpler way of writing properties in addition to reading them. Furthermore, when it comes time to add something such as validation to the setter, any existing code that calls the property will not have to change, even though the property declaration will have changed to include an implementation.

Throughout the remainder of the book, we will frequently use this C# 3.0 or later syntax without indicating that it is a feature introduced in C# 3.0.

One final thing to note about automatically declared properties is that in C# 6.0, it is possible to initialize them as Listing 5.18 does for :

Prior to C# 6.0, property initialization was possible only via a method (including the constructor, as we discuss later in the chapter). However, with C# 6.0, you can initialize automatically implemented properties at declaration time using a syntax much like that used for field initialization.

Property and Field Guidelines

Given that it is possible to write explicit setter and getter methods rather than properties, on occasion a question may arise as to whether it is better to use a property or a method. The general guideline is that methods should represent actions and properties should represent data. Properties are intended to provide simple access to simple data with a simple computation. The expectation is that invoking a property will not be significantly more expensive than accessing a field.

With regard to naming, notice that in Listing 5.18 the property name is , and the field name changed from earlier listings to —that is, PascalCase with an underscore suffix. Other common naming conventions for the private field that backs a property are and (a holdover from C++, where the m stands for member variable), and on occasion the camelCase convention, just like with local variables.3 The camelCase convention should be avoided, however. The camelCase used for property names is the same as the naming convention used for local variables and parameters, meaning that overlaps in names become highly probable. Also, to respect the principles of encapsulation, fields should not be declared as public or protected.

Regardless of which naming pattern you use for private fields, the coding standard for properties is PascalCase. Therefore, properties should use the and pattern with names that represent nouns, noun phrases, or adjectives. It is not uncommon, in fact, that the property name is the same as the type name. Consider an property of type on a object, for example.

Using Properties with Validation

Notice in Listing 5.19 that the method of uses the property rather than the field for assignment as well. Although this is not required, the result is that any validation within the property setter will be invoked both inside and outside the class. Consider, for example, what would happen if you changed the property so that it checked for or an empty string, before assigning it to .

LISTING 5.19: Providing Property Validation

With this new implementation, the code throws an exception if is assigned an invalid value, either from another member of the same class or via a direct assignment to from inside . The ability to intercept an assignment and validate the parameters by providing a field-like API is one of the advantages of properties.

It is a good practice to access a property-backing field only from inside the property implementation. In other words, you should always use the property, rather than calling the field directly. In many cases, this principle holds even from code within the same class as the property. If you follow this practice, when you add code such as validation code, the entire class immediately takes advantage of it.5

Although rare, it is possible to assign inside the setter, as Listing 5.19 does. In this case, the call to removes any whitespace surrounding the new last name value.

Read-Only and Write-Only Properties

By removing either the getter or the setter portion of a property, you can change a property’s accessibility. Properties with only a setter are write-only, which is a relatively rare occurrence. Similarly, providing only a getter will cause the property to be read-only; any attempts to assign a value will cause a compile error. To make read-only, for example, you would code it as shown in Listing 5.20.

LISTING 5.20: Defining a Read-Only Property prior to C# 6.0

Listing 5.20 assigns the field from within the constructor rather than the property (). Assigning via the property causes a compile error, as it does in .

Starting in C# 6.0, there is also support for read-only automatically implemented properties as follows:

public bool[,,] Cells { get; } = new bool[2, 3, 3];

This is clearly a significant improvement over the pre-C# 6.0 approach, especially given the commonality of read-only properties for something like an array of items or the in Listing 5.20.

One important note about a read-only automatically implemented property is that, like read-only fields, the compiler requires that it be initialized in the constructor or via an initializer. In the preceding snippet we use an initializer, but the assignment of from within the constructor is also permitted.

Given the guideline that fields should not be accessed from outside their wrapping property, those programming in a C# 6.0 world will discover that there is virtually no need to ever use pre-C# 6.0 syntax; instead, the programmer can always use a read-only, automatically implemented property. The only exception might be when the data type of the read-only modified field does not match the data type of the property—for example, if the field was of type and the read-only property was of type .

Properties As Virtual Fields

As you have seen, properties behave like virtual fields. In some instances, you do not need a backing field at all. Instead, the property getter returns a calculated value while the setter parses the value and persists it to some other member fields (if it even exists). Consider, for example, the property implementation shown in Listing 5.21. Output 5.7 shows the results.

LISTING 5.21: Defining Properties


The getter for the property concatenates the values returned from the and properties. In fact, the name value assigned is not actually stored. When the property is assigned, the value on the right side is parsed into its first and last name parts.

Access Modifiers on Getters and Setters

As previously mentioned, it is a good practice not to access fields from outside their properties because doing so circumvents any validation or additional logic that may be inserted. Unfortunately, C# 1.0 did not allow different levels of encapsulation between the getter and setter portions of a property. It was not possible, therefore, to create a public getter and a private setter so that external classes would have read-only access to the property while code within the class could write to the property.

In C# 2.0, support was added for placing an access modifier on either the get or the set portion of the property implementation (not on both), thereby overriding the access modifier specified on the property declaration. Listing 5.22 demonstrates how to do this.

LISTING 5.22: Placing Access Modifiers on the Setter

By using on the setter, the property appears as read-only to classes other than . From within , the property appears as read/write, so you can assign the property within the constructor. When specifying an access modifier on the getter or setter, take care that the access modifier is more restrictive than the access modifier on the property as a whole. It is a compile error, for example, to declare the property as and the setter as .

Properties and Method Calls Not Allowed As or Parameter Values

C# allows properties to be used identically to fields, except when they are passed as or parameter values. and parameter values are internally implemented by passing the memory address to the target method. However, because properties can be virtual fields that have no backing field, or can be read-only or write-only, it is not possible to pass the address for the underlying storage. As a result, you cannot pass properties as or parameter values. The same is true for method calls. Instead, when code needs to pass a property or method call as a or parameter value, the code must first copy the value into a variable and then pass the variable. Once the method call has completed, the code must assign the variable back into the property.

The read-only role (snc_read_only) restricts a user or a group of users to read-only access on the tables to which the user already has access.

This role is not intended to be the only role a user has. It is intended to be an extra role to restrict insert, update, and delete operations on the tables that the user can access as defined by the other roles.

After you assign this role to a user, they can no longer can create, update, or delete records on ANY tables.

Note: Assign this role only to users. Do not assign this role to other resources in the system, including applications, ACLs, and so on.

The snc_read_only role can be assigned to any user as a simple way to limit access to data without having to create ACLs for system and custom tables and fields. This practice is useful for performing internal or external audits without allowing a user to have insert or update access to data.

Users with the snc_read_only role have the following restrictions regardless of other roles and privileges they have.
  • Cannot insert, update, or delete records from the UI or when using the GlideRecord API.
  • Cannot activate or upgrade plugins.
  • Cannot directly run SQL.
  • Cannot upload XML files.
  • Can only run background scripts when on an instance in the public sandbox environment.

Note: These role restrictions are in place even if impersonating another user with write access such as an admin.

Activate the read-only role

If it is not already active, an administrator can activate the Read-Only User Role (com.snc.read_only.role) plugin .

Before you begin

Role required: admin

About this task

For evaluation, you can activate the plugin for an application that requires a purchased subscription on a sub-production instance. To activate the plugin on production instances, you must purchase the subscription. To purchase a subscription, contact your ServiceNow account manager. For details on purchasing a plugin, see Purchase a plugin.

Some plugins require activation by ServiceNow personnel. Request these plugins through the HI Customer Service System instead of activating them yourself. For details, see Request a plugin.

For plugins that you can activate yourself, continue with the following steps.


  1. Navigate to .
  2. Find and click the plugin name.
  3. On the System Plugin form, review the plugin details and then click the Activate/Upgrade related link.

    If the plugin depends on other plugins, these plugins are listed along with their activation status.

    If the plugin has optional features that depend on other plugins, those plugins are listed under Some files will not be loaded because these plugins are inactive. The optional features are not installed until the listed plugins are installed (before or after the installation of the current plugin).

  4. (Optional) If available, select the Load demo data check box.

    Some plugins include demo data—Sample records that are designed to illustrate plugin features for common use cases. Loading demo data is a good practice when you first activate the plugin on a development or test instance.

    You can also load demo data after the plugin is activated by clicking the Load Demo Data Only related link on the System Plugin form.

  5. Click Activate.

Read-only role properties

These system properties control the snc_read_only role. The following default values are used for the properties.

glide.security.snc_read_only_role.tables.exempt_createSpecifies which tables are exempt from the read-only role enforcement and allow the creation of new records.
  • Type: string
  • Default value: sys_user_session, sysevent, syslog, syslog_transaction, sys_user_preference, sys_ui_list, sys_ui_list_element, sys_db_cache, user_multifactor_auth
  • Location: System Properties [sys_properties] table
glide.security.snc_read_only_role.tables.exempt_writeSpecifies which tables are exempt from the read-only role enforcement and allow the updating of existing records.
  • Type: string
  • Default value: sys_user_session, sysevent, syslog, syslog_transaction, sys_user_preference, sys_ui_list, sys_ui_list_element, sys_db_cache, user_multifactor_auth
  • Location: System Properties [sys_properties] table
glide.security.snc_read_only_role.tables.exempt_deleteSpecifies which tables are exempt from the read-only role enforcement and allow the deletion of existing records.
  • Type: string
  • Default value: sys_user_preference, sys_ui_list, sys_ui_list_element, sys_db_cache, user_multifactor_auth
  • Location: System Properties [sys_properties] table

Log on with the read-only role

Users logging in to a production instance should log in using the snc_read_only role to prevent unwanted modifications to the instance data.

  1. Click To log on with different role(s), click here.
  2. Enter read_only, maint.
  3. Click Refresh.
  4. Click read_only,maint to log in.

One thought on “Readonly Property Cannot Be Used As An Assignment Target Jobs

Leave a comment

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *