How to create subtypes

The following concepts are discussed in this article: accessing the ISubtypes interface, adding subtypes to a feature class, setting the feature classes default subtype, assigning default values to fields at the subtype level, assigning domains to fields at the subtype level and lastly how to reset the subtype codes.

In this topic

Creating subtypes

Although all objects in a feature class or object class must have the same behavior and attributes, not all objects have to share the same default values and validation rules. You can group features and objects into subtypes. Subtypes differentiate objects based on their rules. The ISubtypes interface is used to manage and query the subtypes, domains, and default values associated with an object class. The following properties can be set using the ISubtypes interface:
Accessing the ISubtypes interface
The ISubtypes interface is implemented by the ObjectClass class and its subclasses, such as FeatureClass and XYEventSource.
Adding subtypes to a feature class
Every ObjectClass has a default subtype code. If the user has not explicitly specified a default subtype or a subtype field, the DefaultSubtypeCode returns a subtype value of 0. Additionally, you can query the HasSubtype property—false indicates an absence of a default subtype code, and true indicates the presence of a default subtype code.
Instead, if the client asks for the enumeration of subtypes associated with an ObjectClass and no subtype has been previously added to the ObjectClass, the enumerator contains a single entry with a code of 0. The subtype field index will be –1 if a default subtype has not been previously specified.
Subtypes can only be short or long integers (esriFieldTypeSmallInteger or esriFieldTypeInteger). If a subtype code already exists when you set the default subtype code, it will be deleted. A subtype field must be specified prior to setting the subtype code value.
In the following code example, a subtype was added to a pipe feature class. The PipeType field (esriFieldTypeSmallInteger) of the pipe feature class will be used for the subtype field. The code example consists of two subtypes:
Once the subtypes are created, the DefaultSubtypeCode can be set. In this case, the "Primary" pipe type is chosen to be the default by indicating a subtype code of 1.
static void addPipeSubtypes(IFeatureClass featureClass)throws Exception{
    // QI the feature class to the ISubtypes interface.
    ISubtypes subtypes = (ISubtypes)featureClass;
    // Assign "PipeType" as the subtype field.
    // Add the subtypes.
    subtypes.addSubtype(1, "Primary");
    subtypes.addSubtype(2, "Secondary");
    // Assign the default subtype code.
Assigning domains and default values to fields at the subtype level
In the next code example, the feature class also contains fields for the pipe construction material (Material) and the diameter of the pipe (Diameter). Domains have been created in the workspace to constrain the accurate criteria of these values for each of the different types of pipes (primary or secondary). 
Also, in the following example, different default values for each field based on the subtype will be assigned and the domains will be associated at the subtype level.
static void setDefaultsForSubtypes(IWorkspaceDomains workspaceDomains, ISubtypes
    subtypes)throws Exception{
    // The Diameter field in this example is an esriFieldTypeString field while
    // the Material field type is esriFieldTypeInteger.
    // Set the default value for the Diameter field on the primary subtype to 12.
    subtypes.setDefaultValue(1, "Diameter", "12");
    // Set the domain for the Material field on the primary subtype to be the PrimaryMaterials domain.
    IDomain domain_PrimaryMaterials = workspaceDomains.getDomainByName(
    subtypes.setDomainByRef(1, "Material", domain_PrimaryMaterials);
    // Assign remaining domains at the subtype level.
    IDomain domain_PrimaryDiameters = workspaceDomains.getDomainByName(
    subtypes.setDomainByRef(1, "Diameter", domain_PrimaryDiameters);
    IDomain domain_SecondaryDiameters = workspaceDomains.getDomainByName(
    subtypes.setDomainByRef(2, "Diameter", domain_SecondaryDiameters);
    IDomain domain_SecondaryMaterials = workspaceDomains.getDomainByName(
    subtypes.setDomainByRef(2, "Material", domain_SecondaryMaterials);
    // Assign the remaining default values at the subtype level.
    subtypes.setDefaultValue(1, "Material", 1); 
        // In this case, 1 represents the domain code for steel.
    subtypes.setDefaultValue(2, "Diameter", "4");
    subtypes.setDefaultValue(2, "Material", 2); 
        // In this case, 2 represents the domain code for copper.

Resetting subtypes codes
The last code example shows how you can reset the subtypes on a feature class  (or object class). When resetting the subtype codes all previously created subtypes will be removed. This is done by assigning a blank string to the SubtypeFieldName property. The code below checks if the feature class passed in has subtypes and then resets them if they were present.
static void resetSubtypes(IObjectClass objectClass)throws Exception{
    ISubtypes subtypes = (ISubtypes)objectClass;
    if (subtypes.isHasSubtype()){
        // The Subtype field can be reset by assigning an empty string to SubtypeFieldName
        System.out.println("The class has no subtype defined.");

See Also:

How to create attribute domains

Additional Requirements
  • If working in ArcSDE, an ArcEditor or greater license is required for ArcGIS Desktop, and the Geodatabase Update extension is required for ArcGIS Engine.

Development licensingDeployment licensing
ArcGIS for Desktop BasicArcGIS for Desktop Basic
ArcGIS for Desktop StandardArcGIS for Desktop Standard
ArcGIS for Desktop AdvancedArcGIS for Desktop Advanced
Engine Developer KitEngine: Geodatabase Update