# Virtual

    @propertyWrapper
    public struct Virtual<V> : AttributeKeyPathStringConvertible, FieldAttributeProtocol

The containing type for computed property values. Because this value is not persisted to the backing store, any type is supported. `Field.Virtual` properties are not allowed to have initial values, including `nil` for optional types.

    class Animal: CoreStoreObject {

        @Field.Virtual(
            "pluralName",
            customGetter: { (object, field) in
                return object.$species.value + "s"
            }
        )
        var pluralName: String

        @Field.Stored("species")
        var species: String = ""
    }

Important

`Field` properties are required to be used as `@propertyWrapper`s. Any other declaration not using the `@Field.Virtual(...) var` syntax will be ignored.

- `init(_:customGetter:customSetter:affectedByKeyPaths:)`

  Initializes the metadata for the property. `Field.Virtual` properties are not allowed to have initial values, including `nil` for optional types.

      class Person: CoreStoreObject {

          @Field.Virtual(
              "pluralName",
              customGetter: { (object, field) in
                  return object.$species.value + "s"
              }
          )
          var pluralName: String

          @Field.Stored("species")
          var species: String = ""
      }

  #### Declaration

  Swift

      public init(
          _ keyPath: KeyPathString,
          customGetter: @escaping (_ object: ObjectProxy<O>, _ field: ObjectProxy<O>.FieldProxy<V>) -> V,
          customSetter: ((_ object: ObjectProxy<O>, _ field: ObjectProxy<O>.FieldProxy<V>, _ newValue: V) -> Void)? = nil,
          affectedByKeyPaths: @autoclosure @escaping () -> Set<KeyPathString> = [])

  #### Parameters

  `keyPath` | the permanent attribute name for this property.
  `customGetter` | use this closure as an “override” for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
  `customSetter` | use this closure as an “override” for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties’ static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
  `affectedByKeyPaths` | a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.

### AnyKeyPathStringConvertible

- `cs_keyPathString`

  #### Declaration

  Swift

      public var cs_keyPathString: String { get }

### KeyPathStringConvertible

- `ObjectType`

  #### Declaration

  Swift

      public typealias ObjectType = O

- `DestinationValueType`

  #### Declaration

  Swift

      public typealias DestinationValueType = V

### AttributeKeyPathStringConvertible

- `ReturnValueType`

  #### Declaration

  Swift

      public typealias ReturnValueType = DestinationValueType

### Available where `V`: `FieldOptionalType`

- `init(_:customGetter:customSetter:affectedByKeyPaths:)`

  Initializes the metadata for the property. `Field.Virtual` properties are not allowed to have initial values, including `nil` for optional types.

      class Person: CoreStoreObject {

          @Field.Virtual(
              "pluralName",
              customGetter: { (object, field) in
                  return object.$species.value + "s"
              }
          )
          var pluralName: String?

          @Field.Stored("species")
          var species: String = ""
      }

  #### Declaration

  Swift

      public init(
          _ keyPath: KeyPathString,
          customGetter: ((_ object: ObjectProxy<O>, _ field: ObjectProxy<O>.FieldProxy<V>) -> V)? = nil,
          customSetter: ((_ object: ObjectProxy<O>, _ field: ObjectProxy<O>.FieldProxy<V>, _ newValue: V) -> Void)? = nil,
          affectedByKeyPaths: @autoclosure @escaping () -> Set<KeyPathString> = [])

  #### Parameters

  `keyPath` | the permanent attribute name for this property.
  `customGetter` | use this closure as an “override” for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
  `customSetter` | use this closure as an “override” for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties’ static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
  `affectedByKeyPaths` | a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.