Parameters are one of Revit's most important features — they drive the model's flexibility and are the primary way add-ins read and write element data. When working with them programmatically, the most important things to understand are unit types and storage types.
Unit System
Revit stores numeric parameter values in its internal unit type. For length, this is always feet — even when the project is set to display millimeters. The three unit-related concepts are:
- Storage Type — the .NET type of the stored value (
Double,Integer,String,ElementId) - Unit Type — what the parameter measures (length, area, force…). Determines the internal unit (feet for length)
- Display Unit Type — how the value is shown to the user (meters, millimeters, feet). Controlled by the project unit settings
Getting Parameters
csharp
// Get a Room to work with
Room room = new FilteredElementCollector(document)
.WherePasses(new RoomFilter())
.Cast<Room>()
.FirstOrDefault();
// Option 1: by BuiltInParameter enum
Parameter roomName = room.get_Parameter(BuiltInParameter.ROOM_NAME);
// Option 2: by display name (may return multiple — names can be duplicated across shared parameters)
List<Parameter> commentParams = room.GetParameters("Comments").ToList();
// Option 3: all parameters in display order
List<Parameter> allParams = room.GetOrderedParameters().ToList();Iterating Safely
csharp
// Iterating parameters safely — skip read-only and invalid storage types
foreach (Parameter parameter in allParams)
{
if (!parameter.UserModifiable || parameter.StorageType == StorageType.None)
continue;
// process parameter
}Reading Values
Always check StorageType before reading — calling the wrong accessor throws:
csharp
// Reading a parameter value — use the StorageType to pick the right accessor
string valueRepr = parameter.StorageType switch
{
StorageType.Double => parameter.AsDouble().ToString(),
StorageType.ElementId => parameter.AsElementId().IntegerValue.ToString(),
StorageType.Integer => parameter.AsInteger().ToString(),
_ => parameter.AsValueString() // string + formatted display
};Setting Values
csharp
// Setting a parameter value — must not be read-only
switch (parameter.StorageType)
{
case StorageType.Double:
parameter.Set(100.0);
break;
case StorageType.ElementId:
parameter.Set(new ElementId(123));
break;
case StorageType.Integer:
parameter.Set(123);
break;
default:
parameter.Set("Hello");
break;
}Displaying the Unit
Use UnitUtils.ConvertFromInternalUnits to convert the raw stored value to the display unit, and LabelUtils.GetLabelForUnit to get the unit abbreviation:
csharp
// Revit stores length parameters internally in FEET regardless of project units
// UnitUtils converts from internal to display units:
double internalValue = parameter.AsDouble();
ForgeTypeId unitType = parameter.GetUnitTypeId();
double displayValue = UnitUtils.ConvertFromInternalUnits(internalValue, unitType);
// DisplayUnitType (pre-Revit 2022) or ForgeTypeId (2022+) reflects the project unit setting
// LabelUtils.GetLabelForUnit renders the unit abbreviation (e.g. "m", "mm", "ft")
string unitLabel = LabelUtils.GetLabelForUnit(unitType);
Console.WriteLine(quot;{displayValue} {unitLabel}");