Surface int[]? ArrayDimensions on TwinCATTagDefinition + thread it through
ITwinCATClient.ReadValueAsync / WriteValueAsync. When non-null + non-empty,
AdsTwinCATClient issues a single ADS read against the symbol with
clrType.MakeArrayType() and returns the flat 1-D CLR Array; for IEC TIME /
DATE / DT / TOD element types we project per-element to the native
TimeSpan / DateTime so consumers see consistent types regardless of rank.
DiscoverAsync surfaces IsArray=true + ArrayDim=product(dims) onto
DriverAttributeInfo via a new ResolveArrayShape helper. Multi-dim shapes
flatten to the product on the wire — DriverAttributeInfo.ArrayDim is
single-uint today and the OPC UA layer reflects rank via its own metadata.
Native ADS notification subscriptions skip whole-array tags so the OPC UA
layer falls through to a polled snapshot — the per-element AdsNotificationEx
callback shape doesn't fit a flat array. Whole-array WRITES are out of
scope for this PR — AdsTwinCATClient.WriteValueAsync returns
BadNotSupported when ArrayDimensions is set.
Tests: TwinCATArrayReadTests covers ResolveArrayShape (null / empty /
single-dim / multi-dim flatten / non-positive defensive), DiscoverAsync
emitting IsArray + ArrayDim for declared array tags, single-dim + multi-dim
fake-client read fan-out, and the BadNotSupported gate on whole-array
writes. Existing 137 unit tests still pass — total now 143.
Closes#308