GH-47523: [C#] Remove csharp/ (#47547)

T### Rationale for this change

We've moved `csharp/` to https://github.com/apache/arrow-dotnet .

### What changes are included in this PR?

Remove `csharp/` and related files.

### Are these changes tested?

Yes.

### Are there any user-facing changes?

Yes.
* GitHub Issue: #47523

Authored-by: Sutou Kouhei <kou@clear-code.com>
Signed-off-by: Raúl Cumplido <raulcumplido@gmail.com>
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 79e658f..12b78f7 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -33,9 +33,8 @@
 /cpp/src/arrow/engine @westonpace
 /cpp/src/arrow/flight/ @lidavidm
 /cpp/src/parquet @wgtmac
-/csharp/ @curthagenlocher
 /matlab/ @kevingurney @kou @sgilmore10
-/python/ @AlenkaF @raulcd @rok 
+/python/ @AlenkaF @raulcd @rok
 /python/pyarrow/_flight.pyx @lidavidm
 /python/pyarrow/**/*gandiva* @wjones127
 /r/ @jonkeane @thisisnic
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 2583dfc..282a886 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -24,34 +24,3 @@
     commit-message:
       prefix: "MINOR: [CI] "
     open-pull-requests-limit: 10
-  - package-ecosystem: "gomod"
-    directory: "/swift/CDataWGo/"
-    schedule:
-      interval: "weekly"
-    commit-message:
-      prefix: "MINOR: [Swift] "
-    open-pull-requests-limit: 10
-  - package-ecosystem: "gomod"
-    directory: "/swift/data-generator/swift-datagen/"
-    schedule:
-      interval: "weekly"
-    commit-message:
-      prefix: "MINOR: [Swift] "
-    open-pull-requests-limit: 10
-  - package-ecosystem: "nuget"
-    directory: "/csharp/"
-    schedule:
-      interval: "weekly"
-    commit-message:
-      prefix: "MINOR: [C#] "
-    open-pull-requests-limit: 10
-    ignore:
-      - dependency-name: "Microsoft.Extensions.*"
-        update-types:
-          - "version-update:semver-major"
-      - dependency-name: "Microsoft.Bcl.*"
-        update-types:
-          - "version-update:semver-major"
-      - dependency-name: "System.*"
-        update-types:
-          - "version-update:semver-major"
diff --git a/.github/workflows/csharp.yml b/.github/workflows/csharp.yml
deleted file mode 100644
index ba6b473..0000000
--- a/.github/workflows/csharp.yml
+++ /dev/null
@@ -1,212 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-name: C#
-
-on:
-  push:
-    branches:
-      - '**'
-      - '!dependabot/**'
-    tags:
-      - '**'
-    paths:
-      - '.github/workflows/csharp.yml'
-      - 'ci/scripts/csharp_*'
-      - 'csharp/**'
-  pull_request:
-    paths:
-      - '.github/workflows/csharp.yml'
-      - 'ci/scripts/csharp_*'
-      - 'csharp/**'
-
-concurrency:
-  group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }}
-  cancel-in-progress: true
-
-permissions:
-  contents: read
-
-jobs:
-
-  ubuntu:
-    name: AMD64 Ubuntu 24.04 C# ${{ matrix.dotnet }}
-    runs-on: ubuntu-latest
-    if: ${{ !contains(github.event.pull_request.title, 'WIP') }}
-    timeout-minutes: 15
-    strategy:
-      fail-fast: false
-      matrix:
-        dotnet: ['8.0.x']
-    steps:
-      - name: Install C#
-        uses: actions/setup-dotnet@v4.3.1
-        with:
-          dotnet-version: ${{ matrix.dotnet }}
-      - name: Setup Python
-        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
-        with:
-          python-version: 3
-      - name: Checkout Arrow
-        uses: actions/checkout@v5
-        with:
-          fetch-depth: 0
-      - name: Build
-        shell: bash
-        run: ci/scripts/csharp_build.sh $(pwd)
-      - name: Test
-        shell: bash
-        run: ci/scripts/csharp_test.sh $(pwd)
-
-  windows:
-    name: AMD64 Windows C# ${{ matrix.dotnet }}
-    runs-on: windows-2022
-    if: ${{ !contains(github.event.pull_request.title, 'WIP') }}
-    timeout-minutes: 15
-    strategy:
-      fail-fast: false
-      matrix:
-        dotnet: ['8.0.x']
-    steps:
-      - name: Install C#
-        uses: actions/setup-dotnet@v4.3.1
-        with:
-          dotnet-version: ${{ matrix.dotnet }}
-      - name: Checkout Arrow
-        uses: actions/checkout@v5
-        with:
-          fetch-depth: 0
-      - name: Build
-        shell: bash
-        run: ci/scripts/csharp_build.sh $(pwd)
-      - name: Test
-        shell: bash
-        run: ci/scripts/csharp_test.sh $(pwd)
-
-  macos:
-    name: AMD64 macOS 13 C# ${{ matrix.dotnet }}
-    runs-on: macos-13
-    if: ${{ !contains(github.event.pull_request.title, 'WIP') }}
-    timeout-minutes: 15
-    strategy:
-      fail-fast: false
-      matrix:
-        dotnet: ['8.0.x']
-    steps:
-      - name: Install C#
-        uses: actions/setup-dotnet@v4.3.1
-        with:
-          dotnet-version: ${{ matrix.dotnet }}
-      - name: Setup Python
-        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
-        with:
-          python-version: 3.12
-      - name: Checkout Arrow
-        uses: actions/checkout@v5
-        with:
-          fetch-depth: 0
-      - name: Build
-        shell: bash
-        run: ci/scripts/csharp_build.sh $(pwd)
-      - name: Test
-        shell: bash
-        run: ci/scripts/csharp_test.sh $(pwd)
-
-  package:
-    name: Package
-    # Branch or RC tag
-    if: github.ref_type != 'tag' || contains(github.ref_name, 'rc')
-    runs-on: ubuntu-latest
-    timeout-minutes: 15
-    permissions:
-      contents: write
-    steps:
-      - name: Checkout for utilities
-        if: github.ref_type == 'tag'
-        uses: actions/checkout@v5
-        with:
-          path: arrow
-      - name: Download source archive
-        if: github.ref_type == 'tag'
-        run: |
-          arrow/dev/release/utils-watch-gh-workflow.sh \
-            ${GITHUB_REF_NAME} \
-            release_candidate.yml
-          gh release download ${GITHUB_REF_NAME} \
-            --pattern "*.tar.gz" \
-            --repo ${GITHUB_REPOSITORY}
-          tar -xf *.tar.gz --strip-components=1
-          mv csharp/dummy.git .git
-        env:
-          GH_TOKEN: ${{ github.token }}
-      - name: Checkout
-        if: github.ref_type != 'tag'
-        uses: actions/checkout@v5
-        with:
-          fetch-depth: 0
-      - name: Prepare version
-        if: github.ref_type != 'tag'
-        run: |
-          # apache-arrow-20.0.0.dev-9-g758867f907 ->
-          #              20.0.0.dev-9-g758867f907 ->
-          #              20.0.0.dev-9             ->
-          #              20.0.0-dev-9
-          semver="$(git describe --tags | \
-                     sed -E \
-                         -e 's/^apache-arrow-//' \
-                         -e 's/-[^-]*$//' \
-                         -e 's/^([0-9]*\.[0-9]*\.[0-9])\./\1-/')"
-          sed -i'' -E -e \
-            "s/^    <Version>.+<\/Version>/    <Version>${semver}<\/Version>/" \
-            csharp/Directory.Build.props
-      - name: Setup Python
-        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
-        with:
-          python-version: 3
-      - name: Setup Archery
-        run: |
-          python3 -m pip install -e 'dev/archery[docker]'
-      - name: Build
-        run: |
-          archery docker run ubuntu-csharp
-      - name: Prepare artifacts
-        run: |
-          shopt -s globstar
-          cp csharp/artifacts/**/*.{,s}nupkg ./
-          for artifact in *.{,s}nupkg; do
-            dev/release/utils-generate-checksum.sh "${artifact}"
-          done
-      - name: Upload
-        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
-        with:
-          name: nuget
-          path: |
-            *.nupkg
-            *.sha256
-            *.sha512
-            *.snupkg
-      - name: Publish
-        if: github.ref_type == 'tag'
-        run: |
-          gh release upload ${GITHUB_REF_NAME} \
-            --repo ${GITHUB_REPOSITORY} \
-            *.nupkg \
-            *.sha256 \
-            *.sha512 \
-            *.snupkg
-        env:
-          GH_TOKEN: ${{ github.token }}
diff --git a/.github/workflows/dev_pr/labeler.yml b/.github/workflows/dev_pr/labeler.yml
index 1c50b24..0950cac 100644
--- a/.github/workflows/dev_pr/labeler.yml
+++ b/.github/workflows/dev_pr/labeler.yml
@@ -25,11 +25,6 @@
   - any-glob-to-any-file:
     - c_glib/**/*
 
-"Component: C#":
-- changed-files:
-  - any-glob-to-any-file:
-    - csharp/**/*
-
 "Component: MATLAB":
 - changed-files:
   - any-glob-to-any-file:
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index d1658fb..25c5181 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -32,7 +32,6 @@
       - 'docker-compose.yml'
       - 'integration/**'
       - 'cpp/**'
-      - 'csharp/**'
       - 'format/**'
   pull_request:
     paths:
@@ -43,7 +42,6 @@
       - 'docker-compose.yml'
       - 'integration/**'
       - 'cpp/**'
-      - 'csharp/**'
       - 'format/**'
 
 concurrency:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 39efd52..502bb70 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -305,9 +305,6 @@
           ?^ci/scripts/conan_build\.sh$|
           ?^ci/scripts/conan_setup\.sh$|
           ?^ci/scripts/cpp_test\.sh$|
-          ?^ci/scripts/csharp_build\.sh$|
-          ?^ci/scripts/csharp_pack\.sh$|
-          ?^ci/scripts/csharp_test\.sh$|
           ?^ci/scripts/download_tz_database\.sh$|
           ?^ci/scripts/install_azurite\.sh$|
           ?^ci/scripts/install_ccache\.sh$|
diff --git a/README.md b/README.md
index f31dee9..49d56fe 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@
    Arrow data with application-defined semantics (for example a storage server or a database)
  - [C++ libraries](https://github.com/apache/arrow/tree/main/cpp)
  - [C bindings using GLib](https://github.com/apache/arrow/tree/main/c_glib)
- - [C# .NET libraries](https://github.com/apache/arrow/tree/main/csharp)
+ - [.NET libraries](https://github.com/apache/arrow-dotnet)
  - [Gandiva](https://github.com/apache/arrow/tree/main/cpp/src/gandiva):
    an [LLVM](https://llvm.org)-based Arrow expression compiler, part of the C++ codebase
  - [Go libraries](https://github.com/apache/arrow-go) `↗`
diff --git a/ci/scripts/csharp_build.sh b/ci/scripts/csharp_build.sh
deleted file mode 100755
index f90233f..0000000
--- a/ci/scripts/csharp_build.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -ex
-
-source_dir=${1}/csharp
-
-pushd "${source_dir}"
-dotnet build
-popd
diff --git a/ci/scripts/csharp_pack.sh b/ci/scripts/csharp_pack.sh
deleted file mode 100755
index 9849df6..0000000
--- a/ci/scripts/csharp_pack.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -eux
-
-source_dir=${1}/csharp
-
-pushd "${source_dir}"
-dotnet pack -c Release
-popd
diff --git a/ci/scripts/csharp_test.sh b/ci/scripts/csharp_test.sh
deleted file mode 100755
index f521afc..0000000
--- a/ci/scripts/csharp_test.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -ex
-
-source_dir=${1}/csharp
-
-# Python and PyArrow are required for C Data Interface tests.
-if [ -z "${PYTHON}" ]; then
-  if type python3 > /dev/null 2>&1; then
-    export PYTHON=python3
-  else
-    export PYTHON=python
-  fi
-fi
-${PYTHON} -m pip install pyarrow find-libpython
-PYTHONNET_PYDLL=$(${PYTHON} -m find_libpython)
-export PYTHONNET_PYDLL
-
-pushd "${source_dir}"
-dotnet test
-popd
diff --git a/csharp/.editorconfig b/csharp/.editorconfig
deleted file mode 100644
index 01506a0..0000000
--- a/csharp/.editorconfig
+++ /dev/null
@@ -1,169 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-root = true
-
-# Default settings:
-# A newline ending every file
-# Use 4 spaces as indentation
-[*]
-insert_final_newline = true
-indent_style = space
-indent_size = 4
-trim_trailing_whitespace = true
-
-# C# files
-[*.cs]
-# New line preferences
-csharp_new_line_before_open_brace = all
-csharp_new_line_before_else = true
-csharp_new_line_before_catch = true
-csharp_new_line_before_finally = true
-csharp_new_line_before_members_in_object_initializers = true
-csharp_new_line_before_members_in_anonymous_types = true
-csharp_new_line_between_query_expression_clauses = true
-
-# Indentation preferences
-csharp_indent_block_contents = true
-csharp_indent_braces = false
-csharp_indent_case_contents = true
-csharp_indent_case_contents_when_block = true
-csharp_indent_switch_labels = true
-csharp_indent_labels = one_less_than_current
-
-# Modifier preferences
-csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
-
-# avoid this. unless absolutely necessary
-dotnet_style_qualification_for_field = false:suggestion
-dotnet_style_qualification_for_property = false:suggestion
-dotnet_style_qualification_for_method = false:suggestion
-dotnet_style_qualification_for_event = false:suggestion
-
-# Types: use keywords instead of BCL types, and permit var only when the type is clear
-csharp_style_var_for_built_in_types = false:suggestion
-csharp_style_var_when_type_is_apparent = false:none
-csharp_style_var_elsewhere = false:suggestion
-dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
-dotnet_style_predefined_type_for_member_access = true:suggestion
-
-# name all constant fields using PascalCase
-dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
-dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols  = constant_fields
-dotnet_naming_rule.constant_fields_should_be_pascal_case.style    = pascal_case_style
-dotnet_naming_symbols.constant_fields.applicable_kinds   = field
-dotnet_naming_symbols.constant_fields.required_modifiers = const
-dotnet_naming_style.pascal_case_style.capitalization = pascal_case
-
-# static fields should have s_ prefix
-dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
-dotnet_naming_rule.static_fields_should_have_prefix.symbols  = static_fields
-dotnet_naming_rule.static_fields_should_have_prefix.style    = static_prefix_style
-dotnet_naming_symbols.static_fields.applicable_kinds   = field
-dotnet_naming_symbols.static_fields.required_modifiers = static
-dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
-dotnet_naming_style.static_prefix_style.required_prefix = s_
-dotnet_naming_style.static_prefix_style.capitalization = camel_case 
-
-# internal and private fields should be _camelCase
-dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
-dotnet_naming_rule.camel_case_for_private_internal_fields.symbols  = private_internal_fields
-dotnet_naming_rule.camel_case_for_private_internal_fields.style    = camel_case_underscore_style
-dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
-dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
-dotnet_naming_style.camel_case_underscore_style.required_prefix = _
-dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case 
-
-# Code style defaults
-csharp_using_directive_placement = outside_namespace:suggestion
-dotnet_sort_system_directives_first = true
-csharp_prefer_braces = true:refactoring
-csharp_preserve_single_line_blocks = true:none
-csharp_preserve_single_line_statements = false:none
-csharp_prefer_static_local_function = true:suggestion
-csharp_prefer_simple_using_statement = false:none
-csharp_style_prefer_switch_expression = true:suggestion
-
-# Code quality
-dotnet_style_readonly_field = true:suggestion
-dotnet_code_quality_unused_parameters = non_public:suggestion
-
-# Expression-level preferences
-dotnet_style_object_initializer = true:suggestion
-dotnet_style_collection_initializer = true:suggestion
-dotnet_style_explicit_tuple_names = true:suggestion
-dotnet_style_coalesce_expression = true:suggestion
-dotnet_style_null_propagation = true:suggestion
-dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
-dotnet_style_prefer_inferred_tuple_names = true:suggestion
-dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
-dotnet_style_prefer_auto_properties = true:suggestion
-dotnet_style_prefer_conditional_expression_over_assignment = true:refactoring
-dotnet_style_prefer_conditional_expression_over_return = true:refactoring
-csharp_prefer_simple_default_expression = true:suggestion
-
-# Expression-bodied members
-csharp_style_expression_bodied_methods = true:refactoring
-csharp_style_expression_bodied_constructors = true:refactoring
-csharp_style_expression_bodied_operators = true:refactoring
-csharp_style_expression_bodied_properties = true:refactoring
-csharp_style_expression_bodied_indexers = true:refactoring
-csharp_style_expression_bodied_accessors = true:refactoring
-csharp_style_expression_bodied_lambdas = true:refactoring
-csharp_style_expression_bodied_local_functions = true:refactoring
-
-# Pattern matching
-csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
-csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
-csharp_style_inlined_variable_declaration = true:suggestion
-
-# Null checking preferences
-csharp_style_throw_expression = true:suggestion
-csharp_style_conditional_delegate_call = true:suggestion
-
-# Other features
-csharp_style_prefer_index_operator = false:none
-csharp_style_prefer_range_operator = false:none
-csharp_style_pattern_local_over_anonymous_function = false:none
-
-# Space preferences
-csharp_space_after_cast = false
-csharp_space_after_colon_in_inheritance_clause = true
-csharp_space_after_comma = true
-csharp_space_after_dot = false
-csharp_space_after_keywords_in_control_flow_statements = true
-csharp_space_after_semicolon_in_for_statement = true
-csharp_space_around_binary_operators = before_and_after
-csharp_space_around_declaration_statements = do_not_ignore
-csharp_space_before_colon_in_inheritance_clause = true
-csharp_space_before_comma = false
-csharp_space_before_dot = false
-csharp_space_before_open_square_brackets = false
-csharp_space_before_semicolon_in_for_statement = false
-csharp_space_between_empty_square_brackets = false
-csharp_space_between_method_call_empty_parameter_list_parentheses = false
-csharp_space_between_method_call_name_and_opening_parenthesis = false
-csharp_space_between_method_call_parameter_list_parentheses = false
-csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
-csharp_space_between_method_declaration_name_and_open_parenthesis = false
-csharp_space_between_method_declaration_parameter_list_parentheses = false
-csharp_space_between_parentheses = false
-csharp_space_between_square_brackets = false
-
-# Xml project files
-[*.{csproj,props,targets}]
-indent_size = 2
-charset = utf-8
diff --git a/csharp/.gitattributes b/csharp/.gitattributes
deleted file mode 100644
index d2ff52b..0000000
--- a/csharp/.gitattributes
+++ /dev/null
@@ -1,36 +0,0 @@
-###############################################################################
-# Set default behavior to automatically normalize line endings.
-###############################################################################
-* text=auto
-
-###############################################################################
-# Set default behavior for command prompt diff.
-#
-# This is need for earlier builds of msysgit that does not have it on by
-# default for csharp files.
-# Note: This is only used by command line
-###############################################################################
-#*.cs     diff=csharp
-
-###############################################################################
-# Set the merge driver for project and solution files
-#
-# Merging from the command prompt will add diff markers to the files if there
-# are conflicts (Merging from VS is not affected by the settings below, in VS
-# the diff markers are never inserted). Diff markers may cause the following
-# file extensions to fail to load in VS. An alternative would be to treat
-# these files as binary and thus will always conflict and require user
-# intervention with every merge. To do so, just uncomment the entries below
-###############################################################################
-#*.sln       merge=binary
-#*.csproj    merge=binary
-#*.vbproj    merge=binary
-#*.vcxproj   merge=binary
-#*.vcproj    merge=binary
-#*.dbproj    merge=binary
-#*.fsproj    merge=binary
-#*.lsproj    merge=binary
-#*.wixproj   merge=binary
-#*.modelproj merge=binary
-#*.sqlproj   merge=binary
-#*.wwaproj   merge=binary
\ No newline at end of file
diff --git a/csharp/.gitignore b/csharp/.gitignore
deleted file mode 100644
index a9fbd58..0000000
--- a/csharp/.gitignore
+++ /dev/null
@@ -1,267 +0,0 @@
-## Ignore Visual Studio temporary files, build results, and
-## files generated by popular Visual Studio add-ons.
-
-# User-specific files
-*.suo
-*.user
-*.userosscache
-*.sln.docstates
-
-# User-specific files (MonoDevelop/Xamarin Studio)
-*.userprefs
-
-# Build results
-[Dd]ebug/
-[Dd]ebugPublic/
-[Rr]elease/
-[Rr]eleases/
-x64/
-x86/
-bld/
-[Bb]in/
-[Oo]bj/
-[Ll]og/
-
-# Visual Studio 2015 cache/options directory
-.vs/
-# Uncomment if you have tasks that create the project's static files in wwwroot
-#wwwroot/
-
-# MSTest test Results
-[Tt]est[Rr]esult*/
-[Bb]uild[Ll]og.*
-
-# NUNIT
-*.VisualState.xml
-TestResult.xml
-
-# Build Results of an ATL Project
-[Dd]ebugPS/
-[Rr]eleasePS/
-dlldata.c
-
-# DNX
-project.lock.json
-project.fragment.lock.json
-artifacts/
-
-*_i.c
-*_p.c
-*_i.h
-*.ilk
-*.meta
-*.obj
-*.pch
-*.pdb
-*.pgc
-*.pgd
-*.rsp
-*.sbr
-*.tlb
-*.tli
-*.tlh
-*.tmp
-*.tmp_proj
-*.log
-*.vspscc
-*.vssscc
-.builds
-*.pidb
-*.svclog
-*.scc
-
-# Chutzpah Test files
-_Chutzpah*
-
-# Visual C++ cache files
-ipch/
-*.aps
-*.ncb
-*.opendb
-*.opensdf
-*.sdf
-*.cachefile
-*.VC.db
-*.VC.VC.opendb
-
-# Visual Studio profiler
-*.psess
-*.vsp
-*.vspx
-*.sap
-
-# TFS 2012 Local Workspace
-$tf/
-
-# Guidance Automation Toolkit
-*.gpState
-
-# ReSharper is a .NET coding add-in
-_ReSharper*/
-*.[Rr]e[Ss]harper
-*.DotSettings.user
-
-# JustCode is a .NET coding add-in
-.JustCode
-
-# TeamCity is a build add-in
-_TeamCity*
-
-# DotCover is a Code Coverage Tool
-*.dotCover
-
-# NCrunch
-_NCrunch_*
-.*crunch*.local.xml
-nCrunchTemp_*
-
-# MightyMoose
-*.mm.*
-AutoTest.Net/
-
-# Web workbench (sass)
-.sass-cache/
-
-# Installshield output folder
-[Ee]xpress/
-
-# DocProject is a documentation generator add-in
-DocProject/buildhelp/
-DocProject/Help/*.HxT
-DocProject/Help/*.HxC
-DocProject/Help/*.hhc
-DocProject/Help/*.hhk
-DocProject/Help/*.hhp
-DocProject/Help/Html2
-DocProject/Help/html
-
-# Click-Once directory
-publish/
-
-# Publish Web Output
-*.[Pp]ublish.xml
-*.azurePubxml
-# TODO: Comment the next line if you want to checkin your web deploy settings
-# but database connection strings (with potential passwords) will be unencrypted
-#*.pubxml
-*.publishproj
-
-# Microsoft Azure Web App publish settings. Comment the next line if you want to
-# checkin your Azure Web App publish settings, but sensitive information contained
-# in these scripts will be unencrypted
-PublishScripts/
-
-# NuGet Packages
-*.nupkg
-# The packages folder can be ignored because of Package Restore
-**/packages/*
-# except build/, which is used as an MSBuild target.
-!**/packages/build/
-# Uncomment if necessary however generally it will be regenerated when needed
-#!**/packages/repositories.config
-# NuGet v3's project.json files produces more ignorable files
-*.nuget.props
-*.nuget.targets
-
-# Microsoft Azure Build Output
-csx/
-*.build.csdef
-
-# Microsoft Azure Emulator
-ecf/
-rcf/
-
-# Windows Store app package directories and files
-AppPackages/
-BundleArtifacts/
-Package.StoreAssociation.xml
-_pkginfo.txt
-
-# Visual Studio cache files
-# files ending in .cache can be ignored
-*.[Cc]ache
-# but keep track of directories ending in .cache
-!*.[Cc]ache/
-
-# Others
-ClientBin/
-~$*
-*~
-*.dbmdl
-*.dbproj.schemaview
-*.jfm
-*.pfx
-*.publishsettings
-node_modules/
-orleans.codegen.cs
-
-# Since there are multiple workflows, uncomment next line to ignore bower_components
-# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
-#bower_components/
-
-# RIA/Silverlight projects
-Generated_Code/
-
-# Backup & report files from converting an old project file
-# to a newer Visual Studio version. Backup files are not needed,
-# because we have git ;-)
-_UpgradeReport_Files/
-Backup*/
-UpgradeLog*.XML
-UpgradeLog*.htm
-
-# SQL Server files
-*.mdf
-*.ldf
-
-# Business Intelligence projects
-*.rdl.data
-*.bim.layout
-*.bim_*.settings
-
-# Microsoft Fakes
-FakesAssemblies/
-
-# GhostDoc plugin setting file
-*.GhostDoc.xml
-
-# Node.js Tools for Visual Studio
-.ntvs_analysis.dat
-
-# Visual Studio 6 build log
-*.plg
-
-# Visual Studio 6 workspace options file
-*.opt
-
-# Visual Studio LightSwitch build output
-**/*.HTMLClient/GeneratedArtifacts
-**/*.DesktopClient/GeneratedArtifacts
-**/*.DesktopClient/ModelManifest.xml
-**/*.Server/GeneratedArtifacts
-**/*.Server/ModelManifest.xml
-_Pvt_Extensions
-
-# Paket dependency manager
-.paket/paket.exe
-paket-files/
-
-# FAKE - F# Make
-.fake/
-
-# JetBrains Rider
-.idea/
-*.sln.iml
-
-# CodeRush
-.cr/
-
-# Python Tools for Visual Studio (PTVS)
-__pycache__/
-*.pyc
-
-# Project-specific
-artifacts/
-
-# add .sln files back because they are ignored by the root .gitignore file
-!*.sln
diff --git a/csharp/Apache.Arrow.sln b/csharp/Apache.Arrow.sln
deleted file mode 100644
index 0dd6853..0000000
--- a/csharp/Apache.Arrow.sln
+++ /dev/null
@@ -1,97 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29926.136
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Arrow", "src\Apache.Arrow\Apache.Arrow.csproj", "{BA6B2B0D-EAAE-4183-8A39-1B9CF571F71F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Arrow.Tests", "test\Apache.Arrow.Tests\Apache.Arrow.Tests.csproj", "{9CCEC01B-E67A-4726-BE72-7B514F76163F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Arrow.Benchmarks", "test\Apache.Arrow.Benchmarks\Apache.Arrow.Benchmarks.csproj", "{742DF47D-77C5-4B84-9E0C-69645F1161EA}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Arrow.Flight.Tests", "test\Apache.Arrow.Flight.Tests\Apache.Arrow.Flight.Tests.csproj", "{D6443535-3740-4F6C-8001-F90EDAF4CF0C}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Arrow.Flight.TestWeb", "test\Apache.Arrow.Flight.TestWeb\Apache.Arrow.Flight.TestWeb.csproj", "{058F9CFA-2A13-43B8-87D9-E69F63F9EFF0}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Arrow.Flight", "src\Apache.Arrow.Flight\Apache.Arrow.Flight.csproj", "{2490AA1E-DDA4-4069-B065-79A4897B0582}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Arrow.Flight.AspNetCore", "src\Apache.Arrow.Flight.AspNetCore\Apache.Arrow.Flight.AspNetCore.csproj", "{E4F74938-E8FF-4AC1-A495-FEE95FC1EFDF}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Arrow.Compression", "src\Apache.Arrow.Compression\Apache.Arrow.Compression.csproj", "{B62E77D2-D0B0-4C0C-BA78-1C117DE4C299}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Arrow.Compression.Tests", "test\Apache.Arrow.Compression.Tests\Apache.Arrow.Compression.Tests.csproj", "{5D7FF380-B7DF-4752-B415-7C08C70C9F06}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Flight.Sql.Tests", "test\Apache.Arrow.Flight.Sql.Tests\Apache.Arrow.Flight.Sql.Tests.csproj", "{DCC99EB1-4E60-4F0D-AEA9-C44A4C0C8B1D}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Flight.Sql", "src\Apache.Arrow.Flight.Sql\Apache.Arrow.Flight.Sql.csproj", "{2ADE087A-B424-4895-8CC5-10170D10BA62}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Flight.IntegrationTest", "test\Apache.Arrow.Flight.IntegrationTest\Apache.Arrow.Flight.IntegrationTest.csproj", "{7E66CBB4-D921-41E7-A98A-7C6DEA521696}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Arrow.IntegrationTest", "test\Apache.Arrow.IntegrationTest\Apache.Arrow.IntegrationTest.csproj", "{E8264B7F-B680-4A55-939B-85DB628164BB}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{BA6B2B0D-EAAE-4183-8A39-1B9CF571F71F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{BA6B2B0D-EAAE-4183-8A39-1B9CF571F71F}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{BA6B2B0D-EAAE-4183-8A39-1B9CF571F71F}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{BA6B2B0D-EAAE-4183-8A39-1B9CF571F71F}.Release|Any CPU.Build.0 = Release|Any CPU
-		{9CCEC01B-E67A-4726-BE72-7B514F76163F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{9CCEC01B-E67A-4726-BE72-7B514F76163F}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{9CCEC01B-E67A-4726-BE72-7B514F76163F}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{9CCEC01B-E67A-4726-BE72-7B514F76163F}.Release|Any CPU.Build.0 = Release|Any CPU
-		{742DF47D-77C5-4B84-9E0C-69645F1161EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{742DF47D-77C5-4B84-9E0C-69645F1161EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{742DF47D-77C5-4B84-9E0C-69645F1161EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{742DF47D-77C5-4B84-9E0C-69645F1161EA}.Release|Any CPU.Build.0 = Release|Any CPU
-		{D6443535-3740-4F6C-8001-F90EDAF4CF0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{D6443535-3740-4F6C-8001-F90EDAF4CF0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{D6443535-3740-4F6C-8001-F90EDAF4CF0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{D6443535-3740-4F6C-8001-F90EDAF4CF0C}.Release|Any CPU.Build.0 = Release|Any CPU
-		{058F9CFA-2A13-43B8-87D9-E69F63F9EFF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{058F9CFA-2A13-43B8-87D9-E69F63F9EFF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{058F9CFA-2A13-43B8-87D9-E69F63F9EFF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{058F9CFA-2A13-43B8-87D9-E69F63F9EFF0}.Release|Any CPU.Build.0 = Release|Any CPU
-		{2490AA1E-DDA4-4069-B065-79A4897B0582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{2490AA1E-DDA4-4069-B065-79A4897B0582}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{2490AA1E-DDA4-4069-B065-79A4897B0582}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{2490AA1E-DDA4-4069-B065-79A4897B0582}.Release|Any CPU.Build.0 = Release|Any CPU
-		{E4F74938-E8FF-4AC1-A495-FEE95FC1EFDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{E4F74938-E8FF-4AC1-A495-FEE95FC1EFDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{E4F74938-E8FF-4AC1-A495-FEE95FC1EFDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{E4F74938-E8FF-4AC1-A495-FEE95FC1EFDF}.Release|Any CPU.Build.0 = Release|Any CPU
-		{E8264B7F-B680-4A55-939B-85DB628164BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{E8264B7F-B680-4A55-939B-85DB628164BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{E8264B7F-B680-4A55-939B-85DB628164BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{E8264B7F-B680-4A55-939B-85DB628164BB}.Release|Any CPU.Build.0 = Release|Any CPU
-		{B62E77D2-D0B0-4C0C-BA78-1C117DE4C299}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{B62E77D2-D0B0-4C0C-BA78-1C117DE4C299}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{B62E77D2-D0B0-4C0C-BA78-1C117DE4C299}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{B62E77D2-D0B0-4C0C-BA78-1C117DE4C299}.Release|Any CPU.Build.0 = Release|Any CPU
-		{5D7FF380-B7DF-4752-B415-7C08C70C9F06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{5D7FF380-B7DF-4752-B415-7C08C70C9F06}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{5D7FF380-B7DF-4752-B415-7C08C70C9F06}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{5D7FF380-B7DF-4752-B415-7C08C70C9F06}.Release|Any CPU.Build.0 = Release|Any CPU
-		{DCC99EB1-4E60-4F0D-AEA9-C44A4C0C8B1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{DCC99EB1-4E60-4F0D-AEA9-C44A4C0C8B1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{DCC99EB1-4E60-4F0D-AEA9-C44A4C0C8B1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{DCC99EB1-4E60-4F0D-AEA9-C44A4C0C8B1D}.Release|Any CPU.Build.0 = Release|Any CPU
-		{2ADE087A-B424-4895-8CC5-10170D10BA62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{2ADE087A-B424-4895-8CC5-10170D10BA62}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{2ADE087A-B424-4895-8CC5-10170D10BA62}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{2ADE087A-B424-4895-8CC5-10170D10BA62}.Release|Any CPU.Build.0 = Release|Any CPU
-		{7E66CBB4-D921-41E7-A98A-7C6DEA521696}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{7E66CBB4-D921-41E7-A98A-7C6DEA521696}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{7E66CBB4-D921-41E7-A98A-7C6DEA521696}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{7E66CBB4-D921-41E7-A98A-7C6DEA521696}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-		SolutionGuid = {FD0BB617-6031-4844-B99D-B331E335B572}
-	EndGlobalSection
-EndGlobal
diff --git a/csharp/ApacheArrow.snk b/csharp/ApacheArrow.snk
deleted file mode 100644
index 68df439..0000000
--- a/csharp/ApacheArrow.snk
+++ /dev/null
Binary files differ
diff --git a/csharp/Directory.Build.props b/csharp/Directory.Build.props
deleted file mode 100644
index 65afde5..0000000
--- a/csharp/Directory.Build.props
+++ /dev/null
@@ -1,62 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements. See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-
-<Project>
-
-  <!-- Common repo directories -->
-  <PropertyGroup>
-    <RepoRoot>$(MSBuildThisFileDirectory)../</RepoRoot>
-    <CSharpDir>$(MSBuildThisFileDirectory)</CSharpDir>
-    <BaseOutputPath>$(CSharpDir)/artifacts/$(MSBuildProjectName)</BaseOutputPath>
-  </PropertyGroup>
-
-  <!-- AssemblyInfo properties -->
-  <PropertyGroup>
-    <Product>Apache Arrow library</Product>
-    <Copyright>Copyright 2016-2024 The Apache Software Foundation</Copyright>
-    <Company>The Apache Software Foundation</Company>
-    <Version>22.0.0-SNAPSHOT</Version>
-  </PropertyGroup>
-
-  <PropertyGroup>
-    <EmbedUntrackedSources>true</EmbedUntrackedSources>
-    <LangVersion>latest</LangVersion>
-    <SignAssembly>true</SignAssembly>
-    <AssemblyOriginatorKeyFile>$(CSharpDir)ApacheArrow.snk</AssemblyOriginatorKeyFile>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-
-  <!-- NuGet properties -->
-  <PropertyGroup>
-    <Authors>The Apache Software Foundation</Authors>
-    <PackageIcon>feather.png</PackageIcon>
-    <!-- We can't use PackageLicenseExpression; the license file also contains 3rd-party notices. -->
-    <PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
-    <PackageProjectUrl>https://arrow.apache.org/</PackageProjectUrl>
-    <PackageTags>apache arrow</PackageTags>
-    <RepositoryType>git</RepositoryType>
-    <RepositoryUrl>https://github.com/apache/arrow</RepositoryUrl>
-    <IncludeSymbols>true</IncludeSymbols>
-    <SymbolPackageFormat>snupkg</SymbolPackageFormat>
-  </PropertyGroup>
-
-  <ItemGroup Condition="'$(IsPackable)' == 'true'">
-    <Content Include="$(RepoRoot)LICENSE.txt" Pack="true" PackagePath="" />
-    <Content Include="$(CSharpDir)/feather.png" Link="feather.png" Pack="true" PackagePath="\" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/Directory.Build.targets b/csharp/Directory.Build.targets
deleted file mode 100644
index 498c752..0000000
--- a/csharp/Directory.Build.targets
+++ /dev/null
@@ -1,29 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements. See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-
-<Project>
-
-  <!-- The following works around https://github.com/dotnet/sourcelink/issues/572  -->
-  <PropertyGroup>
-    <TargetFrameworkMonikerAssemblyAttributesPath>$([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))</TargetFrameworkMonikerAssemblyAttributesPath>
-  </PropertyGroup>
-  <ItemGroup>
-    <EmbeddedFiles Include="$(GeneratedAssemblyInfoFile)"/>
-    <EmbeddedFiles Include="$(TargetFrameworkMonikerAssemblyAttributesPath)"/>
-  </ItemGroup>
-  
-</Project>
diff --git a/csharp/README.md b/csharp/README.md
deleted file mode 100644
index 663aaf8..0000000
--- a/csharp/README.md
+++ /dev/null
@@ -1,198 +0,0 @@
-<!---
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-
-# Apache Arrow
-
-An implementation of Arrow targeting .NET Standard.
-
-See our current [feature matrix](https://github.com/apache/arrow/blob/main/docs/source/status.rst)
-for currently available features.
-
-# Implementation
-
-- Arrow specification 1.0.0. (Support for reading 0.11+.)
-- C# 11
-- .NET Standard 2.0 and .NET 6.0
-- Asynchronous I/O
-- Uses modern .NET runtime features such as **Span&lt;T&gt;**, **Memory&lt;T&gt;**, **MemoryManager&lt;T&gt;**, and **System.Buffers** primitives for memory allocation, memory storage, and fast serialization.
-- Uses **Acyclic Visitor Pattern** for array types and arrays to facilitate serialization, record batch traversal, and format growth.
-
-# Known Issues
-
-- Cannot read Arrow files containing tensors.
-- Cannot easily modify allocation strategy without implementing a custom memory pool. All allocations are currently 64-byte aligned and padded to 8-bytes.
-- Default memory allocation strategy uses an over-allocation strategy with pointer fixing, which results in significant memory overhead for small buffers. A buffer that requires a single byte for storage may be backed by an allocation of up to 64-bytes to satisfy alignment requirements.
-- There are currently few builder APIs available for specific array types. Arrays must be built manually with an arrow buffer builder abstraction.
-- FlatBuffer code generation is not included in the build process.
-- Serialization implementation does not perform exhaustive validation checks during deserialization in every scenario.
-- Throws exceptions with vague, inconsistent, or non-localized messages in many situations
-- Throws exceptions that are non-specific to the Arrow implementation in some circumstances where it probably should (eg. does not throw ArrowException exceptions)
-- Lack of code documentation
-- Lack of usage examples
-
-# Usage
-
-	using System.Diagnostics;
-	using System.IO;
-	using System.Threading.Tasks;
-	using Apache.Arrow;
-	using Apache.Arrow.Ipc;
-
-    public static async Task<RecordBatch> ReadArrowAsync(string filename)
-    {
-        using (var stream = File.OpenRead(filename))
-        using (var reader = new ArrowFileReader(stream))
-        {
-            var recordBatch = await reader.ReadNextRecordBatchAsync();
-            Debug.WriteLine("Read record batch with {0} column(s)", recordBatch.ColumnCount);
-            return recordBatch;
-        }
-    }
-
-
-# Status
-
-## Memory Management
-
-- Allocations are 64-byte aligned and padded to 8-bytes.
-- Allocations are automatically garbage collected
-
-## Arrays
-
-### Primitive Types
-
-- Int8, Int16, Int32, Int64
-- UInt8, UInt16, UInt32, UInt64
-- Float, Double, Half-float (.NET 6+)
-- Binary (variable-length)
-- String (utf-8)
-- Null
-
-### Parametric Types
-
-- Timestamp
-- Date32
-- Date64
-- Decimal
-- Time32
-- Time64
-- Binary (fixed-length)
-- List
-- Struct
-- Union
-- Map
-- Duration
-- Interval
-
-### Type Metadata
-
-- Data Types
-- Fields
-- Schema
-
-### Serialization
-
-- File
-- Stream
-
-## IPC Format
-
-### Compression
-
-- Buffer compression and decompression is supported, but requires installing the `Apache.Arrow.Compression` package.
-  When reading compressed data, you must pass an `Apache.Arrow.Compression.CompressionCodecFactory` instance to the
-  `ArrowFileReader` or `ArrowStreamReader` constructor, and when writing compressed data a
-  `CompressionCodecFactory` must be set in the `IpcOptions`.
-  Alternatively, a custom implementation of `ICompressionCodecFactory` can be used.
-
-## Not Implemented
-
-- Serialization
-    - Exhaustive validation
-    - Run End Encoding
-- Types
-    - Tensor
-- Arrays
-    - Large Arrays. There are large array types provided to help with interoperability with other libraries,
-      but these do not support buffers larger than 2 GiB and an exception will be raised if trying to import an array that is too large.
-        - Large Binary
-        - Large List
-        - Large String
-    - Views
-        - Binary
-        - List
-        - String
-        - Large Binary
-        - Large List
-        - Large String
-- Array Operations
-	- Equality / Comparison
-	- Casting
-- Compute
-    - There is currently no API available for a compute / kernel abstraction.
-
-# Build
-
-Install the latest `.NET Core SDK` from https://dotnet.microsoft.com/download.
-
-    dotnet build
-
-## NuGet Build
-
-To build the NuGet package run the following command to build a debug flavor, preview package into the **artifacts** folder.
-
-    dotnet pack
-
-When building the officially released version run: (see Note below about current `git` repository)
-
-    dotnet pack -c Release
-
-Which will build the final/stable package.
-
-NOTE: When building the officially released version, ensure that your `git` repository has the `origin` remote set to `https://github.com/apache/arrow.git`, which will ensure Source Link is set correctly. See https://github.com/dotnet/sourcelink/blob/main/docs/README.md for more information.
-
-There are two output artifacts:
-1. `Apache.Arrow.<version>.nupkg` - this contains the executable assemblies
-2. `Apache.Arrow.<version>.snupkg` - this contains the debug symbols files
-
-Both of these artifacts can then be uploaded to https://www.nuget.org/packages/manage/upload.
-
-## Docker Build
-
-Build from the Apache Arrow project root.
-
-    docker build -f csharp/build/docker/Dockerfile .
-
-## Testing
-
-	dotnet test
-
-All build artifacts are placed in the **artifacts** folder in the project root.
-
-# Coding Style
-
-This project follows the coding style specified in [Coding Style](https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/coding-style.md).
-
-# Updating FlatBuffers code
-
-See https://google.github.io/flatbuffers/flatbuffers_guide_use_java_c-sharp.html for how to get the `flatc` executable.
-
-Run `flatc --csharp` on each `.fbs` file in the [format](../format) folder. And replace the checked in `.cs` files under [FlatBuf](src/Apache.Arrow/Flatbuf) with the generated files.
-
-Update the non-generated [FlatBuffers](src/Apache.Arrow/Flatbuf/FlatBuffers) `.cs` files with the files from the [google/flatbuffers repo](https://github.com/google/flatbuffers/tree/master/net/FlatBuffers).
diff --git a/csharp/examples/Examples.sln b/csharp/examples/Examples.sln
deleted file mode 100644
index fbbac01..0000000
--- a/csharp/examples/Examples.sln
+++ /dev/null
@@ -1,55 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.12.35707.178 d17.12
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentBuilderExample", "FluentBuilderExample\FluentBuilderExample.csproj", "{ECE22119-D91D-44F7-9575-85B98F946289}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.Arrow", "..\src\Apache.Arrow\Apache.Arrow.csproj", "{1FE1DE95-FF6E-4895-82E7-909713C53524}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightAspServerExample", "FlightAspServerExample\FlightAspServerExample.csproj", "{16FF9B95-1E65-4285-9A78-463A71823D3C}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightClientExample", "FlightClientExample\FlightClientExample.csproj", "{8D19CF7A-3DAB-41D0-94B1-20892C4EACB8}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Flight", "..\src\Apache.Arrow.Flight\Apache.Arrow.Flight.csproj", "{9D5029EC-CFF6-4A0C-A03D-CC534A54C6BB}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Flight.AspNetCore", "..\src\Apache.Arrow.Flight.AspNetCore\Apache.Arrow.Flight.AspNetCore.csproj", "{6F2FA3F3-1B33-4742-99C2-B728CBD27861}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{ECE22119-D91D-44F7-9575-85B98F946289}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{ECE22119-D91D-44F7-9575-85B98F946289}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{ECE22119-D91D-44F7-9575-85B98F946289}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{ECE22119-D91D-44F7-9575-85B98F946289}.Release|Any CPU.Build.0 = Release|Any CPU
-		{1FE1DE95-FF6E-4895-82E7-909713C53524}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{1FE1DE95-FF6E-4895-82E7-909713C53524}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{1FE1DE95-FF6E-4895-82E7-909713C53524}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{1FE1DE95-FF6E-4895-82E7-909713C53524}.Release|Any CPU.Build.0 = Release|Any CPU
-		{16FF9B95-1E65-4285-9A78-463A71823D3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{16FF9B95-1E65-4285-9A78-463A71823D3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{16FF9B95-1E65-4285-9A78-463A71823D3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{16FF9B95-1E65-4285-9A78-463A71823D3C}.Release|Any CPU.Build.0 = Release|Any CPU
-		{8D19CF7A-3DAB-41D0-94B1-20892C4EACB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{8D19CF7A-3DAB-41D0-94B1-20892C4EACB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{8D19CF7A-3DAB-41D0-94B1-20892C4EACB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{8D19CF7A-3DAB-41D0-94B1-20892C4EACB8}.Release|Any CPU.Build.0 = Release|Any CPU
-		{9D5029EC-CFF6-4A0C-A03D-CC534A54C6BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{9D5029EC-CFF6-4A0C-A03D-CC534A54C6BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{9D5029EC-CFF6-4A0C-A03D-CC534A54C6BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{9D5029EC-CFF6-4A0C-A03D-CC534A54C6BB}.Release|Any CPU.Build.0 = Release|Any CPU
-		{6F2FA3F3-1B33-4742-99C2-B728CBD27861}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{6F2FA3F3-1B33-4742-99C2-B728CBD27861}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{6F2FA3F3-1B33-4742-99C2-B728CBD27861}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{6F2FA3F3-1B33-4742-99C2-B728CBD27861}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-		SolutionGuid = {C22A81AD-8B64-4D7C-97AC-49E9F118AE78}
-	EndGlobalSection
-EndGlobal
diff --git a/csharp/examples/FlightAspServerExample/FlightAspServerExample.csproj b/csharp/examples/FlightAspServerExample/FlightAspServerExample.csproj
deleted file mode 100644
index 7931252..0000000
--- a/csharp/examples/FlightAspServerExample/FlightAspServerExample.csproj
+++ /dev/null
@@ -1,35 +0,0 @@
-<!---
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-
-<Project Sdk="Microsoft.NET.Sdk.Web">
-
-  <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
-    <Nullable>enable</Nullable>
-    <ImplicitUsings>enable</ImplicitUsings>
-    <LangVersion>10</LangVersion>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" />
-    <ProjectReference Include="..\..\src\Apache.Arrow.Flight\Apache.Arrow.Flight.csproj" />
-    <ProjectReference Include="..\..\src\Apache.Arrow.Flight.AspNetCore\Apache.Arrow.Flight.AspNetCore.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/examples/FlightAspServerExample/Program.cs b/csharp/examples/FlightAspServerExample/Program.cs
deleted file mode 100644
index 08c21a5..0000000
--- a/csharp/examples/FlightAspServerExample/Program.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using FlightAspServerExample.Services;
-using Microsoft.AspNetCore.Server.Kestrel.Core;
-
-var builder = WebApplication.CreateBuilder(args);
-
-// Additional configuration is required to successfully run gRPC on macOS.
-// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
-if (builder.Environment.IsDevelopment())
-{
-    builder.WebHost.ConfigureKestrel(options =>
-    {
-        // Setup a HTTP/2 endpoint without TLS.
-        options.ListenLocalhost(5000, o => o.Protocols =
-            HttpProtocols.Http2);
-    });
-}
-
-// There may be multiple instances of InMemoryFlightServer, so we need a singleton instance
-// of the data store.
-builder.Services.AddSingleton<FlightData>();
-
-// Add services to the container.
-var grpcBuilder = builder.Services.AddGrpc();
-grpcBuilder.AddFlightServer<InMemoryFlightServer>();
-
-var app = builder.Build();
-// Configure the HTTP request pipeline.
-app.MapFlightEndpoint();
-app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
-
-app.Run();
diff --git a/csharp/examples/FlightAspServerExample/Properties/launchSettings.json b/csharp/examples/FlightAspServerExample/Properties/launchSettings.json
deleted file mode 100644
index 5afc7b6..0000000
--- a/csharp/examples/FlightAspServerExample/Properties/launchSettings.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "profiles": {
-    "FlightAspServerExample": {
-      "commandName": "Project",
-      "dotnetRunMessages": true,
-      "launchBrowser": false,
-      "applicationUrl": "http://localhost:5268;https://localhost:7295",
-      "environmentVariables": {
-        "ASPNETCORE_ENVIRONMENT": "Development"
-      }
-    }
-  }
-}
diff --git a/csharp/examples/FlightAspServerExample/Services/InMemoryFlightServer.cs b/csharp/examples/FlightAspServerExample/Services/InMemoryFlightServer.cs
deleted file mode 100644
index 2a72133..0000000
--- a/csharp/examples/FlightAspServerExample/Services/InMemoryFlightServer.cs
+++ /dev/null
@@ -1,162 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Collections.Concurrent;
-using Apache.Arrow;
-using Apache.Arrow.Flight;
-using Apache.Arrow.Flight.Server;
-using Grpc.Core;
-
-namespace FlightAspServerExample.Services
-{
-    public class FlightData
-    {
-        public FlightData()
-        {
-            Flights = new ConcurrentDictionary<FlightTicket, FlightInfo> { };
-            Tables = new ConcurrentDictionary<FlightTicket, List<RecordBatch>> { };
-        }
-        public IDictionary<FlightTicket, FlightInfo> Flights { get; }
-        public IDictionary<FlightTicket, List<RecordBatch>> Tables { get; }
-    }
-
-    public class InMemoryFlightServer : FlightServer
-    {
-        private FlightData _flightData;
-
-        public InMemoryFlightServer(FlightData flightData)
-        {
-            _flightData = flightData;
-        }
-
-        public override async Task DoPut(
-            FlightServerRecordBatchStreamReader requestStream,
-            IAsyncStreamWriter<FlightPutResult> responseStream,
-            ServerCallContext context
-        )
-        {
-            var newTable = new List<RecordBatch> { };
-            long numRows = 0;
-
-            await foreach (var batch in requestStream.ReadAllAsync(context.CancellationToken))
-            {
-                newTable.Add(batch);
-                numRows += batch.Length;
-            }
-
-            var descriptor = await requestStream.FlightDescriptor;
-            var ticket = DescriptorAsTicket(descriptor);
-            var schema = await requestStream.Schema;
-
-            _flightData.Flights.Add(ticket, new FlightInfo(
-                schema,
-                descriptor,
-                new List<FlightEndpoint> { GetEndpoint(ticket, $"http://{context.Host}") },
-                numRows,
-                -1 // Unknown
-            ));
-            _flightData.Tables.Add(ticket, newTable);
-
-            await responseStream.WriteAsync(new FlightPutResult("Table saved."));
-        }
-
-        public override async Task DoGet(
-            FlightTicket ticket,
-            FlightServerRecordBatchStreamWriter responseStream,
-            ServerCallContext context
-        )
-        {
-            if (!_flightData.Tables.ContainsKey(ticket))
-            {
-                throw new RpcException(new Status(StatusCode.NotFound, "Flight not found."));
-            }
-            var table = _flightData.Tables[ticket];
-
-            foreach (var batch in table)
-            {
-                await responseStream.WriteAsync(batch);
-            }
-        }
-
-        public override async Task ListFlights(
-            FlightCriteria request,
-            IAsyncStreamWriter<FlightInfo> responseStream,
-            ServerCallContext context
-        )
-        {
-            foreach (var flight in _flightData.Flights.Values)
-            {
-                await responseStream.WriteAsync(flight);
-            }
-        }
-
-        public override Task<FlightInfo> GetFlightInfo(FlightDescriptor request, ServerCallContext context)
-        {
-            var key = DescriptorAsTicket(request);
-            if (_flightData.Flights.ContainsKey(key))
-            {
-                return Task.FromResult(_flightData.Flights[key]);
-            }
-            else
-            {
-                throw new RpcException(new Status(StatusCode.NotFound, "Flight not found."));
-            }
-        }
-
-        public override async Task ListActions(
-            IAsyncStreamWriter<FlightActionType> responseStream, 
-            ServerCallContext context
-        )
-        {
-            await responseStream.WriteAsync(new FlightActionType("clear", "Clear the flights from the server"));
-        }
-
-        public override Task DoAction(
-            FlightAction request, 
-            IAsyncStreamWriter<FlightResult> responseStream, 
-            ServerCallContext context
-        )
-        {
-            if (request.Type == "clear")
-            {
-                _flightData.Flights.Clear();
-                _flightData.Tables.Clear();
-            }
-            else
-            {
-                throw new RpcException(new Status(StatusCode.InvalidArgument, "Action does not exist."));
-            }
-
-            return Task.CompletedTask;
-        }
-
-        public override async Task<Schema> GetSchema(FlightDescriptor request, ServerCallContext context)
-        {
-            var info = await GetFlightInfo(request, context);
-            return info.Schema;
-        }
-
-        private FlightTicket DescriptorAsTicket(FlightDescriptor desc)
-        {
-            return new FlightTicket(desc.Command);
-        }
-
-        private FlightEndpoint GetEndpoint(FlightTicket ticket, string host)
-        {
-            var location = new FlightLocation(host);
-            return new FlightEndpoint(ticket, new List<FlightLocation> { location });
-        }
-    }
-}
\ No newline at end of file
diff --git a/csharp/examples/FlightAspServerExample/appsettings.json b/csharp/examples/FlightAspServerExample/appsettings.json
deleted file mode 100644
index 1aef507..0000000
--- a/csharp/examples/FlightAspServerExample/appsettings.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "Logging": {
-    "LogLevel": {
-      "Default": "Information",
-      "Microsoft.AspNetCore": "Warning"
-    }
-  },
-  "AllowedHosts": "*",
-  "Kestrel": {
-    "EndpointDefaults": {
-      "Protocols": "Http2"
-    }
-  }
-}
diff --git a/csharp/examples/FlightAspServerExample/readme.md b/csharp/examples/FlightAspServerExample/readme.md
deleted file mode 100644
index 9ba20ea..0000000
--- a/csharp/examples/FlightAspServerExample/readme.md
+++ /dev/null
@@ -1,44 +0,0 @@
-<!---
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-
-# Flight Asp Server Example
-
-This example flight service stores uploaded Arrow tables in memory.
-
-## How this was created
-
-First, create a new gRPC service (Flight is based on gRPC):
-
-```
-dotnet new grpc
-```
-
-Delete the example greeter service.
-
-Then, implement a concrete subclass of [`FlightServer`](../../src/Apache.Arrow.Flight/Server/FlightServer.cs). 
-See [./Services/InMemoryFlightServer.cs](./Services/InMemoryFlightServer.cs).
-
-Finally, in [./Program.cs](./Program.cs) add the Flight server to the gRPC services and 
-map the endpoints with the extension methods:
-
-```csharp
-grpcBuilder.AddFlightServer<InMemoryFlightServer>();
-...
-app.MapFlightEndpoint();
-```
diff --git a/csharp/examples/FlightClientExample/FlightClientExample.csproj b/csharp/examples/FlightClientExample/FlightClientExample.csproj
deleted file mode 100644
index ce0ec83..0000000
--- a/csharp/examples/FlightClientExample/FlightClientExample.csproj
+++ /dev/null
@@ -1,31 +0,0 @@
-<!---
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-
-<Project Sdk="Microsoft.NET.Sdk">
-  
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>net8.0</TargetFramework>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\..\src\Apache.Arrow.Flight\Apache.Arrow.Flight.csproj" />
-  </ItemGroup>
-
-</Project>
\ No newline at end of file
diff --git a/csharp/examples/FlightClientExample/Program.cs b/csharp/examples/FlightClientExample/Program.cs
deleted file mode 100644
index 8a3c170..0000000
--- a/csharp/examples/FlightClientExample/Program.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Threading.Tasks;
-using Grpc.Net.Client;
-using Grpc.Core;
-using Apache.Arrow.Flight.Client;
-using Apache.Arrow.Flight;
-using Apache.Arrow;
-using System.Linq;
-using System;
-using System.Collections.Generic;
-
-namespace FlightClientExample
-{
-    public class Program
-    {
-        public static async Task Main(string[] args)
-        {
-            string host = args.Length > 0 ? args[0] : "localhost";
-            string port = args.Length > 1 ? args[1] : "5000";
-
-            // Create client
-            // (In production systems, you should use https not http)
-            var address = $"http://{host}:{port}";
-            Console.WriteLine($"Connecting to: {address}");
-            var channel = GrpcChannel.ForAddress(address);
-            var client = new FlightClient(channel);
-
-            var recordBatches = new RecordBatch[] {
-                CreateTestBatch(0, 2000), CreateTestBatch(50, 9000)
-            };
-
-            // Particular flights are identified by a descriptor. This might be a name,
-            // a SQL query, or a path. Here, just using the name "test".
-            var descriptor = FlightDescriptor.CreateCommandDescriptor("test");
-
-            // Upload data with StartPut
-            var batchStreamingCall = client.StartPut(descriptor);
-            foreach (var batch in recordBatches)
-            {
-                await batchStreamingCall.RequestStream.WriteAsync(batch);
-            }
-            // Signal we are done sending record batches
-            await batchStreamingCall.RequestStream.CompleteAsync();
-            // Retrieve final response
-            await batchStreamingCall.ResponseStream.MoveNext();
-            Console.WriteLine(batchStreamingCall.ResponseStream.Current.ApplicationMetadata.ToStringUtf8());
-            Console.WriteLine($"Wrote {recordBatches.Length} batches to server.");
-
-            // Request information:
-            var schema = await client.GetSchema(descriptor).ResponseAsync;
-            Console.WriteLine($"Schema saved as: \n {schema}");
-
-            var info = await client.GetInfo(descriptor).ResponseAsync;
-            Console.WriteLine($"Info provided: \n {info}");
-
-            Console.WriteLine($"Available flights:");
-            var flights_call = client.ListFlights();
-
-            while (await flights_call.ResponseStream.MoveNext())
-            {   
-                Console.WriteLine("  " + flights_call.ResponseStream.Current.ToString());
-            }
-
-            // Download data
-            await foreach (var batch in StreamRecordBatches(info))
-            {
-                Console.WriteLine($"Read batch from flight server: \n {batch}")  ;
-            }
-
-            // See available commands on this server
-            var action_stream = client.ListActions();
-            Console.WriteLine("Actions:");
-            while (await action_stream.ResponseStream.MoveNext())
-            {
-                var action = action_stream.ResponseStream.Current;
-                Console.WriteLine($"  {action.Type}: {action.Description}");
-            }
-
-            // Send clear command to drop all data from the server.
-            var clear_result = client.DoAction(new FlightAction("clear"));
-            await clear_result.ResponseStream.MoveNext(default);
-        }
-
-        public static async IAsyncEnumerable<RecordBatch> StreamRecordBatches(
-            FlightInfo info
-        )
-        {
-            // There might be multiple endpoints hosting part of the data. In simple services,
-            // the only endpoint might be the same server we initially queried.
-            foreach (var endpoint in info.Endpoints)
-            {
-                // We may have multiple locations to choose from. Here we choose the first.
-                var download_channel = GrpcChannel.ForAddress(endpoint.Locations.First().Uri);
-                var download_client = new FlightClient(download_channel);
-
-                var stream = download_client.GetStream(endpoint.Ticket);
-
-                while (await stream.ResponseStream.MoveNext())
-                { 
-                    yield return stream.ResponseStream.Current;
-                }
-            }
-        }
-
-        public static RecordBatch CreateTestBatch(int start, int length)
-        {
-            return new RecordBatch.Builder()
-                .Append("Column A", false, col => col.Int32(array => array.AppendRange(Enumerable.Range(start, start + length))))
-                .Append("Column B", false, col => col.Float(array => array.AppendRange(Enumerable.Range(start, start + length).Select(x => Convert.ToSingle(x * 2)))))
-                .Append("Column C", false, col => col.String(array => array.AppendRange(Enumerable.Range(start, start + length).Select(x => $"Item {x+1}"))))
-                .Append("Column D", false, col => col.Boolean(array => array.AppendRange(Enumerable.Range(start, start + length).Select(x => x % 2 == 0))))
-                .Build();
-        }
-    }
-}
\ No newline at end of file
diff --git a/csharp/examples/FlightClientExample/readme.md b/csharp/examples/FlightClientExample/readme.md
deleted file mode 100644
index 0cfc442..0000000
--- a/csharp/examples/FlightClientExample/readme.md
+++ /dev/null
@@ -1,29 +0,0 @@
-<!---
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-
-# Example Flight Client
-
-This client can connect [the Flight Server example](../FlightAspServerExample/readme.md) and will:
-
- 1. Upload a test Arrow table
- 2. Query metadata about available flights and the uploaded Arrow table
- 3. Download the test Arrow table.
- 4. Clear data on the server.
-
-To test this, start the Example Flight Server first and then run this.
diff --git a/csharp/examples/FluentBuilderExample/FluentBuilderExample.csproj b/csharp/examples/FluentBuilderExample/FluentBuilderExample.csproj
deleted file mode 100644
index b1d76d4..0000000
--- a/csharp/examples/FluentBuilderExample/FluentBuilderExample.csproj
+++ /dev/null
@@ -1,12 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-  
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>net8.0</TargetFramework>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\..\src\Apache.Arrow\Apache.Arrow.csproj" />
-  </ItemGroup>
-
-</Project>
\ No newline at end of file
diff --git a/csharp/examples/FluentBuilderExample/Program.cs b/csharp/examples/FluentBuilderExample/Program.cs
deleted file mode 100644
index 6dbdc3d..0000000
--- a/csharp/examples/FluentBuilderExample/Program.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow;
-using Apache.Arrow.Ipc;
-using Apache.Arrow.Memory;
-using System;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace FluentBuilderExample
-{
-    public class Program
-    {
-        public static async Task Main(string[] args)
-        {
-            // Use a specific memory pool from which arrays will be allocated (optional)
-
-            var memoryAllocator = new NativeMemoryAllocator(alignment: 64);
-
-            // Build a record batch using the Fluent API
-
-            var recordBatch = new RecordBatch.Builder(memoryAllocator)
-                .Append("Column A", false, col => col.Int32(array => array.AppendRange(Enumerable.Range(0, 10))))
-                .Append("Column B", false, col => col.Float(array => array.AppendRange(Enumerable.Range(0, 10).Select(x => Convert.ToSingle(x * 2)))))
-                .Append("Column C", false, col => col.String(array => array.AppendRange(Enumerable.Range(0, 10).Select(x => $"Item {x+1}"))))
-                .Append("Column D", false, col => col.Boolean(array => array.AppendRange(Enumerable.Range(0, 10).Select(x => x % 2 == 0))))
-                .Build();
-
-            // Print memory allocation statistics
-
-            Console.WriteLine("Allocations: {0}", memoryAllocator.Statistics.Allocations);
-            Console.WriteLine("Allocated: {0} byte(s)", memoryAllocator.Statistics.BytesAllocated);
-
-            // Write record batch to a file
-
-            using (var stream = File.OpenWrite("test.arrow"))
-            using (var writer = new ArrowFileWriter(stream, recordBatch.Schema))
-            {
-                await writer.WriteRecordBatchAsync(recordBatch);
-                await writer.WriteEndAsync();
-            }
-
-            Console.WriteLine("Done");
-            Console.ReadKey();
-        }
-    }
-}
diff --git a/csharp/feather.png b/csharp/feather.png
deleted file mode 100644
index 7b596e6..0000000
--- a/csharp/feather.png
+++ /dev/null
Binary files differ
diff --git a/csharp/src/Apache.Arrow.Compression/Apache.Arrow.Compression.csproj b/csharp/src/Apache.Arrow.Compression/Apache.Arrow.Compression.csproj
deleted file mode 100644
index 940bf62..0000000
--- a/csharp/src/Apache.Arrow.Compression/Apache.Arrow.Compression.csproj
+++ /dev/null
@@ -1,23 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <Description>Provides decompression support for the Arrow IPC format</Description>
-  </PropertyGroup>
-
-  <PropertyGroup Condition="'$(IsWindows)'=='true'">
-    <TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(IsWindows)'!='true'">
-    <TargetFrameworks>netstandard2.0</TargetFrameworks>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.3.8" />
-    <PackageReference Include="ZstdSharp.Port" Version="0.8.5" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\Apache.Arrow\Apache.Arrow.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/src/Apache.Arrow.Compression/CompressionCodecFactory.cs b/csharp/src/Apache.Arrow.Compression/CompressionCodecFactory.cs
deleted file mode 100644
index 4bfcdf6..0000000
--- a/csharp/src/Apache.Arrow.Compression/CompressionCodecFactory.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Ipc;
-
-namespace Apache.Arrow.Compression
-{
-    /// <summary>
-    /// Creates compression codec implementations for decompressing Arrow IPC data
-    /// </summary>
-    public sealed class CompressionCodecFactory : ICompressionCodecFactory
-    {
-        public ICompressionCodec CreateCodec(CompressionCodecType compressionCodecType)
-        {
-            return CreateCodec(compressionCodecType, null);
-        }
-
-        public ICompressionCodec CreateCodec(CompressionCodecType compressionCodecType, int? compressionLevel)
-        {
-            return compressionCodecType switch
-            {
-                CompressionCodecType.Lz4Frame => new Lz4CompressionCodec(compressionLevel),
-                CompressionCodecType.Zstd => new ZstdCompressionCodec(compressionLevel),
-                _ => throw new NotImplementedException($"Compression type {compressionCodecType} is not supported")
-            };
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Compression/Lz4CompressionCodec.cs b/csharp/src/Apache.Arrow.Compression/Lz4CompressionCodec.cs
deleted file mode 100644
index ec48d89..0000000
--- a/csharp/src/Apache.Arrow.Compression/Lz4CompressionCodec.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-using Apache.Arrow.Ipc;
-using K4os.Compression.LZ4;
-using K4os.Compression.LZ4.Streams;
-
-namespace Apache.Arrow.Compression
-{
-    internal sealed class Lz4CompressionCodec : ICompressionCodec
-    {
-        private readonly LZ4EncoderSettings _settings = null;
-
-        public Lz4CompressionCodec(int? compressionLevel = null)
-        {
-            if (compressionLevel.HasValue)
-            {
-                if (Enum.IsDefined(typeof(LZ4Level), compressionLevel))
-                {
-                    _settings = new LZ4EncoderSettings
-                    {
-                        CompressionLevel = (LZ4Level) compressionLevel
-                    };
-                }
-                else
-                {
-                    throw new ArgumentException(
-                        $"Invalid LZ4 compression level ({compressionLevel})", nameof(compressionLevel));
-                }
-            }
-        }
-
-        public int Decompress(ReadOnlyMemory<byte> source, Memory<byte> destination)
-        {
-            using var decoder = LZ4Frame.Decode(source);
-            return decoder.ReadManyBytes(destination.Span);
-        }
-
-        public void Compress(ReadOnlyMemory<byte> source, Stream destination)
-        {
-            using var encoder = LZ4Frame.Encode(destination, _settings, leaveOpen: true);
-            encoder.WriteManyBytes(source.Span);
-        }
-
-        public void Dispose()
-        {
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Compression/ZstdCompressionCodec.cs b/csharp/src/Apache.Arrow.Compression/ZstdCompressionCodec.cs
deleted file mode 100644
index d89480e..0000000
--- a/csharp/src/Apache.Arrow.Compression/ZstdCompressionCodec.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-using Apache.Arrow.Ipc;
-using ZstdSharp;
-
-namespace Apache.Arrow.Compression
-{
-    internal sealed class ZstdCompressionCodec : ITryCompressionCodec
-    {
-        private readonly Decompressor _decompressor;
-        private readonly Compressor _compressor;
-
-        public ZstdCompressionCodec(int? compressionLevel = null)
-        {
-            if (compressionLevel.HasValue &&
-                (compressionLevel.Value < Compressor.MinCompressionLevel ||
-                 compressionLevel.Value > Compressor.MaxCompressionLevel))
-            {
-                throw new ArgumentException(
-                    $"Zstd compression level must be between {Compressor.MinCompressionLevel} and {Compressor.MaxCompressionLevel}",
-                    nameof(compressionLevel));
-            }
-
-            _decompressor = new Decompressor();
-            _compressor = new Compressor(compressionLevel ?? Compressor.DefaultCompressionLevel);
-        }
-
-        public int Decompress(ReadOnlyMemory<byte> source, Memory<byte> destination)
-        {
-            return _decompressor.Unwrap(source.Span, destination.Span);
-        }
-
-        public void Compress(ReadOnlyMemory<byte> source, Stream destination)
-        {
-            using var compressor = new CompressionStream(
-                destination, _compressor, preserveCompressor: true, leaveOpen: true);
-            compressor.Write(source.Span);
-        }
-
-        public bool TryCompress(ReadOnlyMemory<byte> source, Memory<byte> destination, out int bytesWritten)
-        {
-            return _compressor.TryWrap(source.Span, destination.Span, out bytesWritten);
-        }
-
-        public void Dispose()
-        {
-            _decompressor.Dispose();
-            _compressor.Dispose();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight.AspNetCore/Apache.Arrow.Flight.AspNetCore.csproj b/csharp/src/Apache.Arrow.Flight.AspNetCore/Apache.Arrow.Flight.AspNetCore.csproj
deleted file mode 100644
index 9adfab7..0000000
--- a/csharp/src/Apache.Arrow.Flight.AspNetCore/Apache.Arrow.Flight.AspNetCore.csproj
+++ /dev/null
@@ -1,15 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>net6.0</TargetFramework>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Grpc.AspNetCore.Server" Version="2.71.0" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\Apache.Arrow.Flight\Apache.Arrow.Flight.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/src/Apache.Arrow.Flight.AspNetCore/Extensions/FlightIEndpointRouteBuilderExtensions.cs b/csharp/src/Apache.Arrow.Flight.AspNetCore/Extensions/FlightIEndpointRouteBuilderExtensions.cs
deleted file mode 100644
index 5902d7b..0000000
--- a/csharp/src/Apache.Arrow.Flight.AspNetCore/Extensions/FlightIEndpointRouteBuilderExtensions.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Flight.Server.Internal;
-using Microsoft.AspNetCore.Routing;
-
-namespace Microsoft.AspNetCore.Builder
-{
-    public static class FlightIEndpointRouteBuilderExtensions
-    {
-        public static GrpcServiceEndpointConventionBuilder MapFlightEndpoint(this IEndpointRouteBuilder endpointRouteBuilder)
-        {
-            return endpointRouteBuilder.MapGrpcService<FlightServerImplementation>();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight.AspNetCore/Extensions/FlightIGrpcServerBuilderExtensions.cs b/csharp/src/Apache.Arrow.Flight.AspNetCore/Extensions/FlightIGrpcServerBuilderExtensions.cs
deleted file mode 100644
index 692e86f..0000000
--- a/csharp/src/Apache.Arrow.Flight.AspNetCore/Extensions/FlightIGrpcServerBuilderExtensions.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Flight.Server;
-using Grpc.AspNetCore.Server;
-
-namespace Microsoft.Extensions.DependencyInjection
-{
-    public static class FlightIGrpcServerBuilderExtensions
-    {
-        public static IGrpcServerBuilder AddFlightServer<T>(this IGrpcServerBuilder grpcServerBuilder)
-            where T : FlightServer
-        {
-            grpcServerBuilder.Services.AddScoped<FlightServer, T>();
-            return grpcServerBuilder;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/Apache.Arrow.Flight.Sql.csproj b/csharp/src/Apache.Arrow.Flight.Sql/Apache.Arrow.Flight.Sql.csproj
deleted file mode 100644
index 6a57e2a..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/Apache.Arrow.Flight.Sql.csproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-  <PropertyGroup>
-    <TargetFramework>netstandard2.1</TargetFramework>
-    <Nullable>enable</Nullable>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Grpc.Tools" Version="2.72.0" PrivateAssets="All" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\Apache.Arrow.Flight\Apache.Arrow.Flight.csproj" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <Protobuf Include="..\..\..\format\FlightSql.proto" Access="public" />
-  </ItemGroup>
-</Project>
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/Client/FlightSqlClient.cs b/csharp/src/Apache.Arrow.Flight.Sql/Client/FlightSqlClient.cs
deleted file mode 100644
index 98e4b47..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/Client/FlightSqlClient.cs
+++ /dev/null
@@ -1,1047 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Client;
-using Arrow.Flight.Protocol.Sql;
-using Google.Protobuf.WellKnownTypes;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Sql.Client;
-
-public class FlightSqlClient
-{
-    private readonly FlightClient _client;
-
-    public FlightSqlClient(FlightClient client)
-    {
-        _client = client;
-    }
-
-    /// <summary>
-    /// Execute a SQL query on the server.
-    /// </summary>
-    /// <param name="query">The UTF8-encoded SQL query to be executed.</param>
-    /// <param name="transaction">A transaction to associate this query with.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> ExecuteAsync(
-        string query,
-        Transaction transaction = default,
-        FlightCallOptions? options = null,
-        CancellationToken cancellationToken = default)
-    {
-        if (transaction == default)
-        {
-            transaction = Transaction.NoTransaction;
-        }
-
-        if (string.IsNullOrEmpty(query))
-        {
-            throw new ArgumentException($"Query cannot be null or empty: {nameof(query)}");
-        }
-
-        try
-        {
-            var commandQuery = new CommandStatementQuery { Query = query };
-
-            if (transaction.IsValid)
-            {
-                commandQuery.TransactionId = transaction.TransactionId;
-            }
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(commandQuery.PackAndSerialize());
-            return await GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to execute query", ex);
-        }
-    }
-
-    /// <summary>
-    /// Executes an update SQL command and returns the number of affected rows.
-    /// </summary>
-    /// <param name="query">The UTF8-encoded SQL query to be executed.</param>
-    /// <param name="transaction">A transaction to associate this query with. Defaults to no transaction if not provided.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>The number of rows affected by the operation.</returns>
-    public async Task<long> ExecuteUpdateAsync(
-        string query,
-        Transaction transaction = default,
-        FlightCallOptions? options = null,
-        CancellationToken cancellationToken = default)
-    {
-        if (transaction == default)
-        {
-            transaction = Transaction.NoTransaction;
-        }
-
-        if (string.IsNullOrEmpty(query))
-        {
-            throw new ArgumentException("Query cannot be null or empty", nameof(query));
-        }
-
-        try
-        {
-            var updateRequestCommand =
-                new ActionCreatePreparedStatementRequest { Query = query, TransactionId = transaction.TransactionId };
-            byte[] serializedUpdateRequestCommand = updateRequestCommand.PackAndSerialize();
-            var action = new FlightAction(SqlAction.CreateRequest, serializedUpdateRequestCommand);
-            var call = DoActionAsync(action, options, cancellationToken);
-            long affectedRows = 0;
-
-            await foreach (var result in call.ConfigureAwait(false))
-            {
-                var preparedStatementResponse = result.Body.ParseAndUnpack<ActionCreatePreparedStatementResult>();
-                var command = new CommandPreparedStatementQuery
-                {
-                    PreparedStatementHandle = preparedStatementResponse.PreparedStatementHandle
-                };
-
-                var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-                var flightInfo = await GetFlightInfoAsync(descriptor, options, cancellationToken);
-                var doGetResult = DoGetAsync(flightInfo.Endpoints[0].Ticket, options, cancellationToken);
-
-                await foreach (var recordBatch in doGetResult.ConfigureAwait(false))
-                {
-                    affectedRows += recordBatch.ExtractRowCount();
-                }
-            }
-
-            return affectedRows;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to execute update query", ex);
-        }
-    }
-
-    /// <summary>
-    /// Asynchronously retrieves flight information for a given flight descriptor.
-    /// </summary>
-    /// <param name="descriptor">The descriptor of the dataset request, whether a named dataset or a command.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>A task that represents the asynchronous operation. The task result contains the FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> GetFlightInfoAsync(
-        FlightDescriptor descriptor,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (descriptor is null)
-        {
-            throw new ArgumentNullException(nameof(descriptor));
-        }
-
-        try
-        {
-            var flightInfoCall = _client.GetInfo(descriptor, options?.Headers, null, cancellationToken);
-            var flightInfo = await flightInfoCall.ResponseAsync.ConfigureAwait(false);
-            return flightInfo;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get flight info", ex);
-        }
-    }
-
-    /// <summary>
-    /// Perform the indicated action, returning an iterator to the stream of results, if any.
-    /// </summary>
-    /// <param name="action">The action to be performed</param>
-    /// <param name="options">Per-RPC options</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>An async enumerable of results</returns>
-    public async IAsyncEnumerable<FlightResult> DoActionAsync(
-        FlightAction action,
-        FlightCallOptions? options = default,
-        [EnumeratorCancellation] CancellationToken cancellationToken = default)
-    {
-        if (action is null)
-            throw new ArgumentNullException(nameof(action));
-
-        var call = _client.DoAction(action, options?.Headers, null, cancellationToken);
-
-        await foreach (var result in call.ResponseStream.ReadAllAsync(cancellationToken).ConfigureAwait(false))
-        {
-            yield return result;
-        }
-    }
-
-    /// <summary>
-    /// Get the result set schema from the server for the given query.
-    /// </summary>
-    /// <param name="query">The UTF8-encoded SQL query</param>
-    /// <param name="transaction">A transaction to associate this query with</param>
-    /// <param name="options">Per-RPC options</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>The SchemaResult describing the schema of the result set</returns>
-    public async Task<Schema> GetExecuteSchemaAsync(
-        string query, Transaction transaction = default,
-        FlightCallOptions? options = null,
-        CancellationToken cancellationToken = default)
-    {
-        if (transaction == default)
-        {
-            transaction = Transaction.NoTransaction;
-        }
-
-        if (string.IsNullOrEmpty(query))
-            throw new ArgumentException($"Query cannot be null or empty: {nameof(query)}");
-        try
-        {
-            var prepareStatementRequest =
-                new ActionCreatePreparedStatementRequest { Query = query, TransactionId = transaction.TransactionId };
-            var action = new FlightAction(SqlAction.CreateRequest, prepareStatementRequest.PackAndSerialize());
-            var call = _client.DoAction(action, options?.Headers, null, cancellationToken);
-
-            var preparedStatementResponse = await ReadPreparedStatementAsync(call, cancellationToken).ConfigureAwait(false);
-
-            if (preparedStatementResponse.PreparedStatementHandle.IsEmpty)
-                throw new InvalidOperationException("Received an empty or invalid PreparedStatementHandle.");
-            var commandSqlCall = new CommandPreparedStatementQuery
-            {
-                PreparedStatementHandle = preparedStatementResponse.PreparedStatementHandle
-            };
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(commandSqlCall.PackAndSerialize());
-            var schemaResult = await GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return schemaResult.Schema;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get execute schema", ex);
-        }
-    }
-
-    /// <summary>
-    /// Request a list of catalogs.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> GetCatalogsAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var command = new CommandGetCatalogs();
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-            var catalogsInfo = await GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return catalogsInfo;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get catalogs", ex);
-        }
-    }
-
-    /// <summary>
-    /// Get the catalogs schema from the server.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>The SchemaResult describing the schema of the catalogs.</returns>
-    public async Task<Schema> GetCatalogsSchemaAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var commandGetCatalogsSchema = new CommandGetCatalogs();
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(commandGetCatalogsSchema.PackAndSerialize());
-            var schemaResult = await GetSchemaAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return schemaResult;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get catalogs schema", ex);
-        }
-    }
-
-    /// <summary>
-    /// Asynchronously retrieves schema information for a given flight descriptor.
-    /// </summary>
-    /// <param name="descriptor">The descriptor of the dataset request, whether a named dataset or a command.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>A task that represents the asynchronous operation. The task result contains the SchemaResult describing the dataset schema.</returns>
-    public virtual async Task<Schema> GetSchemaAsync(
-        FlightDescriptor descriptor,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (descriptor is null)
-        {
-            throw new ArgumentNullException(nameof(descriptor));
-        }
-
-        try
-        {
-            var schemaResultCall = _client.GetSchema(descriptor, options?.Headers, null, cancellationToken);
-            var schemaResult = await schemaResultCall.ResponseAsync.ConfigureAwait(false);
-            return schemaResult;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get schema", ex);
-        }
-    }
-
-    /// <summary>
-    /// Request a list of database schemas.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <param name="catalog">The catalog.</param>
-    /// <param name="dbSchemaFilterPattern">The schema filter pattern.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> GetDbSchemasAsync(
-        string? catalog = null,
-        string? dbSchemaFilterPattern = null,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var command = new CommandGetDbSchemas();
-
-            if (catalog != null)
-            {
-                command.Catalog = catalog;
-            }
-
-            if (dbSchemaFilterPattern != null)
-            {
-                command.DbSchemaFilterPattern = dbSchemaFilterPattern;
-            }
-
-            byte[] serializedAndPackedCommand = command.PackAndSerialize();
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(serializedAndPackedCommand);
-            var flightInfoCall = GetFlightInfoAsync(descriptor, options, cancellationToken);
-            var flightInfo = await flightInfoCall.ConfigureAwait(false);
-
-            return flightInfo;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get database schemas", ex);
-        }
-    }
-
-    /// <summary>
-    /// Get the database schemas schema from the server.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>The SchemaResult describing the schema of the database schemas.</returns>
-    public async Task<Schema> GetDbSchemasSchemaAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var command = new CommandGetDbSchemas();
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-            var schemaResult = await GetSchemaAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return schemaResult;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get database schemas schema", ex);
-        }
-    }
-
-    /// <summary>
-    /// Given a flight ticket and schema, request to be sent the stream. Returns record batch stream reader.
-    /// </summary>
-    /// <param name="ticket">The flight ticket to use</param>
-    /// <param name="options">Per-RPC options</param>
-    /// <returns>The returned RecordBatchReader</returns>
-    public async IAsyncEnumerable<RecordBatch> DoGetAsync(
-        FlightTicket ticket,
-        FlightCallOptions? options = default,
-        [EnumeratorCancellation] CancellationToken cancellationToken = default)
-    {
-        if (ticket == null)
-        {
-            throw new ArgumentNullException(nameof(ticket));
-        }
-
-        var call = _client.GetStream(ticket, options?.Headers);
-        await foreach (var recordBatch in call.ResponseStream.ReadAllAsync(cancellationToken).ConfigureAwait(false))
-        {
-            yield return recordBatch;
-        }
-    }
-
-    /// <summary>
-    /// Upload data to a Flight described by the given descriptor. The caller must call Close() on the returned stream
-    /// once they are done writing.
-    /// </summary>
-    /// <param name="descriptor">The descriptor of the stream.</param>
-    /// <param name="recordBatch">The record for the data to upload.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>A Task representing the asynchronous operation. The task result contains a DoPutResult struct holding a reader and a writer.</returns>
-    public async Task<FlightPutResult> DoPutAsync(
-        FlightDescriptor descriptor,
-        RecordBatch recordBatch,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (descriptor is null)
-            throw new ArgumentNullException(nameof(descriptor));
-
-        if (recordBatch is null)
-            throw new ArgumentNullException(nameof(recordBatch));
-        try
-        {
-            var doPutResult = _client.StartPut(descriptor, options?.Headers, null, cancellationToken);
-            var writer = doPutResult.RequestStream;
-            var reader = doPutResult.ResponseStream;
-
-            if (recordBatch == null || recordBatch.Length == 0)
-                throw new InvalidOperationException("RecordBatch is empty or improperly initialized.");
-
-            await writer.WriteAsync(recordBatch).ConfigureAwait(false);
-            await writer.CompleteAsync().ConfigureAwait(false);
-
-            if (await reader.MoveNext(cancellationToken).ConfigureAwait(false))
-            {
-                var putResult = reader.Current;
-                return new FlightPutResult(putResult.ApplicationMetadata);
-            }
-            return FlightPutResult.Empty;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to perform DoPut operation", ex);
-        }
-    }
-
-    /// <summary>
-    /// Request the primary keys for a table.
-    /// </summary>
-    /// <param name="tableRef">The table reference.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> GetPrimaryKeysAsync(TableRef tableRef, FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        if (tableRef == null)
-            throw new ArgumentNullException(nameof(tableRef));
-
-        try
-        {
-            var getPrimaryKeysRequest = new CommandGetPrimaryKeys
-            {
-                Catalog = tableRef.Catalog ?? string.Empty,
-                DbSchema = tableRef.DbSchema,
-                Table = tableRef.Table
-            };
-
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(getPrimaryKeysRequest.PackAndSerialize());
-            var flightInfo = await GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-
-            return flightInfo;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get primary keys", ex);
-        }
-    }
-
-    /// <summary>
-    /// Request a list of tables.
-    /// </summary>
-    /// <param name="catalog">The catalog.</param>
-    /// <param name="dbSchemaFilterPattern">The schema filter pattern.</param>
-    /// <param name="tableFilterPattern">The table filter pattern.</param>
-    /// <param name="includeSchema">True to include the schema upon return, false to not include the schema.</param>
-    /// <param name="tableTypes">The table types to include.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<IEnumerable<FlightInfo>> GetTablesAsync(
-        string? catalog = null,
-        string? dbSchemaFilterPattern = null,
-        string? tableFilterPattern = null,
-        bool includeSchema = false,
-        IEnumerable<string>? tableTypes = null,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        var command = new CommandGetTables
-        {
-            Catalog = catalog ?? string.Empty,
-            DbSchemaFilterPattern = dbSchemaFilterPattern ?? string.Empty,
-            TableNameFilterPattern = tableFilterPattern ?? string.Empty,
-            IncludeSchema = includeSchema
-        };
-
-        if (tableTypes != null)
-        {
-            command.TableTypes.AddRange(tableTypes);
-        }
-
-        var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-        var flightInfoCall = GetFlightInfoAsync(descriptor, options, cancellationToken);
-        var flightInfo = await flightInfoCall.ConfigureAwait(false);
-        var flightInfos = new List<FlightInfo> { flightInfo };
-
-        return flightInfos;
-    }
-
-    /// <summary>
-    /// Retrieves a description about the foreign key columns that reference the primary key columns of the given table.
-    /// </summary>
-    /// <param name="tableRef">The table reference.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> GetExportedKeysAsync(
-        TableRef tableRef,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (tableRef == null)
-            throw new ArgumentNullException(nameof(tableRef));
-
-        try
-        {
-            var getExportedKeysRequest = new CommandGetExportedKeys
-            {
-                Catalog = tableRef.Catalog ?? string.Empty,
-                DbSchema = tableRef.DbSchema,
-                Table = tableRef.Table
-            };
-
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(getExportedKeysRequest.PackAndSerialize());
-            var flightInfo = await GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return flightInfo;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get exported keys", ex);
-        }
-    }
-
-    /// <summary>
-    /// Get the exported keys schema from the server.
-    /// </summary>
-    /// <param name="tableRef">The table reference.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The SchemaResult describing the schema of the exported keys.</returns>
-    public async Task<Schema> GetExportedKeysSchemaAsync(
-        TableRef tableRef,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var commandGetExportedKeysSchema = new CommandGetExportedKeys
-            {
-                Catalog = tableRef.Catalog ?? string.Empty,
-                DbSchema = tableRef.DbSchema,
-                Table = tableRef.Table
-            };
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(commandGetExportedKeysSchema.PackAndSerialize());
-            var schemaResult = await GetSchemaAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return schemaResult;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get exported keys schema", ex);
-        }
-    }
-
-    /// <summary>
-    /// Retrieves the foreign key columns for the given table.
-    /// </summary>
-    /// <param name="tableRef">The table reference.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> GetImportedKeysAsync(
-        TableRef tableRef,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (tableRef == null)
-            throw new ArgumentNullException(nameof(tableRef));
-
-        try
-        {
-            var getImportedKeysRequest = new CommandGetImportedKeys
-            {
-                Catalog = tableRef.Catalog ?? string.Empty,
-                DbSchema = tableRef.DbSchema,
-                Table = tableRef.Table
-            };
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(getImportedKeysRequest.PackAndSerialize());
-            var flightInfo = await GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return flightInfo;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get imported keys", ex);
-        }
-    }
-
-    /// <summary>
-    /// Get the imported keys schema from the server.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The SchemaResult describing the schema of the imported keys.</returns>
-    public async Task<Schema> GetImportedKeysSchemaAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var commandGetImportedKeysSchema = new CommandGetImportedKeys();
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(commandGetImportedKeysSchema.PackAndSerialize());
-            var schemaResult = await GetSchemaAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return schemaResult;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get imported keys schema", ex);
-        }
-    }
-
-    /// <summary>
-    /// Retrieves a description of the foreign key columns in the given foreign key table that reference the primary key or the columns representing a unique constraint of the parent table.
-    /// </summary>
-    /// <param name="pkTableRef">The table reference that exports the key.</param>
-    /// <param name="fkTableRef">The table reference that imports the key.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> GetCrossReferenceAsync(
-        TableRef pkTableRef,
-        TableRef fkTableRef,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (pkTableRef == null)
-            throw new ArgumentNullException(nameof(pkTableRef));
-
-        if (fkTableRef == null)
-            throw new ArgumentNullException(nameof(fkTableRef));
-
-        try
-        {
-            var commandGetCrossReference = new CommandGetCrossReference
-            {
-                PkCatalog = pkTableRef.Catalog ?? string.Empty,
-                PkDbSchema = pkTableRef.DbSchema,
-                PkTable = pkTableRef.Table,
-                FkCatalog = fkTableRef.Catalog ?? string.Empty,
-                FkDbSchema = fkTableRef.DbSchema,
-                FkTable = fkTableRef.Table
-            };
-
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(commandGetCrossReference.PackAndSerialize());
-            var flightInfo = await GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-
-            return flightInfo;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get cross reference", ex);
-        }
-    }
-
-    /// <summary>
-    /// Get the cross-reference schema from the server.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The SchemaResult describing the schema of the cross-reference.</returns>
-    public async Task<Schema> GetCrossReferenceSchemaAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var commandGetCrossReferenceSchema = new CommandGetCrossReference();
-            var descriptor =
-                FlightDescriptor.CreateCommandDescriptor(commandGetCrossReferenceSchema.PackAndSerialize());
-            var schemaResultCall = GetSchemaAsync(descriptor, options, cancellationToken);
-            var schemaResult = await schemaResultCall.ConfigureAwait(false);
-
-            return schemaResult;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get cross-reference schema", ex);
-        }
-    }
-
-    /// <summary>
-    /// Request a list of table types.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> GetTableTypesAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var command = new CommandGetTableTypes();
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-            var flightInfo = await GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return flightInfo;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get table types", ex);
-        }
-    }
-
-    /// <summary>
-    /// Get the table types schema from the server.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The SchemaResult describing the schema of the table types.</returns>
-    public async Task<Schema> GetTableTypesSchemaAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var command = new CommandGetTableTypes();
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-            var schemaResult = await GetSchemaAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return schemaResult;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get table types schema", ex);
-        }
-    }
-
-    /// <summary>
-    /// Request the information about all the data types supported with filtering by data type.
-    /// </summary>
-    /// <param name="dataType">The data type to search for as filtering.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> GetXdbcTypeInfoAsync(int dataType, FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var command = new CommandGetXdbcTypeInfo { DataType = dataType };
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-            var flightInfo = await GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return flightInfo;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get XDBC type info", ex);
-        }
-    }
-
-    /// <summary>
-    /// Request the information about all the data types supported.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> GetXdbcTypeInfoAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var command = new CommandGetXdbcTypeInfo();
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-            var flightInfo = await GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return flightInfo;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get XDBC type info", ex);
-        }
-    }
-
-    /// <summary>
-    /// Get the type info schema from the server.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The SchemaResult describing the schema of the type info.</returns>
-    public async Task<Schema> GetXdbcTypeInfoSchemaAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var command = new CommandGetXdbcTypeInfo();
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-            var schemaResult = await GetSchemaAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return schemaResult;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get XDBC type info schema", ex);
-        }
-    }
-
-    /// <summary>
-    /// Request a list of SQL information.
-    /// </summary>
-    /// <param name="sqlInfo">The SQL info required.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The FlightInfo describing where to access the dataset.</returns>
-    public async Task<FlightInfo> GetSqlInfoAsync(
-        List<int>? sqlInfo = default,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        sqlInfo ??= new List<int>();
-        try
-        {
-            var command = new CommandGetSqlInfo();
-            command.Info.AddRange(sqlInfo.ConvertAll(item => (uint)item));
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-            var flightInfo = await GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            return flightInfo;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get SQL info", ex);
-        }
-    }
-
-    /// <summary>
-    /// Get the SQL information schema from the server.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The SchemaResult describing the schema of the SQL information.</returns>
-    public async Task<Schema> GetSqlInfoSchemaAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var command = new CommandGetSqlInfo();
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-            var schemaResultCall = _client.GetSchema(descriptor, options?.Headers, null, cancellationToken);
-            var schemaResult = await schemaResultCall.ResponseAsync.ConfigureAwait(false);
-
-            return schemaResult;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to get SQL info schema", ex);
-        }
-    }
-
-    /// <summary>
-    /// Explicitly cancel a FlightInfo.
-    /// </summary>
-    /// <param name="request">The CancelFlightInfoRequest.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>A Task representing the asynchronous operation. The task result contains the CancelFlightInfoResult describing the canceled result.</returns>
-    public async Task<FlightInfoCancelResult> CancelFlightInfoAsync(
-        FlightInfoCancelRequest request,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (request == null) throw new ArgumentNullException(nameof(request));
-
-        try
-        {
-            var action = new FlightAction(SqlAction.CancelFlightInfoRequest, request.PackAndSerialize());
-            var call = _client.DoAction(action, options?.Headers, null, cancellationToken);
-            await foreach (var result in call.ResponseStream.ReadAllAsync(cancellationToken).ConfigureAwait(false))
-            {
-                if (Any.Parser.ParseFrom(result.Body) is Any anyResult &&
-                    anyResult.TryUnpack(out FlightInfoCancelResult cancelResult))
-                {
-                    return cancelResult;
-                }
-            }
-
-            throw new InvalidOperationException("No response received for the CancelFlightInfo request.");
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to cancel flight info", ex);
-        }
-    }
-
-    /// <summary>
-    /// Explicitly cancel a query.
-    /// </summary>
-    /// <param name="info">The FlightInfo of the query to cancel.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>A Task representing the asynchronous operation.</returns>
-    public async Task<FlightInfoCancelResult> CancelQueryAsync(
-        FlightInfo info,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (info == null)
-            throw new ArgumentNullException(nameof(info));
-
-        try
-        {
-            var cancelQueryRequest = new FlightInfoCancelRequest(info);
-            var cancelQueryAction =
-                new FlightAction(SqlAction.CancelFlightInfoRequest, cancelQueryRequest.PackAndSerialize());
-            var cancelQueryCall = _client.DoAction(cancelQueryAction, options?.Headers, null, cancellationToken);
-
-            await foreach (var result in cancelQueryCall.ResponseStream.ReadAllAsync(cancellationToken).ConfigureAwait(false))
-            {
-                if (Any.Parser.ParseFrom(result.Body) is Any anyResult &&
-                    anyResult.TryUnpack(out FlightInfoCancelResult cancelResult))
-                {
-                    return cancelResult;
-                }
-            }
-            throw new InvalidOperationException("Failed to cancel query: No response received.");
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to cancel query", ex);
-        }
-    }
-
-    /// <summary>
-    /// Begin a new transaction.
-    /// </summary>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>A Task representing the asynchronous operation. The task result contains the Transaction object representing the new transaction.</returns>
-    public async Task<Transaction> BeginTransactionAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        try
-        {
-            var actionBeginTransaction = new ActionBeginTransactionRequest();
-            var action = new FlightAction(SqlAction.BeginTransactionRequest, actionBeginTransaction.PackAndSerialize());
-            var responseStream = _client.DoAction(action, options?.Headers, null, cancellationToken);
-            await foreach (var result in responseStream.ResponseStream.ReadAllAsync(cancellationToken).ConfigureAwait(false))
-            {
-                string? beginTransactionResult = result.Body.ToStringUtf8();
-                return new Transaction(beginTransactionResult);
-            }
-
-            throw new InvalidOperationException("Failed to begin transaction: No response received.");
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to begin transaction", ex);
-        }
-    }
-
-    /// <summary>
-    /// Commit a transaction.
-    /// After this, the transaction and all associated savepoints will be invalidated.
-    /// </summary>
-    /// <param name="transaction">The transaction.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>A Task representing the asynchronous operation.</returns>
-    public AsyncServerStreamingCall<FlightResult> CommitAsync(
-        Transaction transaction,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (transaction == null)
-            throw new ArgumentNullException(nameof(transaction));
-
-        try
-        {
-            var actionCommit = new FlightAction(SqlAction.CommitRequest, transaction.TransactionId);
-            return _client.DoAction(actionCommit, options?.Headers, null, cancellationToken);
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to commit transaction", ex);
-        }
-    }
-
-    /// <summary>
-    /// Rollback a transaction.
-    /// After this, the transaction and all associated savepoints will be invalidated.
-    /// </summary>
-    /// <param name="transaction">The transaction to rollback.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>A Task representing the asynchronous operation.</returns>
-    public AsyncServerStreamingCall<FlightResult> RollbackAsync(
-        Transaction transaction,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (transaction == null)
-        {
-            throw new ArgumentNullException(nameof(transaction));
-        }
-
-        try
-        {
-            var actionRollback = new FlightAction(SqlAction.RollbackRequest, transaction.TransactionId);
-            return _client.DoAction(actionRollback, options?.Headers, null, cancellationToken);
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to rollback transaction", ex);
-        }
-    }
-
-    /// <summary>
-    /// Create a prepared statement object.
-    /// </summary>
-    /// <param name="query">The query that will be executed.</param>
-    /// <param name="transaction">A transaction to associate this query with.</param>
-    /// <param name="options">RPC-layer hints for this call.</param>
-    /// <returns>The created prepared statement.</returns>
-    public async Task<PreparedStatement> PrepareAsync(
-        string query,
-        Transaction transaction = default,
-        FlightCallOptions? options = null,
-        CancellationToken cancellationToken = default)
-    {
-        if (string.IsNullOrEmpty(query))
-            throw new ArgumentException("Query cannot be null or empty", nameof(query));
-
-        if (transaction == default)
-        {
-            transaction = Transaction.NoTransaction;
-        }
-
-        try
-        {
-            var command = new ActionCreatePreparedStatementRequest
-            {
-                Query = query
-            };
-
-            if (transaction.IsValid)
-            {
-                command.TransactionId = transaction.TransactionId;
-            }
-
-            var action = new FlightAction(SqlAction.CreateRequest, command.PackAndSerialize());
-            var call = _client.DoAction(action, options?.Headers);
-            var preparedStatementResponse = await ReadPreparedStatementAsync(call, cancellationToken).ConfigureAwait(false);
-
-            return new PreparedStatement(this,
-                preparedStatementResponse.PreparedStatementHandle.ToStringUtf8(),
-                SchemaExtensions.DeserializeSchema(preparedStatementResponse.DatasetSchema.ToByteArray()),
-                SchemaExtensions.DeserializeSchema(preparedStatementResponse.ParameterSchema.ToByteArray())
-            );
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to prepare statement", ex);
-        }
-    }
-
-    private static async Task<ActionCreatePreparedStatementResult> ReadPreparedStatementAsync(
-        AsyncServerStreamingCall<FlightResult> call,
-        CancellationToken cancellationToken)
-    {
-        await foreach (var result in call.ResponseStream.ReadAllAsync(cancellationToken).ConfigureAwait(false))
-        {
-            var response = Any.Parser.ParseFrom(result.Body);
-            if (response.Is(ActionCreatePreparedStatementResult.Descriptor))
-            {
-                return response.Unpack<ActionCreatePreparedStatementResult>();
-            }
-        }
-        throw new InvalidOperationException("Server did not return a valid prepared statement response.");
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/DoPutResult.cs b/csharp/src/Apache.Arrow.Flight.Sql/DoPutResult.cs
deleted file mode 100644
index 357c7a2..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/DoPutResult.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Client;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Sql;
-
-public class DoPutResult
-{
-    public FlightClientRecordBatchStreamWriter Writer { get; }
-    public IAsyncStreamReader<FlightPutResult> Reader { get; }
-
-    public DoPutResult(FlightClientRecordBatchStreamWriter writer, IAsyncStreamReader<FlightPutResult> reader)
-    {
-        Writer = writer;
-        Reader = reader;
-    }
-    
-    /// <summary>
-    /// Reads the metadata asynchronously from the reader.
-    /// </summary>
-    /// <returns>A ByteString containing the metadata read from the reader.</returns>
-    public async Task<Google.Protobuf.ByteString> ReadMetadataAsync(CancellationToken cancellationToken = default)
-    {
-        if (await Reader.MoveNext(cancellationToken).ConfigureAwait(false))
-        {
-            return Reader.Current.ApplicationMetadata;
-        }
-        throw new RpcException(new Status(StatusCode.Internal, "No metadata available in the response stream."));
-    }
-    
-    /// <summary>
-    /// Completes the writer by signaling the end of the writing process.
-    /// </summary>
-    /// <returns>A Task representing the completion of the writer.</returns>
-    public async Task CompleteAsync()
-    {
-        await Writer.CompleteAsync().ConfigureAwait(false);
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/FlightCallOptions.cs b/csharp/src/Apache.Arrow.Flight.Sql/FlightCallOptions.cs
deleted file mode 100644
index 17541b2..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/FlightCallOptions.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.Threading;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Sql;
-
-public class FlightCallOptions
-{
-    public FlightCallOptions()
-    {
-        Timeout = TimeSpan.FromSeconds(-1);
-    }
-    
-    // Implement any necessary options for RPC calls
-    public Metadata Headers { get; set; } = new();
-
-    /// <summary>
-    /// Gets or sets the optional timeout for this call.
-    /// Negative durations mean an implementation-defined default behavior will be used instead.
-    /// </summary>
-    public TimeSpan Timeout { get; set; }
-}
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/FlightExtensions.cs b/csharp/src/Apache.Arrow.Flight.Sql/FlightExtensions.cs
deleted file mode 100644
index a0936eb..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/FlightExtensions.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Google.Protobuf;
-using Google.Protobuf.WellKnownTypes;
-
-namespace Apache.Arrow.Flight.Sql;
-
-internal static class FlightExtensions
-{
-    public static byte[] PackAndSerialize(this IMessage command) => Any.Pack(command).ToByteArray();
-
-    public static T ParseAndUnpack<T>(this ByteString source) where T : IMessage<T>, new() =>
-        Any.Parser.ParseFrom(source).Unpack<T>();
-
-    public static int ExtractRowCount(this RecordBatch batch)
-    {
-        if (batch.ColumnCount == 0) return 0;
-        int length = batch.Column(0).Length;
-        foreach (var column in batch.Arrays)
-        {
-            if (column.Length != length)
-                throw new InvalidOperationException("Inconsistent column lengths in RecordBatch.");
-        }
-
-        return length;
-    }
-}
\ No newline at end of file
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/FlightSqlServer.cs b/csharp/src/Apache.Arrow.Flight.Sql/FlightSqlServer.cs
deleted file mode 100644
index cbccc9d..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/FlightSqlServer.cs
+++ /dev/null
@@ -1,389 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Server;
-using Apache.Arrow.Types;
-using Arrow.Flight.Protocol.Sql;
-using Google.Protobuf;
-using Google.Protobuf.WellKnownTypes;
-using Grpc.Core;
-using Microsoft.Extensions.Logging;
-
-namespace Apache.Arrow.Flight.Sql;
-
-public abstract class FlightSqlServer : FlightServer
-{
-    private ILogger? Logger { get; }
-    public static readonly Schema CatalogSchema = new(new List<Field> {new("catalog_name", StringType.Default, false)}, null);
-    public static readonly Schema TableTypesSchema = new(new List<Field> {new("table_type", StringType.Default, false)}, null);
-    public static readonly Schema DbSchemaFlightSchema = new(new List<Field> {new("catalog_name", StringType.Default, true), new("db_schema_name", StringType.Default, false)}, null);
-
-    public static readonly Schema PrimaryKeysSchema = new(new List<Field>
-    {
-        new("catalog_name", StringType.Default, true),
-        new("db_schema_name", StringType.Default, true),
-        new("table_name", StringType.Default, false),
-        new("column_name", StringType.Default, false),
-        new("key_sequence", Int32Type.Default, false),
-        new("key_name", StringType.Default, true)
-    }, null);
-
-    public static readonly Schema KeyImportExportSchema = new(new List<Field>
-    {
-        new("pk_catalog_name", StringType.Default, true),
-        new("pk_db_schema_name", StringType.Default, true),
-        new("pk_table_name", StringType.Default, false),
-        new("pk_column_name", StringType.Default, false),
-        new("fk_catalog_name", StringType.Default, true),
-        new("fk_db_schema_name", StringType.Default, true),
-        new("fk_table_name", StringType.Default, false),
-        new("fk_column_name", StringType.Default, false),
-        new("key_sequence", Int32Type.Default, false),
-        new("fk_key_name", StringType.Default, true),
-        new("pk_key_name", StringType.Default, true),
-        new("update_rule", UInt8Type.Default, false),
-        new("delete_rule", UInt8Type.Default, false)
-    }, null);
-
-    public static readonly Schema TypeInfoSchema = new(new List<Field>
-    {
-        new("type_name", StringType.Default, false),
-        new("data_type", Int32Type.Default, false),
-        new("column_size", Int32Type.Default, true),
-        new("literal_prefix", StringType.Default, true),
-        new("literal_suffix", StringType.Default, true),
-        new("create_params", new ListType(new Field("item", StringType.Default, false)), true),
-        new("nullable", Int32Type.Default, false),
-        new("case_sensitive", BooleanType.Default, false),
-        new("searchable", Int32Type.Default, false),
-        new("unsigned_attribute", BooleanType.Default, true),
-        new("fixed_prec_scale", BooleanType.Default, false),
-        new("auto_increment", BooleanType.Default, true),
-        new("local_type_name", StringType.Default, true),
-        new("minimum_scale", Int32Type.Default, true),
-        new("maximum_scale", Int32Type.Default, true),
-        new("sql_data_type", Int32Type.Default, false),
-        new("datetime_subcode", Int32Type.Default, true),
-        new("num_prec_radix", Int32Type.Default, true),
-        new("interval_precision", Int32Type.Default, true)
-    }, null);
-
-    public static readonly Schema SqlInfoSchema = new(new List<Field>
-    {
-        new("info_name", UInt32Type.Default, false)
-        //TODO: once we have union serialization in Arrow Flight for .Net we should to add these fields
-        // fieldList.Add(new Field("value", new UnionType(new List<Field>(), new List<byte>()), false));
-        // fieldList.Add(new Field("value", new UnionType(new []
-        // {
-        //     new Field("string_value", StringType.Default, false),
-        //     new Field("bool_value", BooleanType.Default, false),
-        //     new Field("bigint_value", Int64Type.Default, false),
-        //     new Field("bool_value", BooleanType.Default, false),
-        //     new Field("bigint_value", Int64Type.Default, false),
-        //     new Field("int32_bitmask", Int32Type.Default, false),
-        //     new Field("string_list", new ListType(new Field("item", StringType.Default, false)), false),
-        //     new Field("int32_to_int32_list_map", new DictionaryType(Int32Type.Default, new ListType(Int32Type.Default), false), false),
-        // }, new []{(byte)ArrowTypeId.String, (byte)ArrowTypeId.Boolean, (byte)ArrowTypeId.Int64,/* (byte)3, (byte)4, (byte)5*/}, UnionMode.Dense), false));
-    }, null);
-
-    private static readonly Schema s_tableSchema = new(new List<Field>
-    {
-        new("catalog_name", StringType.Default, true),
-        new("db_schema_name", StringType.Default, true),
-        new("table_name", StringType.Default, false),
-        new("table_type", StringType.Default, false)
-    }, null);
-
-    public static Schema GetTableSchema(bool includeTableSchemaField)
-    {
-        if (!includeTableSchemaField)
-        {
-            return s_tableSchema;
-        }
-
-        var fields = s_tableSchema.FieldsList.ToList();
-        fields.Add(new Field("table_schema", BinaryType.Default, false));
-
-        return new Schema(fields, s_tableSchema.Metadata);
-    }
-
-    public static IMessage? GetCommand(FlightTicket ticket)
-    {
-        try
-        {
-            return GetCommand(Any.Parser.ParseFrom(ticket.Ticket));
-        }
-        catch (InvalidProtocolBufferException) { } //The ticket is not a flight sql command
-
-        return null;
-    }
-
-    public static async Task<IMessage?> GetCommand(FlightServerRecordBatchStreamReader requestStream)
-    {
-        return GetCommand(await requestStream.FlightDescriptor.ConfigureAwait(false));
-    }
-
-    public static IMessage? GetCommand(FlightDescriptor? request)
-    {
-        if (request == null) return null;
-        if (request.Type == FlightDescriptorType.Command && request.ParsedAndUnpackedMessage() is { } command)
-        {
-            return command;
-        }
-
-        return null;
-    }
-
-    private static IMessage? GetCommand(Any command)
-    {
-        if (command.Is(CommandPreparedStatementQuery.Descriptor))
-        {
-            return command.Unpack<CommandPreparedStatementQuery>();
-        }
-
-        if (command.Is(CommandGetSqlInfo.Descriptor))
-        {
-            return command.Unpack<CommandGetSqlInfo>();
-        }
-
-        if (command.Is(CommandGetCatalogs.Descriptor))
-        {
-            return command.Unpack<CommandGetCatalogs>();
-        }
-
-        if (command.Is(CommandGetTableTypes.Descriptor))
-        {
-            return command.Unpack<CommandGetTableTypes>();
-        }
-
-        if (command.Is(CommandGetTables.Descriptor))
-        {
-            return command.Unpack<CommandGetTables>();
-        }
-
-        if (command.Is(CommandGetDbSchemas.Descriptor))
-        {
-            return command.Unpack<CommandGetDbSchemas>();
-        }
-
-        if (command.Is(CommandGetPrimaryKeys.Descriptor))
-        {
-            return command.Unpack<CommandGetPrimaryKeys>();
-        }
-
-        if (command.Is(CommandGetExportedKeys.Descriptor))
-        {
-            return command.Unpack<CommandGetExportedKeys>();
-        }
-
-        if (command.Is(CommandGetImportedKeys.Descriptor))
-        {
-            return command.Unpack<CommandGetImportedKeys>();
-        }
-
-        if (command.Is(CommandGetCrossReference.Descriptor))
-        {
-            return command.Unpack<CommandGetCrossReference>();
-        }
-
-        if (command.Is(CommandGetXdbcTypeInfo.Descriptor))
-        {
-            return command.Unpack<CommandGetXdbcTypeInfo>();
-        }
-
-        return null;
-    }
-
-    protected FlightSqlServer(ILoggerFactory? factory = null)
-    {
-        Logger = factory?.CreateLogger(typeof(FlightSqlServer));
-    }
-
-    /// <summary>
-    /// Lists actions supported by Flight SQL.  For Flight RPC actions support
-    /// implementers should extend this method to return additional supported actions.
-    /// </summary>
-    public override async Task ListActions(IAsyncStreamWriter<FlightActionType> responseStream, ServerCallContext context)
-    {
-        foreach (var actionType in FlightSqlUtils.FlightSqlActions)
-        {
-            await responseStream.WriteAsync(actionType).ConfigureAwait(false);
-        }
-    }
-
-    /// <summary>
-    /// Attempts to execute a valid Flight SQL command.  For Flight RPC calls
-    /// implementers should extend this method in order to handle RPC messages.
-    /// </summary>
-    public override Task<FlightInfo> GetFlightInfo(FlightDescriptor flightDescriptor, ServerCallContext context)
-    {
-        var sqlCommand = GetCommand(flightDescriptor);
-        Logger?.LogTrace("Executing Flight SQL FlightInfo command: {DescriptorName}", sqlCommand?.Descriptor.Name);
-        return sqlCommand switch
-        {
-            CommandStatementQuery command => GetStatementQueryFlightInfo(command, flightDescriptor, context),
-            CommandPreparedStatementQuery command => GetPreparedStatementQueryFlightInfo(command, flightDescriptor, context),
-            CommandGetCatalogs command => GetCatalogFlightInfo(command, flightDescriptor, context),
-            CommandGetDbSchemas command => GetDbSchemaFlightInfo(command, flightDescriptor, context),
-            CommandGetTables command => GetTablesFlightInfo(command, flightDescriptor, context),
-            CommandGetTableTypes command => GetTableTypesFlightInfo(command, flightDescriptor, context),
-            CommandGetSqlInfo command => GetSqlFlightInfo(command, flightDescriptor, context),
-            CommandGetPrimaryKeys command => GetPrimaryKeysFlightInfo(command, flightDescriptor, context),
-            CommandGetExportedKeys command => GetExportedKeysFlightInfo(command, flightDescriptor, context),
-            CommandGetImportedKeys command => GetImportedKeysFlightInfo(command, flightDescriptor, context),
-            CommandGetCrossReference command => GetCrossReferenceFlightInfo(command, flightDescriptor, context),
-            CommandGetXdbcTypeInfo command => GetXdbcTypeFlightInfo(command, flightDescriptor, context),
-            _ => throw new InvalidOperationException($"command type {sqlCommand?.Descriptor?.Name} not supported")
-        };
-    }
-
-    /// <summary>
-    /// Attempts to execute a valid Flight SQL command.  For Flight RPC calls
-    /// implementers should extend this method in order to handle RPC messages.
-    /// </summary>
-    public override Task DoGet(FlightTicket ticket, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context)
-    {
-        var sqlCommand = GetCommand(ticket);
-        Logger?.LogTrace("Executing Flight SQL DoGet command: {SqlCommandDescriptor}", sqlCommand?.Descriptor);
-        return sqlCommand switch
-        {
-            CommandPreparedStatementQuery command => DoGetPreparedStatementQuery(command, responseStream, context),
-            CommandGetSqlInfo command => DoGetSqlInfo(command, responseStream, context),
-            CommandGetCatalogs command => DoGetCatalog(command, responseStream, context),
-            CommandGetTableTypes command => DoGetTableType(command, responseStream, context),
-            CommandGetTables command => DoGetTables(command, responseStream, context),
-            CommandGetDbSchemas command => DoGetDbSchema(command, responseStream, context),
-            CommandGetPrimaryKeys command => DoGetPrimaryKeys(command, responseStream, context),
-            CommandGetExportedKeys command => DoGetExportedKeys(command, responseStream, context),
-            CommandGetImportedKeys command => DoGetImportedKeys(command, responseStream, context),
-            CommandGetCrossReference command => DoGetCrossReference(command, responseStream, context),
-            CommandGetXdbcTypeInfo command => DoGetXbdcTypeInfo(command, responseStream, context),
-            _ => throw new RpcException(new Status(StatusCode.InvalidArgument, $"DoGet command {sqlCommand?.Descriptor} is not supported."))
-        };
-    }
-
-    /// <summary>
-    /// Attempts to execute a valid Flight SQL command.  For Flight RPC calls
-    /// implementers should extend this method in order to handle RPC messages.
-    /// </summary>
-    public override Task DoAction(FlightAction action, IAsyncStreamWriter<FlightResult> responseStream, ServerCallContext context)
-    {
-        Logger?.LogTrace("Executing Flight SQL DoAction: {ActionType}", action.Type);
-        switch (action.Type)
-        {
-            case SqlAction.CreateRequest:
-                var command = FlightSqlUtils.ParseAndUnpack<ActionCreatePreparedStatementRequest>(action.Body);
-                return CreatePreparedStatement(command, action, responseStream, context);
-            case SqlAction.CloseRequest:
-                var closeCommand = FlightSqlUtils.ParseAndUnpack<ActionClosePreparedStatementRequest>(action.Body);
-                return ClosePreparedStatement(closeCommand, action, responseStream, context);
-            default:
-                throw new NotImplementedException($"Action type {action.Type} not supported");
-        }
-    }
-
-    /// <summary>
-    /// Attempts to execute a valid Flight SQL command.  For Flight RPC calls
-    /// implementers should extend this method in order to handle RPC messages.
-    /// </summary>
-    public override async Task DoPut(FlightServerRecordBatchStreamReader requestStream, IAsyncStreamWriter<FlightPutResult> responseStream, ServerCallContext context)
-    {
-        if (await GetCommand(requestStream).ConfigureAwait(false) is { } command)
-        {
-            await DoPutInternal(command, requestStream, responseStream, context).ConfigureAwait(false);
-        }
-        else
-        {
-            throw new NotImplementedException();
-        }
-    }
-
-    private Task DoPutInternal(IMessage command, FlightServerRecordBatchStreamReader requestStream, IAsyncStreamWriter<FlightPutResult> responseStream, ServerCallContext context)
-    {
-        Logger?.LogTrace("Executing Flight SQL DoAction: {DescriptorName}", command.Descriptor.Name);
-        return command switch
-        {
-            CommandStatementUpdate statementUpdate => PutStatementUpdate(statementUpdate, requestStream, responseStream, context),
-            CommandPreparedStatementQuery preparedStatementQuery => PutPreparedStatementQuery(preparedStatementQuery, requestStream, responseStream, context),
-            CommandPreparedStatementUpdate preparedStatementUpdate => PutPreparedStatementUpdate(preparedStatementUpdate, requestStream, responseStream, context),
-            _ => throw new NotImplementedException($"Command {command.Descriptor.Name} not supported")
-        };
-    }
-
-    public static bool SupportsAction(FlightAction action)
-    {
-        switch (action.Type)
-        {
-            case SqlAction.CreateRequest:
-            case SqlAction.CloseRequest:
-                return true;
-            default:
-                return false;
-        }
-    }
-
-
-    #region FlightInfo
-
-    protected abstract Task<FlightInfo> GetStatementQueryFlightInfo(CommandStatementQuery commandStatementQuery, FlightDescriptor flightDescriptor, ServerCallContext context);
-    protected abstract Task<FlightInfo> GetPreparedStatementQueryFlightInfo(CommandPreparedStatementQuery preparedStatementQuery, FlightDescriptor flightDescriptor, ServerCallContext context);
-    protected abstract Task<FlightInfo> GetCatalogFlightInfo(CommandGetCatalogs command, FlightDescriptor flightDescriptor, ServerCallContext context);
-    protected abstract Task<FlightInfo> GetDbSchemaFlightInfo(CommandGetDbSchemas command, FlightDescriptor flightDescriptor, ServerCallContext context);
-    protected abstract Task<FlightInfo> GetTablesFlightInfo(CommandGetTables command, FlightDescriptor flightDescriptor, ServerCallContext context);
-    protected abstract Task<FlightInfo> GetTableTypesFlightInfo(CommandGetTableTypes command, FlightDescriptor flightDescriptor, ServerCallContext context);
-    protected abstract Task<FlightInfo> GetSqlFlightInfo(CommandGetSqlInfo commandGetSqlInfo, FlightDescriptor flightDescriptor, ServerCallContext context);
-    protected abstract Task<FlightInfo> GetPrimaryKeysFlightInfo(CommandGetPrimaryKeys command, FlightDescriptor flightDescriptor, ServerCallContext context);
-    protected abstract Task<FlightInfo> GetExportedKeysFlightInfo(CommandGetExportedKeys command, FlightDescriptor flightDescriptor, ServerCallContext context);
-    protected abstract Task<FlightInfo> GetImportedKeysFlightInfo(CommandGetImportedKeys command, FlightDescriptor flightDescriptor, ServerCallContext context);
-    protected abstract Task<FlightInfo> GetCrossReferenceFlightInfo(CommandGetCrossReference command, FlightDescriptor flightDescriptor, ServerCallContext context);
-    protected abstract Task<FlightInfo> GetXdbcTypeFlightInfo(CommandGetXdbcTypeInfo command, FlightDescriptor flightDescriptor, ServerCallContext context);
-
-    #endregion
-
-    #region DoGet
-
-    protected abstract Task DoGetPreparedStatementQuery(CommandPreparedStatementQuery preparedStatementQuery, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context);
-    protected abstract Task DoGetSqlInfo(CommandGetSqlInfo getSqlInfo, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context);
-    protected abstract Task DoGetCatalog(CommandGetCatalogs command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context);
-    protected abstract Task DoGetTableType(CommandGetTableTypes command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context);
-    protected abstract Task DoGetTables(CommandGetTables command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context);
-    protected abstract Task DoGetPrimaryKeys(CommandGetPrimaryKeys command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context);
-    protected abstract Task DoGetDbSchema(CommandGetDbSchemas command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context);
-    protected abstract Task DoGetExportedKeys(CommandGetExportedKeys command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context);
-    protected abstract Task DoGetImportedKeys(CommandGetImportedKeys command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context);
-    protected abstract Task DoGetCrossReference(CommandGetCrossReference command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context);
-    protected abstract Task DoGetXbdcTypeInfo(CommandGetXdbcTypeInfo command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context);
-
-    #endregion
-
-    #region DoAction
-
-    protected abstract Task CreatePreparedStatement(ActionCreatePreparedStatementRequest request, FlightAction action, IAsyncStreamWriter<FlightResult> streamWriter, ServerCallContext context);
-    protected abstract Task ClosePreparedStatement(ActionClosePreparedStatementRequest request, FlightAction action, IAsyncStreamWriter<FlightResult> streamWriter, ServerCallContext context);
-
-    #endregion
-
-    #region DoPut
-
-    protected abstract Task PutPreparedStatementUpdate(CommandPreparedStatementUpdate command, FlightServerRecordBatchStreamReader requestStream, IAsyncStreamWriter<FlightPutResult> responseStream, ServerCallContext context);
-    protected abstract Task PutStatementUpdate(CommandStatementUpdate command, FlightServerRecordBatchStreamReader requestStream, IAsyncStreamWriter<FlightPutResult> responseStream, ServerCallContext context);
-    protected abstract Task PutPreparedStatementQuery(CommandPreparedStatementQuery command, FlightServerRecordBatchStreamReader requestStream, IAsyncStreamWriter<FlightPutResult> responseStream, ServerCallContext context);
-
-    #endregion
-}
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/FlightSqlUtils.cs b/csharp/src/Apache.Arrow.Flight.Sql/FlightSqlUtils.cs
deleted file mode 100644
index 295fe4d..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/FlightSqlUtils.cs
+++ /dev/null
@@ -1,158 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.Collections.Generic;
-using Arrow.Flight.Protocol.Sql;
-using Google.Protobuf;
-using Google.Protobuf.WellKnownTypes;
-
-namespace Apache.Arrow.Flight.Sql
-{
-    /// <summary>
-    /// Helper methods for doing common Flight Sql tasks and conversions
-    /// </summary>
-    public class FlightSqlUtils
-    {
-        public static readonly FlightActionType FlightSqlCreatePreparedStatement = new("CreatePreparedStatement",
-            "Creates a reusable prepared statement resource on the server. \n" +
-            "Request Message: ActionCreatePreparedStatementRequest\n" +
-            "Response Message: ActionCreatePreparedStatementResult");
-
-        public static readonly FlightActionType FlightSqlClosePreparedStatement = new("ClosePreparedStatement",
-            "Closes a reusable prepared statement resource on the server. \n" +
-            "Request Message: ActionClosePreparedStatementRequest\n" +
-            "Response Message: N/A");
-
-        /// <summary>
-        /// List of possible actions
-        /// </summary>
-        public static readonly List<FlightActionType> FlightSqlActions = new()
-        {
-            FlightSqlCreatePreparedStatement,
-            FlightSqlClosePreparedStatement
-        };
-
-        /// <summary>
-        /// Helper to parse {@link com.google.protobuf.Any} objects to the specific protobuf object.
-        /// </summary>
-        /// <param name="source">the raw bytes source value.</param>
-        /// <returns>the materialized protobuf object.</returns>
-        public static Any Parse(ByteString source)
-        {
-            return Any.Parser.ParseFrom(source);
-        }
-
-        /// <summary>
-        /// Helper to unpack {@link com.google.protobuf.Any} objects to the specific protobuf object.
-        /// </summary>
-        /// <param name="source">the parsed Source value.</param>
-        /// <typeparam name="T">IMessage</typeparam>
-        /// <returns>the materialized protobuf object.</returns>
-        public static T Unpack<T>(Any source) where T : IMessage, new()
-        {
-            return source.Unpack<T>();
-        }
-
-        /// <summary>
-        /// Helper to parse and unpack {@link com.google.protobuf.Any} objects to the specific protobuf object.
-        /// </summary>
-        /// <param name="source">the raw bytes source value.</param>
-        /// <typeparam name="T">IMessage</typeparam>
-        /// <returns>the materialized protobuf object.</returns>
-        public static T ParseAndUnpack<T>(ByteString source) where T : IMessage, new()
-        {
-            return Unpack<T>(Parse(source));
-        }
-    }
-
-    /// <summary>
-    /// A set of helper functions for converting encoded commands to IMessage types
-    /// </summary>
-    public static class FlightSqlExtensions
-    {
-        private static Any ParsedCommand(this FlightDescriptor descriptor)
-        {
-            return FlightSqlUtils.Parse(descriptor.Command);
-        }
-
-        private static IMessage UnpackMessage(this Any command)
-        {
-            if (command.Is(CommandStatementQuery.Descriptor))
-                return FlightSqlUtils.Unpack<CommandStatementQuery>(command);
-            if (command.Is(CommandPreparedStatementQuery.Descriptor))
-                return FlightSqlUtils.Unpack<CommandPreparedStatementQuery>(command);
-            if (command.Is(CommandGetCatalogs.Descriptor))
-                return FlightSqlUtils.Unpack<CommandGetCatalogs>(command);
-            if (command.Is(CommandGetDbSchemas.Descriptor))
-                return FlightSqlUtils.Unpack<CommandGetDbSchemas>(command);
-            if (command.Is(CommandGetTables.Descriptor))
-                return FlightSqlUtils.Unpack<CommandGetTables>(command);
-            if (command.Is(CommandGetTableTypes.Descriptor))
-                return FlightSqlUtils.Unpack<CommandGetTableTypes>(command);
-            if (command.Is(CommandGetSqlInfo.Descriptor))
-                return FlightSqlUtils.Unpack<CommandGetSqlInfo>(command);
-            if (command.Is(CommandGetPrimaryKeys.Descriptor))
-                return FlightSqlUtils.Unpack<CommandGetPrimaryKeys>(command);
-            if (command.Is(CommandGetExportedKeys.Descriptor))
-                return FlightSqlUtils.Unpack<CommandGetExportedKeys>(command);
-            if (command.Is(CommandGetImportedKeys.Descriptor))
-                return FlightSqlUtils.Unpack<CommandGetImportedKeys>(command);
-            if (command.Is(CommandGetCrossReference.Descriptor))
-                return FlightSqlUtils.Unpack<CommandGetCrossReference>(command);
-            if (command.Is(CommandGetXdbcTypeInfo.Descriptor))
-                return FlightSqlUtils.Unpack<CommandGetXdbcTypeInfo>(command);
-            if (command.Is(TicketStatementQuery.Descriptor))
-                return FlightSqlUtils.Unpack<TicketStatementQuery>(command);
-            if (command.Is(TicketStatementQuery.Descriptor))
-                return FlightSqlUtils.Unpack<TicketStatementQuery>(command);
-            if (command.Is(CommandStatementUpdate.Descriptor))
-                return FlightSqlUtils.Unpack<CommandStatementUpdate>(command);
-            if (command.Is(CommandPreparedStatementUpdate.Descriptor))
-                return FlightSqlUtils.Unpack<CommandPreparedStatementUpdate>(command);
-            if (command.Is(CommandPreparedStatementQuery.Descriptor))
-                return FlightSqlUtils.Unpack<CommandPreparedStatementQuery>(command);
-
-            throw new ArgumentException("The defined request is invalid.");
-        }
-
-        /// <summary>
-        /// Extracts a command from a FlightDescriptor
-        /// </summary>
-        /// <param name="descriptor"></param>
-        /// <returns>An IMessage that has been parsed and unpacked</returns>
-        public static IMessage? ParsedAndUnpackedMessage(this FlightDescriptor descriptor)
-        {
-            try
-            {
-                return descriptor.ParsedCommand().UnpackMessage();
-            }
-            catch (ArgumentException)
-            {
-                return null;
-            }
-        }
-
-        public static ByteString Serialize(this IBufferMessage message)
-        {
-            int size = message.CalculateSize();
-            var writer = new ArrayBufferWriter<byte>(size);
-            message.WriteTo(writer);
-            var schemaBytes = writer.WrittenSpan;
-            return ByteString.CopyFrom(schemaBytes);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/PreparedStatement.cs b/csharp/src/Apache.Arrow.Flight.Sql/PreparedStatement.cs
deleted file mode 100644
index 0c49d03..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/PreparedStatement.cs
+++ /dev/null
@@ -1,402 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Sql.Client;
-using Arrow.Flight.Protocol.Sql;
-using Google.Protobuf;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Sql;
-
-public class PreparedStatement : IDisposable, IAsyncDisposable
-{
-    private readonly FlightSqlClient _client;
-    private readonly string _handle;
-    private RecordBatch? _recordsBatch;
-    private bool _isClosed;
-    public Schema DatasetSchema { get; }
-    public Schema ParameterSchema { get; }
-    public bool IsClosed => _isClosed;
-    public string Handle => _handle;
-    public RecordBatch? ParametersBatch => _recordsBatch;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="PreparedStatement"/> class.
-    /// </summary>
-    /// <param name="client">The Flight SQL client used for executing SQL operations.</param>
-    /// <param name="handle">The handle representing the prepared statement.</param>
-    /// <param name="datasetSchema">The schema of the result dataset.</param>
-    /// <param name="parameterSchema">The schema of the parameters for this prepared statement.</param>
-    public PreparedStatement(FlightSqlClient client, string handle, Schema datasetSchema, Schema parameterSchema)
-    {
-        _client = client ?? throw new ArgumentNullException(nameof(client));
-        _handle = handle ?? throw new ArgumentNullException(nameof(handle));
-        DatasetSchema = datasetSchema ?? throw new ArgumentNullException(nameof(datasetSchema));
-        ParameterSchema = parameterSchema ?? throw new ArgumentNullException(nameof(parameterSchema));
-        _isClosed = false;
-    }
-
-    /// <summary>
-    /// Retrieves the schema associated with the prepared statement asynchronously.
-    /// </summary>
-    /// <param name="options">The options used to configure the Flight call.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>A task representing the asynchronous operation, which returns the schema of the result set.</returns>
-    /// <exception cref="InvalidOperationException">Thrown when the schema is empty or invalid.</exception>
-    public async Task<Schema> GetSchemaAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        EnsureStatementIsNotClosed();
-
-        try
-        {
-            var command = new CommandPreparedStatementQuery
-            {
-                PreparedStatementHandle = ByteString.CopyFrom(_handle, Encoding.UTF8)
-            };
-            var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-            var schema = await _client.GetSchemaAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-            if (schema == null || !schema.FieldsList.Any())
-            {
-                throw new InvalidOperationException("Schema is empty or invalid.");
-            }
-            return schema;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to retrieve the schema for the prepared statement", ex);
-        }
-    }
-
-    /// <summary>
-    /// Closes the prepared statement asynchronously.
-    /// </summary>
-    /// <param name="options">The options used to configure the Flight call.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>A task representing the asynchronous operation.</returns>
-    /// <exception cref="InvalidOperationException">Thrown if closing the prepared statement fails.</exception>
-    public async Task CloseAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        EnsureStatementIsNotClosed();
-        try
-        {
-            var closeRequest = new ActionClosePreparedStatementRequest
-            {
-                PreparedStatementHandle = ByteString.CopyFrom(_handle, Encoding.UTF8)
-            };
-
-            var action = new FlightAction(SqlAction.CloseRequest, closeRequest.PackAndSerialize());
-            await foreach (var result in _client.DoActionAsync(action, options, cancellationToken).ConfigureAwait(false))
-            {
-                // Just drain the results to complete the operation
-            }
-
-            _isClosed = true;
-        }
-        catch (RpcException ex)
-        {
-            throw new InvalidOperationException("Failed to close the prepared statement", ex);
-        }
-    }
-
-    /// <summary>
-    /// Reads the result from an asynchronous stream of FlightData and populates the provided Protobuf message.
-    /// </summary>
-    /// <param name="results">The asynchronous stream of <see cref="FlightData"/> objects.</param>
-    /// <param name="message">The Protobuf message to populate with the data from the stream.</param>
-    /// <returns>A task that represents the asynchronous read operation.</returns>
-    /// <exception cref="ArgumentNullException">Thrown if <paramref name="results"/> or <paramref name="message"/> is null.</exception>
-    /// <exception cref="InvalidOperationException">Thrown if parsing the data fails.</exception>
-    public async Task ReadResultAsync(IAsyncEnumerable<FlightData> results, IMessage message)
-    {
-        if (results == null) throw new ArgumentNullException(nameof(results));
-        if (message == null) throw new ArgumentNullException(nameof(message));
-
-        await foreach (var flightData in results.ConfigureAwait(false))
-        {
-            if (flightData.DataBody == null || flightData.DataBody.Length == 0)
-                continue;
-
-            try
-            {
-                message.MergeFrom(message.PackAndSerialize());
-            }
-            catch (InvalidProtocolBufferException ex)
-            {
-                throw new InvalidOperationException("Failed to parse the received FlightData into the specified message.", ex);
-            }
-        }
-    }
-
-    /// <summary>
-    /// Parses the response of a prepared statement execution from the FlightData stream.
-    /// </summary>
-    /// <param name="client">The Flight SQL client.</param>
-    /// <param name="results">The asynchronous stream of <see cref="FlightData"/> objects.</param>
-    /// <returns>A task representing the asynchronous operation, which returns the populated <see cref="PreparedStatement"/>.</returns>
-    /// <exception cref="ArgumentNullException">Thrown if <paramref name="client"/> or <paramref name="results"/> is null.</exception>
-    /// <exception cref="InvalidOperationException">Thrown if the prepared statement handle or data is invalid.</exception>
-    public async Task<PreparedStatement> ParseResponseAsync(FlightSqlClient client, IAsyncEnumerable<FlightData> results)
-    {
-        if (client == null)
-            throw new ArgumentNullException(nameof(client));
-
-        if (results == null)
-            throw new ArgumentNullException(nameof(results));
-
-        var preparedStatementResult = new ActionCreatePreparedStatementResult();
-        await foreach (var flightData in results.ConfigureAwait(false))
-        {
-            if (flightData.DataBody == null || flightData.DataBody.Length == 0)
-            {
-                continue;
-            }
-
-            try
-            {
-                preparedStatementResult.MergeFrom(flightData.DataBody.ToByteArray());
-            }
-            catch (InvalidProtocolBufferException ex)
-            {
-                throw new InvalidOperationException("Failed to parse FlightData into ActionCreatePreparedStatementResult.", ex);
-            }
-        }
-
-        if (preparedStatementResult.PreparedStatementHandle.Length == 0)
-        {
-            throw new InvalidOperationException("Received an empty or invalid PreparedStatementHandle.");
-        }
-
-        Schema datasetSchema = null!;
-        Schema parameterSchema = null!;
-
-        if (preparedStatementResult.DatasetSchema.Length > 0)
-        {
-            datasetSchema = SchemaExtensions.DeserializeSchema(preparedStatementResult.DatasetSchema.ToByteArray());
-        }
-
-        if (preparedStatementResult.ParameterSchema.Length > 0)
-        {
-            parameterSchema = SchemaExtensions.DeserializeSchema(preparedStatementResult.ParameterSchema.ToByteArray());
-        }
-
-        // Create and return the PreparedStatement object
-        return new PreparedStatement(client, preparedStatementResult.PreparedStatementHandle.ToStringUtf8(),
-            datasetSchema, parameterSchema);
-    }
-
-    /// <summary>
-    /// Binds the specified parameter batch to the prepared statement and returns the status.
-    /// </summary>
-    /// <param name="parameterBatch">The <see cref="RecordBatch"/> containing parameters to bind to the statement.</param>
-    /// <param name="cancellationToken">A cancellation token for the binding operation.</param>
-    /// <returns>A <see cref="Status"/> indicating success or failure.</returns>
-    /// <exception cref="ArgumentNullException">Thrown if <paramref name="parameterBatch"/> is null.</exception>
-    public void SetParameters(RecordBatch parameterBatch)
-    {
-        _recordsBatch = parameterBatch ?? throw new ArgumentNullException(nameof(parameterBatch));
-    }
-
-    /// <summary>
-    /// Executes the prepared statement asynchronously and retrieves the query results as <see cref="FlightInfo"/>.
-    /// </summary>
-    /// <param name="options">Optional <see cref="FlightCallOptions"/>The <see cref="FlightCallOptions"/> for the operation, which may include timeouts, headers, and other options for the call.</param>
-    /// <param name="cancellationToken">Optional <see cref="CancellationToken"/> to observe while waiting for the task to complete. The task will be canceled if the token is canceled.</param>
-    /// <returns>A <see cref="Task{FlightInfo}"/> representing the asynchronous operation. The task result contains the <see cref="FlightInfo"/> describing the executed query results.</returns>
-    /// <exception cref="InvalidOperationException">Thrown if the prepared statement is closed or if there is an error during execution.</exception>
-    /// <exception cref="OperationCanceledException">Thrown if the operation is canceled by the <paramref name="cancellationToken"/>.</exception>
-    public async Task<FlightInfo> ExecuteAsync(FlightCallOptions? options = default, CancellationToken cancellationToken = default)
-    {
-        EnsureStatementIsNotClosed();
-
-        var command = new CommandPreparedStatementQuery
-        {
-            PreparedStatementHandle = ByteString.CopyFrom(_handle, Encoding.UTF8),
-        };
-        
-        var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-        cancellationToken.ThrowIfCancellationRequested();
-        
-        if (_recordsBatch != null)
-        {
-            await BindParametersAsync(descriptor, _recordsBatch, options, cancellationToken).ConfigureAwait(false);
-        }
-        cancellationToken.ThrowIfCancellationRequested();
-        return await _client.GetFlightInfoAsync(descriptor, options, cancellationToken).ConfigureAwait(false);
-    }
-
-    /// <summary>
-    /// Executes a prepared update statement asynchronously with the provided parameter batch.
-    /// </summary>
-    /// <remarks>
-    /// This method executes an update operation using a prepared statement. The provided <paramref name="parameterBatch"/> 
-    /// is bound to the statement, and the operation is sent to the server. The server processes the update and returns 
-    /// metadata indicating the number of affected rows.
-    /// 
-    /// This operation is asynchronous and can be canceled via the provided <paramref name="cancellationToken"/>.
-    /// </remarks>
-    /// <param name="parameterBatch">
-    /// A <see cref="RecordBatch"/> containing the parameters to be bound to the update statement. 
-    /// This batch should match the schema expected by the prepared statement.
-    /// </param>
-    /// <param name="options">The <see cref="FlightCallOptions"/> for this execution, containing headers and other options.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>
-    /// A <see cref="Task{TResult}"/> representing the asynchronous operation. 
-    /// The task result contains the number of rows affected by the update.
-    /// </returns>
-    /// <exception cref="ArgumentNullException">
-    /// Thrown if <paramref name="parameterBatch"/> is null, as a valid parameter batch is required for execution.
-    /// </exception>
-    /// <exception cref="InvalidOperationException">
-    /// Thrown if the update operation fails for any reason, including when the server returns invalid or empty metadata, 
-    /// or if the operation is canceled via the <paramref name="cancellationToken"/>.
-    /// </exception>
-    /// <example>
-    /// The following example demonstrates how to use the <see cref="ExecuteUpdateAsync"/> method to execute an update operation:
-    /// <code>
-    /// var parameterBatch = CreateParameterBatch();
-    /// var affectedRows = await preparedStatement.ExecuteUpdateAsync(new FlightCallOptions(), parameterBatch);
-    /// Console.WriteLine($"Rows affected: {affectedRows}");
-    /// </code>
-    /// </example>
-    public async Task<long> ExecuteUpdateAsync(
-        RecordBatch parameterBatch,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (parameterBatch == null)
-        {
-            throw new ArgumentNullException(nameof(parameterBatch), "Parameter batch cannot be null.");
-        }
-        
-        var command = new CommandPreparedStatementQuery
-        {
-            PreparedStatementHandle = ByteString.CopyFrom(_handle, Encoding.UTF8),
-        };
-
-        var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize());
-        var metadata = await BindParametersAsync(descriptor, parameterBatch, options, cancellationToken).ConfigureAwait(false);
-
-        try
-        {
-            return ParseAffectedRows(metadata);
-        }
-        catch (OperationCanceledException)
-        {
-            throw new InvalidOperationException("Update operation was canceled.");
-        }
-        catch (Exception ex)
-        {
-            throw new InvalidOperationException("Failed to execute the prepared update statement.", ex);
-        }
-    }
-
-    private long ParseAffectedRows(ByteString metadata)
-    {
-        if (metadata == null || metadata.Length == 0)
-        {
-            throw new InvalidOperationException("Server returned empty metadata, unable to determine affected row count.");
-        }
-
-        var updateResult = new DoPutUpdateResult();
-        updateResult.MergeFrom(metadata);
-        return updateResult.RecordCount;
-    }
-
-    /// <summary>
-    /// Binds parameters to the prepared statement by streaming the given RecordBatch to the server asynchronously.
-    /// </summary>
-    /// <param name="descriptor">The <see cref="FlightDescriptor"/> that identifies the statement or command being executed.</param>
-    /// <param name="parameterBatch">The <see cref="RecordBatch"/> containing the parameters to bind to the prepared statement.</param>
-    /// <param name="options">The <see cref="FlightCallOptions"/> for the operation, which may include timeouts, headers, and other options for the call.</param>
-    /// <param name="cancellationToken">Cancellation token</param>
-    /// <returns>A <see cref="Task{ByteString}"/> that represents the asynchronous operation. The task result contains the metadata from the server after binding the parameters.</returns>
-    /// <exception cref="ArgumentNullException">Thrown when <paramref name="parameterBatch"/> is null.</exception>
-    /// <exception cref="InvalidOperationException">Thrown if the operation is canceled or if there is an error during the DoPut operation.</exception>
-    public async Task<ByteString> BindParametersAsync(
-        FlightDescriptor descriptor,
-        RecordBatch parameterBatch,
-        FlightCallOptions? options = default,
-        CancellationToken cancellationToken = default)
-    {
-        if (parameterBatch == null)
-        {
-            throw new ArgumentNullException(nameof(parameterBatch), @"Parameter batch cannot be null.");
-        }
-        var putResult = await _client.DoPutAsync(descriptor, parameterBatch, options, cancellationToken).ConfigureAwait(false);
-        try
-        {
-            var metadata = putResult.ApplicationMetadata;
-            return metadata;
-        }
-        catch (OperationCanceledException)
-        {
-            throw new InvalidOperationException("Parameter binding was canceled.");
-        }
-        catch (Exception ex)
-        {
-            throw new InvalidOperationException("Failed to bind parameters to the prepared statement.", ex);
-        }
-    }
-
-    /// <summary>
-    /// Ensures that the statement is not already closed.
-    /// </summary>
-    private void EnsureStatementIsNotClosed()
-    {
-        if (_isClosed)
-            throw new InvalidOperationException("Cannot execute a closed statement.");
-    }
-
-    /// <summary>
-    /// Disposes of the resources used by the prepared statement.
-    /// </summary>
-    public void Dispose()
-    {
-        Dispose(true);
-        GC.SuppressFinalize(this);
-    }
-
-    /// <summary>
-    /// Disposes of the resources used by the prepared statement.
-    /// </summary>
-    /// <param name="disposing">Whether the method is called from <see cref="Dispose()"/>.</param>
-    protected virtual void Dispose(bool disposing)
-    {
-        if (_isClosed) return;
-
-        if (disposing)
-        {
-            DisposeAsync().GetAwaiter().GetResult();
-        }
-
-        _isClosed = true;
-    }
-
-    public async ValueTask DisposeAsync()
-    {
-        if (!_isClosed)
-        {
-            await CloseAsync(new FlightCallOptions());
-            _isClosed = true;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/SchemaExtensions.cs b/csharp/src/Apache.Arrow.Flight.Sql/SchemaExtensions.cs
deleted file mode 100644
index e734736..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/SchemaExtensions.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-using Apache.Arrow.Ipc;
-
-namespace Apache.Arrow.Flight.Sql;
-
-public static class SchemaExtensions
-{
-    /// <summary>
-    /// Deserializes a schema from a byte array.
-    /// </summary>
-    /// <param name="serializedSchema">The byte array representing the serialized schema.</param>
-    /// <returns>The deserialized Schema object.</returns>
-    public static Schema DeserializeSchema(ReadOnlyMemory<byte> serializedSchema)
-    {
-        if (serializedSchema.IsEmpty)
-        {
-            throw new ArgumentException("Invalid serialized schema", nameof(serializedSchema));
-        }
-        using var reader = new ArrowStreamReader(serializedSchema);
-        return reader.Schema;
-    }
-    
-    /// <summary>
-    /// Serializes the provided schema to a byte array.
-    /// </summary>
-    public static byte[] SerializeSchema(Schema schema)
-    {
-        using var memoryStream = new MemoryStream();
-        using var writer = new ArrowStreamWriter(memoryStream, schema);
-        writer.WriteStart(); 
-        writer.WriteEnd();
-        return memoryStream.ToArray();
-    }
-}
\ No newline at end of file
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/SqlActions.cs b/csharp/src/Apache.Arrow.Flight.Sql/SqlActions.cs
deleted file mode 100644
index aea5a35..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/SqlActions.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Flight.Sql;
-
-public static class SqlAction
-{
-    public const string CreateRequest = "CreatePreparedStatement";
-    public const string CloseRequest = "ClosePreparedStatement";
-    public const string CancelFlightInfoRequest = "CancelFlightInfo";
-    public const string BeginTransactionRequest = "BeginTransaction";
-    public const string CommitRequest = "Commit";
-    public const string RollbackRequest = "Rollback";
-    public const string GetPrimaryKeysRequest = "GetPrimaryKeys";
-}
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/TableRef.cs b/csharp/src/Apache.Arrow.Flight.Sql/TableRef.cs
deleted file mode 100644
index 9c98e5f..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/TableRef.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Flight.Sql;
-
-public class TableRef
-{
-    public string? Catalog { get; }
-    public string DbSchema { get; }
-    public string Table { get; }
-
-    public TableRef(string dbSchema, string table)
-    {
-        DbSchema = dbSchema ?? throw new ArgumentNullException(nameof(dbSchema));
-        Table = table ?? throw new ArgumentNullException(nameof(table));
-    }
-
-    public TableRef(string? catalog, string dbSchema, string table)
-    {
-        Catalog = catalog;
-        DbSchema = dbSchema ?? throw new ArgumentNullException(nameof(dbSchema));
-        Table = table ?? throw new ArgumentNullException(nameof(table));
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight.Sql/Transaction.cs b/csharp/src/Apache.Arrow.Flight.Sql/Transaction.cs
deleted file mode 100644
index bc3b738..0000000
--- a/csharp/src/Apache.Arrow.Flight.Sql/Transaction.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Flight.Sql;
-
-using System;
-using Google.Protobuf;
-
-public readonly struct Transaction : IEquatable<Transaction>
-{
-    private static readonly ByteString TransactionIdDefaultValue = ByteString.Empty;
-
-    private readonly ByteString _transactionId;
-
-    public ByteString TransactionId => _transactionId ?? TransactionIdDefaultValue;
-
-    public static readonly Transaction NoTransaction = new(TransactionIdDefaultValue);
-
-    public Transaction(ByteString transactionId)
-    {
-        _transactionId = ProtoPreconditions.CheckNotNull(transactionId, nameof(transactionId));
-    }
-
-    public Transaction(string transactionId)
-    {
-        _transactionId = ByteString.CopyFromUtf8(transactionId);
-    }
-
-    public bool IsValid => TransactionId.Length > 0;
-
-    public override bool Equals(object? obj)
-    {
-        if (obj is not Transaction other)
-            return false;
-
-        return Equals(other);
-    }
-
-    public bool Equals(Transaction other)
-    {
-        // Safe compare even if _transactionId is null (from default(Transaction))  
-        return (_transactionId ?? TransactionIdDefaultValue)
-            .Equals(other._transactionId);
-    }
-
-    public override int GetHashCode() => (_transactionId ?? TransactionIdDefaultValue).GetHashCode();
-
-    public static bool operator ==(Transaction left, Transaction right) => left.Equals(right);
-    public static bool operator !=(Transaction left, Transaction right) => !left.Equals(right);
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Apache.Arrow.Flight.csproj b/csharp/src/Apache.Arrow.Flight/Apache.Arrow.Flight.csproj
deleted file mode 100644
index 78c58e3..0000000
--- a/csharp/src/Apache.Arrow.Flight/Apache.Arrow.Flight.csproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFrameworks>netstandard2.0;netstandard2.1;net472</TargetFrameworks>
-  </PropertyGroup>
-  
-  <ItemGroup>
-    <PackageReference Include="Google.Protobuf" Version="3.32.0" />
-    <PackageReference Include="Grpc.Net.Client" Version="2.65.0" />
-    <PackageReference Include="Grpc.Tools" Version="2.72.0" PrivateAssets="All" />
-    <PackageReference Include="System.Memory" Version="4.6.0" />
-  </ItemGroup>
-
-  <ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
-    <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
-  </ItemGroup>
-  
-  <ItemGroup Condition="'$(TargetFramework)'=='net472'">
-    <PackageReference Include="Grpc.Core" Version="2.46.6" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\Apache.Arrow\Apache.Arrow.csproj" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <Protobuf Include="..\..\..\format\Flight.proto" Access="internal" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/src/Apache.Arrow.Flight/Client/FlightClient.cs b/csharp/src/Apache.Arrow.Flight/Client/FlightClient.cs
deleted file mode 100644
index d094266..0000000
--- a/csharp/src/Apache.Arrow.Flight/Client/FlightClient.cs
+++ /dev/null
@@ -1,256 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Internal;
-using Apache.Arrow.Flight.Protocol;
-using Apache.Arrow.Flight.Server.Internal;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Client
-{
-    public class FlightClient
-    {
-        internal static readonly Empty EmptyInstance = new Empty();
-
-        private readonly FlightService.FlightServiceClient _client;
-
-        public FlightClient(ChannelBase grpcChannel)
-        {
-            _client = new FlightService.FlightServiceClient(grpcChannel);
-        }
-
-        public FlightClient(CallInvoker callInvoker)
-        {
-            _client = new FlightService.FlightServiceClient(callInvoker);
-        }
-
-        public AsyncServerStreamingCall<FlightInfo> ListFlights(FlightCriteria criteria = null, Metadata headers = null)
-        {
-            return ListFlights(criteria, headers, null, CancellationToken.None);
-        }
-
-        public AsyncServerStreamingCall<FlightInfo> ListFlights(FlightCriteria criteria, Metadata headers, System.DateTime? deadline, CancellationToken cancellationToken = default)
-        {
-            if (criteria == null)
-            {
-                criteria = FlightCriteria.Empty;
-            }
-
-            var response = _client.ListFlights(criteria.ToProtocol(), headers, deadline, cancellationToken);
-            var convertStream = new StreamReader<Protocol.FlightInfo, FlightInfo>(response.ResponseStream, inFlight => new FlightInfo(inFlight));
-
-            return new AsyncServerStreamingCall<FlightInfo>(convertStream, response.ResponseHeadersAsync, response.GetStatus, response.GetTrailers, response.Dispose);
-        }
-
-        public AsyncServerStreamingCall<FlightActionType> ListActions(Metadata headers = null)
-        {
-            return ListActions(headers, null, CancellationToken.None);
-        }
-
-        public AsyncServerStreamingCall<FlightActionType> ListActions(Metadata headers, System.DateTime? deadline, CancellationToken cancellationToken = default)
-        {
-            var response = _client.ListActions(EmptyInstance, headers, deadline, cancellationToken);
-            var convertStream = new StreamReader<Protocol.ActionType, FlightActionType>(response.ResponseStream, actionType => new FlightActionType(actionType));
-
-            return new AsyncServerStreamingCall<FlightActionType>(convertStream, response.ResponseHeadersAsync, response.GetStatus, response.GetTrailers, response.Dispose);
-        }
-
-        public FlightRecordBatchStreamingCall GetStream(FlightTicket ticket, Metadata headers = null)
-        {
-            return GetStream(ticket, headers, null, CancellationToken.None);
-        }
-
-        public FlightRecordBatchStreamingCall GetStream(FlightTicket ticket, Metadata headers, System.DateTime? deadline, CancellationToken cancellationToken = default)
-        {
-            var stream = _client.DoGet(ticket.ToProtocol(), headers, deadline, cancellationToken);
-            var responseStream = new FlightClientRecordBatchStreamReader(stream.ResponseStream);
-            return new FlightRecordBatchStreamingCall(responseStream, stream.ResponseHeadersAsync, stream.GetStatus, stream.GetTrailers, stream.Dispose);
-        }
-
-        public AsyncUnaryCall<FlightInfo> GetInfo(FlightDescriptor flightDescriptor, Metadata headers = null)
-        {
-            return GetInfo(flightDescriptor, headers, null, CancellationToken.None);
-        }
-
-        public AsyncUnaryCall<FlightInfo> GetInfo(FlightDescriptor flightDescriptor, Metadata headers, System.DateTime? deadline, CancellationToken cancellationToken = default)
-        {
-            var flightInfoResult = _client.GetFlightInfoAsync(flightDescriptor.ToProtocol(), headers, deadline, cancellationToken);
-
-            var flightInfo = flightInfoResult
-                .ResponseAsync
-                .ContinueWith(async flightInfo => new FlightInfo(await flightInfo.ConfigureAwait(false)))
-                .Unwrap();
-
-            return new AsyncUnaryCall<FlightInfo>(
-                flightInfo,
-                flightInfoResult.ResponseHeadersAsync,
-                flightInfoResult.GetStatus,
-                flightInfoResult.GetTrailers,
-                flightInfoResult.Dispose);
-        }
-
-        /// <summary>
-        /// Start a Flight Put request.
-        /// </summary>
-        /// <param name="flightDescriptor">Descriptor for the data to be put</param>
-        /// <param name="headers">gRPC headers to send with the request</param>
-        /// <returns>A <see cref="FlightRecordBatchDuplexStreamingCall" /> object used to write data batches and receive responses</returns>
-        public FlightRecordBatchDuplexStreamingCall StartPut(FlightDescriptor flightDescriptor, Metadata headers = null)
-        {
-            return StartPut(flightDescriptor, headers, null, CancellationToken.None);
-        }
-
-        /// <summary>
-        /// Start a Flight Put request.
-        /// </summary>
-        /// <param name="flightDescriptor">Descriptor for the data to be put</param>
-        /// <param name="schema">The schema of the data</param>
-        /// <param name="headers">gRPC headers to send with the request</param>
-        /// <returns>A <see cref="FlightRecordBatchDuplexStreamingCall" /> object used to write data batches and receive responses</returns>
-        /// <remarks>Using this method rather than a StartPut overload that doesn't accept a schema
-        /// means that the schema is sent even if no data batches are sent</remarks>
-        public Task<FlightRecordBatchDuplexStreamingCall> StartPut(FlightDescriptor flightDescriptor, Schema schema, Metadata headers = null)
-        {
-            return StartPut(flightDescriptor, schema, headers, null, CancellationToken.None);
-        }
-
-        /// <summary>
-        /// Start a Flight Put request.
-        /// </summary>
-        /// <param name="flightDescriptor">Descriptor for the data to be put</param>
-        /// <param name="headers">gRPC headers to send with the request</param>
-        /// <param name="deadline">Optional deadline. The request will be cancelled if this deadline is reached.</param>
-        /// <param name="cancellationToken">Optional token for cancelling the request</param>
-        /// <returns>A <see cref="FlightRecordBatchDuplexStreamingCall" /> object used to write data batches and receive responses</returns>
-        public FlightRecordBatchDuplexStreamingCall StartPut(FlightDescriptor flightDescriptor, Metadata headers, System.DateTime? deadline, CancellationToken cancellationToken = default)
-        {
-            var channels = _client.DoPut(headers, deadline, cancellationToken);
-            var requestStream = new FlightClientRecordBatchStreamWriter(channels.RequestStream, flightDescriptor);
-            var readStream = new StreamReader<Protocol.PutResult, FlightPutResult>(channels.ResponseStream, putResult => new FlightPutResult(putResult));
-            return new FlightRecordBatchDuplexStreamingCall(
-                requestStream,
-                readStream,
-                channels.ResponseHeadersAsync,
-                channels.GetStatus,
-                channels.GetTrailers,
-                channels.Dispose);
-        }
-
-        /// <summary>
-        /// Start a Flight Put request.
-        /// </summary>
-        /// <param name="flightDescriptor">Descriptor for the data to be put</param>
-        /// <param name="schema">The schema of the data</param>
-        /// <param name="headers">gRPC headers to send with the request</param>
-        /// <param name="deadline">Optional deadline. The request will be cancelled if this deadline is reached.</param>
-        /// <param name="cancellationToken">Optional token for cancelling the request</param>
-        /// <returns>A <see cref="FlightRecordBatchDuplexStreamingCall" /> object used to write data batches and receive responses</returns>
-        /// <remarks>Using this method rather than a StartPut overload that doesn't accept a schema
-        /// means that the schema is sent even if no data batches are sent</remarks>
-        public async Task<FlightRecordBatchDuplexStreamingCall> StartPut(FlightDescriptor flightDescriptor, Schema schema, Metadata headers, System.DateTime? deadline, CancellationToken cancellationToken = default)
-        {
-            var channels = _client.DoPut(headers, deadline, cancellationToken);
-            var requestStream = new FlightClientRecordBatchStreamWriter(channels.RequestStream, flightDescriptor);
-            var readStream = new StreamReader<Protocol.PutResult, FlightPutResult>(channels.ResponseStream, putResult => new FlightPutResult(putResult));
-            var streamingCall = new FlightRecordBatchDuplexStreamingCall(
-                requestStream,
-                readStream,
-                channels.ResponseHeadersAsync,
-                channels.GetStatus,
-                channels.GetTrailers,
-                channels.Dispose);
-            await streamingCall.RequestStream.SetupStream(schema).ConfigureAwait(false);
-            return streamingCall;
-        }
-
-        public AsyncDuplexStreamingCall<FlightHandshakeRequest, FlightHandshakeResponse> Handshake(Metadata headers = null)
-        {
-            return Handshake(headers, null, CancellationToken.None);
-        }
-
-        public AsyncDuplexStreamingCall<FlightHandshakeRequest, FlightHandshakeResponse> Handshake(Metadata headers, System.DateTime? deadline, CancellationToken cancellationToken = default)
-        {
-            var channel = _client.Handshake(headers, deadline, cancellationToken);
-            var readStream = new StreamReader<HandshakeResponse, FlightHandshakeResponse>(channel.ResponseStream, response => new FlightHandshakeResponse(response));
-            var writeStream = new FlightHandshakeStreamWriterAdapter(channel.RequestStream);
-            var call = new AsyncDuplexStreamingCall<FlightHandshakeRequest, FlightHandshakeResponse>(
-                writeStream,
-                readStream,
-                channel.ResponseHeadersAsync,
-                channel.GetStatus,
-                channel.GetTrailers,
-                channel.Dispose);
-
-            return call;
-        }
-
-        public FlightRecordBatchExchangeCall DoExchange(FlightDescriptor flightDescriptor, Metadata headers = null)
-        {
-            return DoExchange(flightDescriptor, headers, null, CancellationToken.None);
-        }
-
-        public FlightRecordBatchExchangeCall DoExchange(FlightDescriptor flightDescriptor, Metadata headers, System.DateTime? deadline, CancellationToken cancellationToken = default)
-        {
-            var channel = _client.DoExchange(headers, deadline, cancellationToken);
-            var requestStream = new FlightClientRecordBatchStreamWriter(channel.RequestStream, flightDescriptor);
-            var responseStream = new FlightClientRecordBatchStreamReader(channel.ResponseStream);
-            var call = new FlightRecordBatchExchangeCall(
-                requestStream,
-                responseStream,
-                channel.ResponseHeadersAsync,
-                channel.GetStatus,
-                channel.GetTrailers,
-                channel.Dispose);
-
-            return call;
-        }
-
-        public AsyncServerStreamingCall<FlightResult> DoAction(FlightAction action, Metadata headers = null)
-        {
-            return DoAction(action, headers, null, CancellationToken.None);
-        }
-
-        public AsyncServerStreamingCall<FlightResult> DoAction(FlightAction action, Metadata headers, System.DateTime? deadline, CancellationToken cancellationToken = default)
-        {
-            var stream = _client.DoAction(action.ToProtocol(), headers, deadline, cancellationToken);
-            var streamReader = new StreamReader<Protocol.Result, FlightResult>(stream.ResponseStream, result => new FlightResult(result));
-            return new AsyncServerStreamingCall<FlightResult>(streamReader, stream.ResponseHeadersAsync, stream.GetStatus, stream.GetTrailers, stream.Dispose);
-        }
-
-        public AsyncUnaryCall<Schema> GetSchema(FlightDescriptor flightDescriptor, Metadata headers = null)
-        {
-            return GetSchema(flightDescriptor, headers, null, CancellationToken.None);
-        }
-
-        public AsyncUnaryCall<Schema> GetSchema(FlightDescriptor flightDescriptor, Metadata headers, System.DateTime? deadline, CancellationToken cancellationToken = default)
-        {
-            var schemaResult = _client.GetSchemaAsync(flightDescriptor.ToProtocol(), headers, deadline, cancellationToken);
-
-            var schema = schemaResult
-                .ResponseAsync
-                .ContinueWith(async schema => FlightMessageSerializer.DecodeSchema((await schemaResult.ResponseAsync.ConfigureAwait(false)).Schema.Memory))
-                .Unwrap();
-
-            return new AsyncUnaryCall<Schema>(
-                schema,
-                schemaResult.ResponseHeadersAsync,
-                schemaResult.GetStatus,
-                schemaResult.GetTrailers,
-                schemaResult.Dispose);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Client/FlightClientRecordBatchStreamReader.cs b/csharp/src/Apache.Arrow.Flight/Client/FlightClientRecordBatchStreamReader.cs
deleted file mode 100644
index 7309433..0000000
--- a/csharp/src/Apache.Arrow.Flight/Client/FlightClientRecordBatchStreamReader.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Flight.Protocol;
-using Apache.Arrow.Flight.Internal;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Client
-{
-    public class FlightClientRecordBatchStreamReader : FlightRecordBatchStreamReader
-    {
-        internal FlightClientRecordBatchStreamReader(IAsyncStreamReader<Protocol.FlightData> flightDataStream) : base(flightDataStream)
-        {
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Client/FlightClientRecordBatchStreamWriter.cs b/csharp/src/Apache.Arrow.Flight/Client/FlightClientRecordBatchStreamWriter.cs
deleted file mode 100644
index e5fa30c..0000000
--- a/csharp/src/Apache.Arrow.Flight/Client/FlightClientRecordBatchStreamWriter.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Protocol;
-using Apache.Arrow.Flight.Internal;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Client
-{
-    public class FlightClientRecordBatchStreamWriter : FlightRecordBatchStreamWriter, IClientStreamWriter<RecordBatch>
-    {
-        private readonly IClientStreamWriter<Protocol.FlightData> _clientStreamWriter;
-        private bool _completed = false;
-        internal FlightClientRecordBatchStreamWriter(IClientStreamWriter<Protocol.FlightData> clientStreamWriter, FlightDescriptor flightDescriptor) : base(clientStreamWriter, flightDescriptor)
-        {
-            _clientStreamWriter = clientStreamWriter;
-        }
-
-        protected override void Dispose(bool disposing)
-        {
-            if (!_completed)
-            {
-                throw new InvalidOperationException("Dispose called before completing the stream.");
-            }
-
-            base.Dispose(disposing);
-        }
-
-        public async Task CompleteAsync()
-        {
-            if (_completed)
-            {
-                return;
-            }
-
-            await _clientStreamWriter.CompleteAsync().ConfigureAwait(false);
-            _completed = true;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Client/FlightRecordBatchDuplexStreamingCall.cs b/csharp/src/Apache.Arrow.Flight/Client/FlightRecordBatchDuplexStreamingCall.cs
deleted file mode 100644
index c9e6ecd..0000000
--- a/csharp/src/Apache.Arrow.Flight/Client/FlightRecordBatchDuplexStreamingCall.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Threading.Tasks;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Client
-{
-    public class FlightRecordBatchDuplexStreamingCall : IDisposable
-    {
-        private readonly Func<Status> _getStatusFunc;
-        private readonly Func<Metadata> _getTrailersFunc;
-        private readonly Action _disposeAction;
-
-        internal FlightRecordBatchDuplexStreamingCall(
-            FlightClientRecordBatchStreamWriter requestStream,
-            IAsyncStreamReader<FlightPutResult> responseStream,
-            Task<Metadata> responseHeadersAsync,
-            Func<Status> getStatusFunc,
-            Func<Metadata> getTrailersFunc,
-            Action disposeAction)
-        {
-            RequestStream = requestStream;
-            ResponseStream = responseStream;
-            ResponseHeadersAsync = responseHeadersAsync;
-            _getStatusFunc = getStatusFunc;
-            _getTrailersFunc = getTrailersFunc;
-            _disposeAction = disposeAction;
-        }
-
-        /// <summary>
-        ///  Async stream to read streaming responses.
-        /// </summary>
-        public IAsyncStreamReader<FlightPutResult> ResponseStream { get; }
-
-        /// <summary>
-        /// Async stream to send streaming requests.
-        /// </summary>
-        public FlightClientRecordBatchStreamWriter RequestStream { get; }
-
-        /// <summary>
-        /// Asynchronous access to response headers.
-        /// </summary>
-        public Task<Metadata> ResponseHeadersAsync { get; }
-
-        /// <summary>
-        /// Provides means to cleanup after the call. If the call has already finished normally
-        /// (response stream has been fully read), doesn't do anything. Otherwise, requests
-        /// cancellation of the call which should terminate all pending async operations
-        /// associated with the call. As a result, all resources being used by the call should
-        /// be released eventually.
-        /// </summary>
-        /// <remarks>
-        /// Normally, there is no need for you to dispose the call unless you want to utilize
-        /// the "Cancel" semantics of invoking Dispose.
-        /// </remarks>
-        public void Dispose()
-        {
-            _disposeAction();
-        }
-
-        /// <summary>
-        /// Gets the call status if the call has already finished. Throws InvalidOperationException otherwise.
-        /// </summary>
-        /// <returns></returns>
-        public Status GetStatus()
-        {
-            return _getStatusFunc();
-        }
-
-        /// <summary>
-        /// Gets the call trailing metadata if the call has already finished. Throws InvalidOperationException otherwise.
-        /// </summary>
-        /// <returns></returns>
-        public Metadata GetTrailers()
-        {
-            return _getTrailersFunc();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Client/FlightRecordBatchExchangeCall.cs b/csharp/src/Apache.Arrow.Flight/Client/FlightRecordBatchExchangeCall.cs
deleted file mode 100644
index 76f0b17..0000000
--- a/csharp/src/Apache.Arrow.Flight/Client/FlightRecordBatchExchangeCall.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Grpc.Core;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.Flight.Client
-{
-    public class FlightRecordBatchExchangeCall : IDisposable
-    {
-        private readonly Func<Status> _getStatusFunc;
-        private readonly Func<Metadata> _getTrailersFunc;
-        private readonly Action _disposeAction;
-
-        internal FlightRecordBatchExchangeCall(
-            FlightClientRecordBatchStreamWriter requestStream,
-            FlightClientRecordBatchStreamReader responseStream,
-            Task<Metadata> responseHeadersAsync,
-            Func<Status> getStatusFunc,
-            Func<Metadata> getTrailersFunc,
-            Action disposeAction)
-        {
-            RequestStream = requestStream;
-            ResponseStream = responseStream;
-            ResponseHeadersAsync = responseHeadersAsync;
-            _getStatusFunc = getStatusFunc;
-            _getTrailersFunc = getTrailersFunc;
-            _disposeAction = disposeAction;
-        }
-
-        /// <summary>
-        ///  Async stream to read streaming responses.
-        /// </summary>
-        public FlightClientRecordBatchStreamReader ResponseStream { get; }
-
-        /// <summary>
-        /// Async stream to send streaming requests.
-        /// </summary>
-        public FlightClientRecordBatchStreamWriter RequestStream { get; }
-
-        /// <summary>
-        /// Asynchronous access to response headers.
-        /// </summary>
-        public Task<Metadata> ResponseHeadersAsync { get; }
-
-        /// <summary>
-        /// Provides means to cleanup after the call. If the call has already finished normally
-        /// (response stream has been fully read), doesn't do anything. Otherwise, requests
-        /// cancellation of the call which should terminate all pending async operations
-        /// associated with the call. As a result, all resources being used by the call should
-        /// be released eventually.
-        /// </summary>
-        /// <remarks>
-        /// Normally, there is no need for you to dispose the call unless you want to utilize
-        /// the "Cancel" semantics of invoking Dispose.
-        /// </remarks>
-        public void Dispose()
-        {
-            _disposeAction();
-        }
-
-        /// <summary>
-        /// Gets the call status if the call has already finished. Throws InvalidOperationException otherwise.
-        /// </summary>
-        /// <returns></returns>
-        public Status GetStatus()
-        {
-            return _getStatusFunc();
-        }
-
-        /// <summary>
-        /// Gets the call trailing metadata if the call has already finished. Throws InvalidOperationException otherwise.
-        /// </summary>
-        /// <returns></returns>
-        public Metadata GetTrailers()
-        {
-            return _getTrailersFunc();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Client/FlightRecordBatchStreamingCall.cs b/csharp/src/Apache.Arrow.Flight/Client/FlightRecordBatchStreamingCall.cs
deleted file mode 100644
index 246cfa7..0000000
--- a/csharp/src/Apache.Arrow.Flight/Client/FlightRecordBatchStreamingCall.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Threading.Tasks;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Client
-{
-    public class FlightRecordBatchStreamingCall : IDisposable
-    {
-        private readonly Func<Status> _getStatusFunc;
-        private readonly Func<Metadata> _getTrailersFunc;
-        private readonly Action _disposeAction;
-
-        internal FlightRecordBatchStreamingCall(
-            FlightClientRecordBatchStreamReader recordBatchStreamReader,
-            Task<Metadata> responseHeadersAsync,
-            Func<Status> getStatusFunc,
-            Func<Metadata> getTrailersFunc,
-            Action disposeAction)
-        {
-            ResponseStream = recordBatchStreamReader;
-            ResponseHeadersAsync = responseHeadersAsync;
-            _getStatusFunc = getStatusFunc;
-            _getTrailersFunc = getTrailersFunc;
-            _disposeAction = disposeAction;
-        }
-
-        public FlightClientRecordBatchStreamReader ResponseStream { get; }
-
-        /// <summary>
-        /// Asynchronous access to response headers.
-        /// </summary>
-        public Task<Metadata> ResponseHeadersAsync { get; }
-
-        /// <summary>
-        /// Gets the call status if the call has already finished. Throws InvalidOperationException otherwise.
-        /// </summary>
-        /// <returns></returns>
-        public Status GetStatus()
-        {
-            return _getStatusFunc();
-        }
-
-        /// <summary>
-        /// Gets the call trailing metadata if the call has already finished. Throws InvalidOperationException otherwise.
-        /// </summary>
-        /// <returns></returns>
-        public Metadata GetTrailers()
-        {
-            return _getTrailersFunc();
-        }
-
-        /// <summary>
-        /// Provides means to cleanup after the call. If the call has already finished normally
-        /// (response stream has been fully read), doesn't do anything. Otherwise, requests
-        /// cancellation of the call which should terminate all pending async operations
-        /// associated with the call. As a result, all resources being used by the call should
-        /// be released eventually.
-        /// </summary>
-        /// <remarks>
-        /// Normally, there is no need for you to dispose the call unless you want to utilize
-        /// the "Cancel" semantics of invoking Dispose.
-        /// </remarks>
-        public void Dispose()
-        {
-            _disposeAction();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Extensions/FlightInfoExtensions.cs b/csharp/src/Apache.Arrow.Flight/Extensions/FlightInfoExtensions.cs
deleted file mode 100644
index 706e092..0000000
--- a/csharp/src/Apache.Arrow.Flight/Extensions/FlightInfoExtensions.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Google.Protobuf;
-
-
-namespace Apache.Arrow.Flight.Extensions
-{
-    public static class FlightInfoExtensions
-    {
-        public static ByteString ToByteString(this FlightInfo flightInfo)
-        { 
-            return flightInfo.ToProtocol().ToByteString();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightAction.cs b/csharp/src/Apache.Arrow.Flight/FlightAction.cs
deleted file mode 100644
index 4a82fa6..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightAction.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight
-{
-    public class FlightAction
-    {
-        private readonly Protocol.Action _action;
-        internal FlightAction(Protocol.Action action)
-        {
-            _action = action;
-        }
-
-        public FlightAction(string type, ByteString body)
-        {
-            _action = new Protocol.Action()
-            {
-                Body = body,
-                Type = type
-            };
-        }
-
-        public FlightAction(string type, string body)
-        {
-            _action = new Protocol.Action()
-            {
-                Body = ByteString.CopyFromUtf8(body),
-                Type = type
-            };
-        }
-
-        public FlightAction(string type, byte[] body)
-        {
-            _action = new Protocol.Action()
-            {
-                Body = ByteString.CopyFrom(body),
-                Type = type
-            };
-        }
-
-        public FlightAction(string type)
-        {
-            _action = new Protocol.Action()
-            {
-                Type = type
-            };
-        }
-
-        public string Type => _action.Type;
-
-        public ByteString Body => _action.Body;
-
-        internal Protocol.Action ToProtocol()
-        {
-            return _action;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightActionType.cs b/csharp/src/Apache.Arrow.Flight/FlightActionType.cs
deleted file mode 100644
index 8df8939..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightActionType.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Apache.Arrow.Flight
-{
-    public class FlightActionType
-    {
-        private readonly Protocol.ActionType _actionType;
-        internal FlightActionType(Protocol.ActionType actionType)
-        {
-            _actionType = actionType;
-        }
-
-        public FlightActionType(string type, string description)
-        {
-            _actionType = new Protocol.ActionType()
-            {
-                Description = description,
-                Type = type
-            };
-        }
-
-        public string Type => _actionType.Type;
-        public string Description => _actionType.Description;
-
-        internal Protocol.ActionType ToProtocol()
-        {
-            return _actionType;
-        }
-
-        public override bool Equals(object obj)
-        {
-            if(obj is FlightActionType other)
-            {
-                return Equals(_actionType, other._actionType);
-            }
-            return false;
-        }
-
-        public override int GetHashCode()
-        {
-            return _actionType.GetHashCode();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightCriteria.cs b/csharp/src/Apache.Arrow.Flight/FlightCriteria.cs
deleted file mode 100644
index 6bcb087..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightCriteria.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight
-{
-    public class FlightCriteria
-    {
-        internal static readonly FlightCriteria Empty = new FlightCriteria();
-
-        private readonly Protocol.Criteria _criteria;
-
-        internal FlightCriteria(Protocol.Criteria criteria)
-        {
-            _criteria = criteria;
-        }
-
-        public FlightCriteria()
-        {
-            _criteria = new Protocol.Criteria();
-        }
-
-        public FlightCriteria(string expression)
-        {
-            _criteria = new Protocol.Criteria()
-            {
-                Expression = ByteString.CopyFromUtf8(expression)
-            };
-        }
-
-        public FlightCriteria(byte[] bytes)
-        {
-            _criteria = new Protocol.Criteria()
-            {
-                Expression = ByteString.CopyFrom(bytes)
-            };
-        }
-
-        public FlightCriteria(ByteString byteString)
-        {
-            _criteria = new Protocol.Criteria()
-            {
-                Expression = byteString
-            };
-        }
-
-        public ByteString Expression => _criteria.Expression;
-
-        internal Protocol.Criteria ToProtocol()
-        {
-            return _criteria;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightData.cs b/csharp/src/Apache.Arrow.Flight/FlightData.cs
deleted file mode 100644
index f38b1de..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightData.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight;
-
-public class FlightData
-{
-    public FlightDescriptor Descriptor { get; }
-    public ByteString AppMetadata { get; }
-    public ByteString DataBody { get; }
-    public ByteString DataHeader { get; }
-
-    public FlightData(FlightDescriptor descriptor, ByteString dataBody = null, ByteString dataHeader = null, ByteString appMetadata = null)
-    {
-        Descriptor = descriptor;
-        DataBody = dataBody;
-        DataHeader = dataHeader;
-        AppMetadata = appMetadata;
-    }
-
-    internal FlightData(Protocol.FlightData protocolFlightData)
-    {
-        Descriptor = protocolFlightData.FlightDescriptor == null ? null : new FlightDescriptor(protocolFlightData.FlightDescriptor);
-        DataBody = protocolFlightData.DataBody;
-        DataHeader = protocolFlightData.DataHeader;
-        AppMetadata = protocolFlightData.AppMetadata;
-    }
-
-    internal Protocol.FlightData ToProtocol()
-    {
-        return new Protocol.FlightData
-        {
-            FlightDescriptor = Descriptor?.ToProtocol(),
-            AppMetadata = AppMetadata,
-            DataBody = DataBody,
-            DataHeader = DataHeader
-        };
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightDescriptor.cs b/csharp/src/Apache.Arrow.Flight/FlightDescriptor.cs
deleted file mode 100644
index 7d44332..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightDescriptor.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight
-{
-    public class FlightDescriptor
-    {
-        private readonly Protocol.FlightDescriptor _flightDescriptor;
-
-        private FlightDescriptor(ByteString command)
-        {
-            _flightDescriptor = new Protocol.FlightDescriptor()
-            {
-                Cmd = command,
-                Type = Protocol.FlightDescriptor.Types.DescriptorType.Cmd
-            };
-        }
-
-        private FlightDescriptor(params string[] paths)
-        {
-            _flightDescriptor = new Protocol.FlightDescriptor()
-            {
-                Type = Protocol.FlightDescriptor.Types.DescriptorType.Path
-            };
-
-            foreach(var path in paths)
-            {
-                _flightDescriptor.Path.Add(path);
-            }
-        }
-
-
-        public static FlightDescriptor CreateCommandDescriptor(byte[] command)
-        {
-            return new FlightDescriptor(ByteString.CopyFrom(command));
-        }
-
-        public static FlightDescriptor CreateCommandDescriptor(string command)
-        {
-            return new FlightDescriptor(ByteString.CopyFromUtf8(command));
-        }
-
-        public static FlightDescriptor CreatePathDescriptor(params string[] paths)
-        {
-            return new FlightDescriptor(paths);
-        }
-
-
-        internal FlightDescriptor(Protocol.FlightDescriptor flightDescriptor)
-        {
-            if(flightDescriptor.Type != Protocol.FlightDescriptor.Types.DescriptorType.Cmd && flightDescriptor.Type != Protocol.FlightDescriptor.Types.DescriptorType.Path)
-            {
-                throw new NotSupportedException();
-            }
-            _flightDescriptor = flightDescriptor;
-        }
-
-        internal Protocol.FlightDescriptor ToProtocol()
-        {
-            return _flightDescriptor;
-        }
-
-        public FlightDescriptorType Type => (FlightDescriptorType)_flightDescriptor.Type;
-
-        public IEnumerable<string> Paths => _flightDescriptor.Path;
-
-        public ByteString Command => _flightDescriptor.Cmd;
-
-
-        public override int GetHashCode()
-        {
-            return _flightDescriptor.GetHashCode();
-        }
-
-        public override bool Equals(object obj)
-        {
-            if(obj is FlightDescriptor other)
-            {
-                return Equals(_flightDescriptor, other._flightDescriptor);
-            }
-            return false;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightDescriptorType.cs b/csharp/src/Apache.Arrow.Flight/FlightDescriptorType.cs
deleted file mode 100644
index 120ed22..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightDescriptorType.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Flight
-{
-    public enum FlightDescriptorType
-    {
-        Path = 1,
-        Command = 2
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightEndpoint.cs b/csharp/src/Apache.Arrow.Flight/FlightEndpoint.cs
deleted file mode 100644
index ab15fed..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightEndpoint.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Apache.Arrow.Flight
-{
-    public class FlightEndpoint
-    {
-        private readonly FlightTicket _ticket;
-        private readonly IReadOnlyList<FlightLocation> _locations;
-        internal FlightEndpoint(Protocol.FlightEndpoint flightEndpoint)
-        {
-            _ticket = new FlightTicket(flightEndpoint.Ticket);
-            _locations = flightEndpoint.Location.Select(x => new FlightLocation(x)).ToList();
-        }
-
-        public FlightEndpoint(FlightTicket ticket, IReadOnlyList<FlightLocation> locations)
-        {
-            _ticket = ticket;
-            _locations = locations;
-        }
-
-        public FlightTicket Ticket => _ticket;
-
-        public IEnumerable<FlightLocation> Locations => _locations;
-
-        internal Protocol.FlightEndpoint ToProtocol()
-        {
-            var output = new Protocol.FlightEndpoint()
-            {
-                Ticket = _ticket.ToProtocol()
-            };
-
-            foreach(var location in _locations)
-            {
-                output.Location.Add(location.ToProtocol());
-            }
-            return output;
-        }
-
-        public override bool Equals(object obj)
-        {
-            if(obj is FlightEndpoint other)
-            {
-                return Equals(_ticket, other._ticket) &&
-                    Enumerable.SequenceEqual(_locations, other._locations);
-            }
-            return false;
-        }
-
-        public override int GetHashCode()
-        {
-            //Ticket should contain enough to get a good hash code
-            return _ticket.GetHashCode();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightHandshakeRequest.cs b/csharp/src/Apache.Arrow.Flight/FlightHandshakeRequest.cs
deleted file mode 100644
index 62db644..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightHandshakeRequest.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight;
-
-public class FlightHandshakeRequest
-{
-    private readonly Protocol.HandshakeRequest _result;
-    public ByteString Payload => _result.Payload;
-    public ulong ProtocolVersion => _result.ProtocolVersion;
-
-    internal FlightHandshakeRequest(Protocol.HandshakeRequest result)
-    {
-        _result = result;
-    }
-
-    public FlightHandshakeRequest(ByteString payload, ulong protocolVersion = 1)
-    {
-        _result = new Protocol.HandshakeRequest
-        {
-            Payload = payload,
-            ProtocolVersion = protocolVersion
-        };
-    }
-
-    internal Protocol.HandshakeRequest ToProtocol()
-    {
-        return _result;
-    }
-
-    public override bool Equals(object obj)
-    {
-        if(obj is FlightHandshakeRequest other)
-        {
-            return Equals(_result, other._result);
-        }
-        return false;
-    }
-
-    public override int GetHashCode()
-    {
-        return _result.GetHashCode();
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightHandshakeResponse.cs b/csharp/src/Apache.Arrow.Flight/FlightHandshakeResponse.cs
deleted file mode 100644
index 4ceb288..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightHandshakeResponse.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight;
-
-public class FlightHandshakeResponse
-{
-    public static readonly FlightHandshakeResponse Empty = new FlightHandshakeResponse();
-    private readonly Protocol.HandshakeResponse _handshakeResponse;
-
-    public ulong ProtocolVersion
-    {
-        get => _handshakeResponse.ProtocolVersion;
-        set => _handshakeResponse.ProtocolVersion = value;
-    }
-
-    public ByteString Payload
-    {
-        get => _handshakeResponse.Payload;
-        set => _handshakeResponse.Payload = value;
-    }
-
-    public FlightHandshakeResponse()
-    {
-        _handshakeResponse = new Protocol.HandshakeResponse
-        {
-            ProtocolVersion = 1
-        };
-    }
-
-    internal FlightHandshakeResponse(Protocol.HandshakeResponse handshakeResponse)
-    {
-        _handshakeResponse = handshakeResponse;
-    }
-
-    public FlightHandshakeResponse(ByteString payload, ulong protocolVersion = 1)
-    {
-        _handshakeResponse = new Protocol.HandshakeResponse
-        {
-            ProtocolVersion = protocolVersion,
-            Payload = payload
-        };
-    }
-
-    internal Protocol.HandshakeResponse ToProtocol()
-    {
-        return _handshakeResponse;
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightInfo.cs b/csharp/src/Apache.Arrow.Flight/FlightInfo.cs
deleted file mode 100644
index 22cd219..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightInfo.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Apache.Arrow.Flight.Internal;
-using Apache.Arrow.Ipc;
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight
-{
-    public class FlightInfo
-    {
-        internal FlightInfo(Protocol.FlightInfo flightInfo)
-        {
-            Schema = flightInfo.Schema?.Length > 0 ? FlightMessageSerializer.DecodeSchema(flightInfo.Schema.Memory) : null;
-            Descriptor = new FlightDescriptor(flightInfo.FlightDescriptor);
-
-            var endpoints = new List<FlightEndpoint>();
-            foreach(var endpoint in flightInfo.Endpoint)
-            {
-                endpoints.Add(new FlightEndpoint(endpoint));
-            }
-            Endpoints = endpoints;
-
-            TotalBytes = flightInfo.TotalBytes;
-            TotalRecords = flightInfo.TotalRecords;
-            Ordered = flightInfo.Ordered;
-            AppMetadata = flightInfo.AppMetadata;
-        }
-        public FlightInfo(Schema schema, FlightDescriptor descriptor, IReadOnlyList<FlightEndpoint> endpoints, long totalRecords = -1, long totalBytes = -1):this(schema,descriptor,endpoints,totalRecords,totalBytes,false, ByteString.Empty)
-        {
-        }
-
-        public FlightInfo(Schema schema, FlightDescriptor descriptor, IReadOnlyList<FlightEndpoint> endpoints, long totalRecords, long totalBytes, bool ordered = false, ByteString appMetadata=null)
-        {
-            Schema = schema;
-            Descriptor = descriptor;
-            Endpoints = endpoints;
-            TotalBytes = totalBytes;
-            TotalRecords = totalRecords;
-            Ordered = ordered;
-            AppMetadata = appMetadata ?? ByteString.Empty;
-        }
-
-        public FlightDescriptor Descriptor { get; }
-
-        public Schema Schema { get; }
-
-        public long TotalBytes { get; }
-
-        public long TotalRecords { get; }
-
-        public bool Ordered { get; }
-
-        public ByteString AppMetadata { get; }
-
-        public IReadOnlyList<FlightEndpoint> Endpoints { get; }
-
-        internal Protocol.FlightInfo ToProtocol()
-        {
-            var serializedSchema = Schema != null ? SchemaWriter.SerializeSchema(Schema) : ByteString.Empty;
-
-            var response = new Protocol.FlightInfo()
-            {
-                Schema = serializedSchema,
-                FlightDescriptor = Descriptor.ToProtocol(),
-                TotalBytes = TotalBytes,
-                TotalRecords = TotalRecords,
-                Ordered = Ordered,
-                AppMetadata = AppMetadata 
-            };
-
-            foreach (var endpoint in Endpoints)
-            {
-                response.Endpoint.Add(endpoint.ToProtocol());
-            }
-
-            return response;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightInfoCancelRequest.cs b/csharp/src/Apache.Arrow.Flight/FlightInfoCancelRequest.cs
deleted file mode 100644
index f4573ef..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightInfoCancelRequest.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Flight.Protocol;
-using Google.Protobuf;
-using Google.Protobuf.Reflection;
-
-namespace Apache.Arrow.Flight;
-
-public class FlightInfoCancelRequest : IMessage
-{
-    private readonly CancelFlightInfoRequest _cancelFlightInfoRequest;
-    public FlightInfo FlightInfo { get; private set; }
-
-    public FlightInfoCancelRequest(FlightInfo flightInfo)
-    {
-        FlightInfo = flightInfo ?? throw new ArgumentNullException(nameof(flightInfo));
-        _cancelFlightInfoRequest = new CancelFlightInfoRequest();
-    }
-
-    public FlightInfoCancelRequest()
-    {
-        _cancelFlightInfoRequest = new CancelFlightInfoRequest();
-    }
-
-    public void MergeFrom(CodedInputStream input)
-    {
-        _cancelFlightInfoRequest.MergeFrom(input);
-    }
-
-    public void WriteTo(CodedOutputStream output)
-    {
-        _cancelFlightInfoRequest.WriteTo(output);
-    }
-
-    public int CalculateSize() => _cancelFlightInfoRequest.CalculateSize();
-
-    public MessageDescriptor Descriptor =>
-        DescriptorReflection.Descriptor.MessageTypes[0];
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightInfoCancelResult.cs b/csharp/src/Apache.Arrow.Flight/FlightInfoCancelResult.cs
deleted file mode 100644
index 14cad66..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightInfoCancelResult.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Flight.Protocol;
-using Google.Protobuf;
-using Google.Protobuf.Reflection;
-
-namespace Apache.Arrow.Flight;
-
-public class FlightInfoCancelResult : IMessage
-{
-    private readonly CancelFlightInfoResult _flightInfoCancelResult;
-
-    public FlightInfoCancelResult()
-    {
-        _flightInfoCancelResult = new CancelFlightInfoResult();
-        Descriptor = DescriptorReflection.Descriptor.MessageTypes[0];
-    }
-
-    public void MergeFrom(CodedInputStream input) => _flightInfoCancelResult.MergeFrom(input);
-
-    public void WriteTo(CodedOutputStream output) => _flightInfoCancelResult.WriteTo(output);
-
-    public int CalculateSize()
-    {
-        return _flightInfoCancelResult.CalculateSize();
-    }
-
-    public MessageDescriptor Descriptor { get; }
-
-    public int GetCancelStatus()
-    {
-        return (int)_flightInfoCancelResult.Status;
-    }
-
-    public void SetStatus(int status)
-    {
-        _flightInfoCancelResult.Status = (CancelStatus)status;
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightLocation.cs b/csharp/src/Apache.Arrow.Flight/FlightLocation.cs
deleted file mode 100644
index 25b9d5d..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightLocation.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Apache.Arrow.Flight
-{
-    public class FlightLocation
-    {
-        private readonly Protocol.Location _location;
-        internal FlightLocation(Protocol.Location location)
-        {
-            _location = location;
-        }
-
-        public FlightLocation(string uri)
-        {
-            _location = new Protocol.Location()
-            {
-                Uri = uri
-            };
-        }
-
-        public string Uri => _location.Uri;
-
-        internal Protocol.Location ToProtocol()
-        {
-            return _location;
-        }
-
-        public override bool Equals(object obj)
-        {
-            if(obj is FlightLocation other)
-            {
-                return Equals(_location, other._location);
-            }
-            return false;
-        }
-
-        public override int GetHashCode()
-        {
-            return _location.GetHashCode();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightPutResult.cs b/csharp/src/Apache.Arrow.Flight/FlightPutResult.cs
deleted file mode 100644
index 16f278a..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightPutResult.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight
-{
-    public class FlightPutResult
-    {
-        public static readonly FlightPutResult Empty = new FlightPutResult();
-
-        private readonly Protocol.PutResult _putResult;
-
-        public FlightPutResult()
-        {
-            _putResult = new Protocol.PutResult();
-        }
-
-        public FlightPutResult(ByteString applicationMetadata)
-        {
-            _putResult = new Protocol.PutResult()
-            {
-                AppMetadata = applicationMetadata
-            };
-        }
-
-        public FlightPutResult(byte[] applicationMetadata)
-            : this(ByteString.CopyFrom(applicationMetadata))
-        {
-        }
-
-        public FlightPutResult(string applicationMetadata)
-            : this(ByteString.CopyFromUtf8(applicationMetadata))
-        {
-        }
-
-        internal FlightPutResult(Protocol.PutResult putResult)
-        {
-            _putResult = putResult;
-        }
-
-        public ByteString ApplicationMetadata => _putResult.AppMetadata;
-
-        internal Protocol.PutResult ToProtocol()
-        {
-            return _putResult;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightRecordBatchStreamReader.cs b/csharp/src/Apache.Arrow.Flight/FlightRecordBatchStreamReader.cs
deleted file mode 100644
index 7400ec1..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightRecordBatchStreamReader.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flatbuf;
-using Apache.Arrow.Flight.Internal;
-using Apache.Arrow.Flight.Protocol;
-using Apache.Arrow.Ipc;
-using Google.Protobuf;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight
-{
-    /// <summary>
-    /// Stream of record batches
-    ///
-    /// Use MoveNext() and Current to iterate over the batches.
-    /// There are also gRPC helper functions such as ToListAsync() etc.
-    /// </summary>
-    public abstract class FlightRecordBatchStreamReader : IAsyncStreamReader<RecordBatch>, IAsyncEnumerable<RecordBatch>, IDisposable
-    {
-        //Temporary until .NET 5.0 upgrade
-        private static ValueTask CompletedValueTask = new ValueTask();
-
-        private readonly RecordBatchReaderImplementation _arrowReaderImplementation;
-
-        private protected FlightRecordBatchStreamReader(IAsyncStreamReader<Protocol.FlightData> flightDataStream)
-        {
-            _arrowReaderImplementation = new RecordBatchReaderImplementation(flightDataStream);
-        }
-
-        public ValueTask<Schema> Schema => _arrowReaderImplementation.GetSchemaAsync();
-
-        internal ValueTask<FlightDescriptor> GetFlightDescriptor()
-        {
-            return _arrowReaderImplementation.ReadFlightDescriptor();
-        }
-
-        /// <summary>
-        /// Get the application metadata from the latest received record batch
-        /// </summary>
-        public IReadOnlyList<ByteString> ApplicationMetadata => _arrowReaderImplementation.ApplicationMetadata;
-
-        public RecordBatch Current { get; private set; }
-
-        public async Task<bool> MoveNext(CancellationToken cancellationToken)
-        {
-            Current = await _arrowReaderImplementation.ReadNextRecordBatchAsync(cancellationToken);
-
-            return Current != null;
-        }
-
-        public IAsyncEnumerator<RecordBatch> GetAsyncEnumerator(CancellationToken cancellationToken = default)
-        {
-            return new AsyncEnumerator(this, cancellationToken);
-        }
-
-        public void Dispose()
-        {
-            _arrowReaderImplementation.Dispose();
-        }
-
-        private class AsyncEnumerator : IAsyncEnumerator<RecordBatch>
-        {
-            private readonly FlightRecordBatchStreamReader _flightRecordBatchStreamReader;
-            private readonly CancellationToken _cancellationToken;
-
-            internal AsyncEnumerator(FlightRecordBatchStreamReader flightRecordBatchStreamReader, CancellationToken cancellationToken)
-            {
-                _flightRecordBatchStreamReader = flightRecordBatchStreamReader;
-                _cancellationToken = cancellationToken;
-            }
-
-            public RecordBatch Current => _flightRecordBatchStreamReader.Current;
-
-            public async ValueTask<bool> MoveNextAsync()
-            {
-                return await _flightRecordBatchStreamReader.MoveNext(_cancellationToken);
-            }
-
-            public ValueTask DisposeAsync()
-            {
-                _flightRecordBatchStreamReader.Dispose();
-                return CompletedValueTask;
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightRecordBatchStreamWriter.cs b/csharp/src/Apache.Arrow.Flight/FlightRecordBatchStreamWriter.cs
deleted file mode 100644
index 314d46d..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightRecordBatchStreamWriter.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Internal;
-using Apache.Arrow.Flight.Protocol;
-using Google.Protobuf;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight
-{
-    public abstract class FlightRecordBatchStreamWriter : IAsyncStreamWriter<RecordBatch>, IDisposable
-    {
-        private FlightDataStream _flightDataStream;
-        private readonly IAsyncStreamWriter<Protocol.FlightData> _clientStreamWriter;
-        private readonly FlightDescriptor _flightDescriptor;
-
-        private bool _disposed;
-
-        private protected FlightRecordBatchStreamWriter(IAsyncStreamWriter<Protocol.FlightData> clientStreamWriter, FlightDescriptor flightDescriptor)
-        {
-            _clientStreamWriter = clientStreamWriter;
-            _flightDescriptor = flightDescriptor;
-        }
-
-        /// <summary>
-        /// Configure the data stream to write to.
-        /// </summary>
-        /// <remarks>
-        /// The stream will be set up automatically when writing a RecordBatch if required,
-        /// but calling this method before writing any data allows handling empty streams.
-        /// </remarks>
-        /// <param name="schema">The schema of data to be written to this stream</param>
-        public async Task SetupStream(Schema schema)
-        {
-            if (_flightDataStream != null)
-            {
-                throw new InvalidOperationException("Flight data stream is already set");
-            }
-            _flightDataStream = new FlightDataStream(_clientStreamWriter, _flightDescriptor, schema);
-            await _flightDataStream.SendSchema().ConfigureAwait(false);
-        }
-
-        public WriteOptions WriteOptions { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
-
-        public Task WriteAsync(RecordBatch message)
-        {
-            return WriteAsync(message, default);
-        }
-
-        public async Task WriteAsync(RecordBatch message, ByteString applicationMetadata)
-        {
-            if (_flightDataStream == null)
-            {
-                await SetupStream(message.Schema).ConfigureAwait(false);
-            }
-
-            await _flightDataStream.Write(message, applicationMetadata);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (!_disposed)
-            {
-                _flightDataStream?.Dispose();
-                _disposed = true;
-            }
-        }
-
-        public void Dispose()
-        {
-            Dispose(true);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightResult.cs b/csharp/src/Apache.Arrow.Flight/FlightResult.cs
deleted file mode 100644
index 3ddadd4..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightResult.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight
-{
-    public class FlightResult
-    {
-        private readonly Protocol.Result _result;
-
-        internal FlightResult(Protocol.Result result)
-        {
-            _result = result;
-        }
-
-        public FlightResult(ByteString body)
-        {
-            _result = new Protocol.Result()
-            {
-                Body = body
-            };
-        }
-
-        public FlightResult(string body)
-            : this(ByteString.CopyFromUtf8(body))
-        {
-        }
-
-        public FlightResult(byte[] body)
-            : this(ByteString.CopyFrom(body))
-        {
-        }
-
-        public ByteString Body => _result.Body;
-
-        internal Protocol.Result ToProtocol()
-        {
-            return _result;
-        }
-
-        public override bool Equals(object obj)
-        {
-            if(obj is FlightResult other)
-            {
-                return Equals(_result, other._result);
-            }
-            return false;
-        }
-
-        public override int GetHashCode()
-        {
-            return _result.GetHashCode();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/FlightTicket.cs b/csharp/src/Apache.Arrow.Flight/FlightTicket.cs
deleted file mode 100644
index 7b3d6dd..0000000
--- a/csharp/src/Apache.Arrow.Flight/FlightTicket.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight
-{
-    public class FlightTicket
-    {
-        private readonly Protocol.Ticket _ticket;
-        internal FlightTicket(Protocol.Ticket ticket)
-        {
-            _ticket = ticket;
-        }
-
-        public FlightTicket(ByteString ticket)
-        {
-            _ticket = new Protocol.Ticket()
-            {
-                Ticket_ = ticket
-            };
-        }
-
-        public FlightTicket(string ticket)
-            : this(ByteString.CopyFromUtf8(ticket))
-        {
-        }
-
-        public FlightTicket(byte[] bytes)
-            : this(ByteString.CopyFrom(bytes))
-        {
-        }
-
-        public ByteString Ticket => _ticket.Ticket_;
-
-        internal Protocol.Ticket ToProtocol()
-        {
-            return _ticket;
-        }
-
-        public override bool Equals(object obj)
-        {
-            if(obj is FlightTicket other)
-            {
-                return Equals(_ticket, other._ticket);
-            }
-            return false;
-        }
-
-        public override int GetHashCode()
-        {
-            return _ticket.GetHashCode();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Internal/FlightDataStream.cs b/csharp/src/Apache.Arrow.Flight/Internal/FlightDataStream.cs
deleted file mode 100644
index 7cbbe66..0000000
--- a/csharp/src/Apache.Arrow.Flight/Internal/FlightDataStream.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flatbuf;
-using Apache.Arrow.Flight.Protocol;
-using Apache.Arrow.Ipc;
-using Google.FlatBuffers;
-using Google.Protobuf;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Internal
-{
-    /// <summary>
-    /// Handles writing record batches as flight data
-    /// </summary>
-    internal class FlightDataStream : ArrowStreamWriter
-    {
-        private readonly FlightDescriptor _flightDescriptor;
-        private readonly IAsyncStreamWriter<Protocol.FlightData> _clientStreamWriter;
-        private Protocol.FlightData _currentFlightData;
-
-        public FlightDataStream(IAsyncStreamWriter<Protocol.FlightData> clientStreamWriter, FlightDescriptor flightDescriptor, Schema schema)
-            : base(new MemoryStream(), schema)
-        {
-            _clientStreamWriter = clientStreamWriter;
-            _flightDescriptor = flightDescriptor;
-        }
-
-        public async Task SendSchema()
-        {
-            _currentFlightData = new Protocol.FlightData();
-
-            if(_flightDescriptor != null)
-            {
-                _currentFlightData.FlightDescriptor = _flightDescriptor.ToProtocol();
-            }
-
-            var offset = SerializeSchema(Schema);
-            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
-            await WriteMessageAsync(MessageHeader.Schema, offset, 0, cancellationTokenSource.Token).ConfigureAwait(false);
-            await _clientStreamWriter.WriteAsync(_currentFlightData).ConfigureAwait(false);
-            HasWrittenSchema = true;
-        }
-
-        private void ResetStream()
-        {
-            this.BaseStream.Position = 0;
-            this.BaseStream.SetLength(0);
-        }
-
-        public async Task Write(RecordBatch recordBatch, ByteString applicationMetadata)
-        {
-            if (!HasWrittenSchema)
-            {
-                await SendSchema().ConfigureAwait(false);
-            }
-            ResetStream();
-
-            _currentFlightData = new Protocol.FlightData();
-
-            if(applicationMetadata != null)
-            {
-                _currentFlightData.AppMetadata = applicationMetadata;
-            }
-
-            await WriteRecordBatchInternalAsync(recordBatch).ConfigureAwait(false);
-
-            //Reset stream position
-            this.BaseStream.Position = 0;
-            var bodyData = await ByteString.FromStreamAsync(this.BaseStream).ConfigureAwait(false);
-
-            _currentFlightData.DataBody = bodyData;
-            await _clientStreamWriter.WriteAsync(_currentFlightData).ConfigureAwait(false);
-        }
-
-        private protected override ValueTask<long> WriteMessageAsync<T>(MessageHeader headerType, Offset<T> headerOffset, int bodyLength, CancellationToken cancellationToken)
-        {
-            Offset<Flatbuf.Message> messageOffset = Flatbuf.Message.CreateMessage(
-                Builder, CurrentMetadataVersion, headerType, headerOffset.Value,
-                bodyLength);
-
-            Builder.Finish(messageOffset.Value);
-
-            ReadOnlyMemory<byte> messageData = Builder.DataBuffer.ToReadOnlyMemory(Builder.DataBuffer.Position, Builder.Offset);
-
-            _currentFlightData.DataHeader = ByteString.CopyFrom(messageData.Span);
-
-            return new ValueTask<long>(0);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Internal/FlightMessageSerializer.cs b/csharp/src/Apache.Arrow.Flight/Internal/FlightMessageSerializer.cs
deleted file mode 100644
index 47ffe43..0000000
--- a/csharp/src/Apache.Arrow.Flight/Internal/FlightMessageSerializer.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers.Binary;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using Apache.Arrow.Ipc;
-using Google.FlatBuffers;
-
-namespace Apache.Arrow.Flight
-{
-    internal static class FlightMessageSerializer
-    {
-        public static Schema DecodeSchema(ReadOnlyMemory<byte> buffer)
-        {
-            if (buffer.IsEmpty) return null;
-            int bufferPosition = 0;
-            int schemaMessageLength = BinaryPrimitives.ReadInt32LittleEndian(buffer.Span.Slice(bufferPosition));
-            bufferPosition += sizeof(int);
-
-            if (schemaMessageLength == MessageSerializer.IpcContinuationToken)
-            {
-                // ARROW-6313, if the first 4 bytes are continuation message, read the next 4 for the length
-                if (buffer.Length <= bufferPosition + sizeof(int))
-                {
-                    throw new InvalidDataException("Corrupted IPC message. Received a continuation token at the end of the message.");
-                }
-
-                schemaMessageLength = BinaryPrimitives.ReadInt32LittleEndian(buffer.Span.Slice(bufferPosition));
-                bufferPosition += sizeof(int);
-            }
-
-            ByteBuffer schemaBuffer = ArrowReaderImplementation.CreateByteBuffer(buffer.Slice(bufferPosition));
-            //DictionaryBatch not supported for now
-            DictionaryMemo dictionaryMemo = null;
-            var schema = MessageSerializer.GetSchema(ArrowReaderImplementation.ReadMessage<Flatbuf.Schema>(schemaBuffer), ref dictionaryMemo);
-            return schema;
-        }
-
-        internal static Schema DecodeSchema(ByteBuffer schemaBuffer)
-        {
-            //DictionaryBatch not supported for now
-            DictionaryMemo dictionaryMemo = null;
-            var schema = MessageSerializer.GetSchema(ArrowReaderImplementation.ReadMessage<Flatbuf.Schema>(schemaBuffer), ref dictionaryMemo);
-            return schema;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Internal/RecordBatchReaderImplementation.cs b/csharp/src/Apache.Arrow.Flight/Internal/RecordBatchReaderImplementation.cs
deleted file mode 100644
index 22d0bd8..0000000
--- a/csharp/src/Apache.Arrow.Flight/Internal/RecordBatchReaderImplementation.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flatbuf;
-using Apache.Arrow.Ipc;
-using Google.Protobuf;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Internal
-{
-    internal class RecordBatchReaderImplementation : ArrowReaderImplementation
-    {
-        private readonly IAsyncStreamReader<Protocol.FlightData> _flightDataStream;
-        private FlightDescriptor _flightDescriptor;
-        private readonly List<ByteString> _applicationMetadatas;
-
-        public RecordBatchReaderImplementation(IAsyncStreamReader<Protocol.FlightData> streamReader)
-        {
-            _flightDataStream = streamReader;
-            _applicationMetadatas = new List<ByteString>();
-        }
-
-        public override RecordBatch ReadNextRecordBatch()
-        {
-            throw new NotImplementedException();
-        }
-
-        public IReadOnlyList<ByteString> ApplicationMetadata => _applicationMetadatas;
-
-        public async ValueTask<FlightDescriptor> ReadFlightDescriptor()
-        {
-            if (!HasReadSchema)
-            {
-                await ReadSchemaAsync(CancellationToken.None).ConfigureAwait(false);
-            }
-            return _flightDescriptor;
-        }
-
-        public async ValueTask<Schema> GetSchemaAsync()
-        {
-            if (!HasReadSchema)
-            {
-                await ReadSchemaAsync(CancellationToken.None).ConfigureAwait(false);
-            }
-            return _schema;
-        }
-
-        public override void ReadSchema()
-        {
-            ReadSchemaAsync(CancellationToken.None).AsTask().Wait();
-        }
-
-        public override async ValueTask ReadSchemaAsync(CancellationToken cancellationToken)
-        {
-            while (!HasReadSchema)
-            {
-                var moveNextResult = await _flightDataStream.MoveNext(cancellationToken).ConfigureAwait(false);
-                if (!moveNextResult)
-                {
-                    throw new Exception("No records or schema in this flight");
-                }
-
-                if (_flightDescriptor == null && _flightDataStream.Current.FlightDescriptor != null)
-                {
-                    _flightDescriptor = new FlightDescriptor(_flightDataStream.Current.FlightDescriptor);
-                }
-
-                // AppMetadata will never be null, but length 0 if empty
-                // Those are skipped
-                if(_flightDataStream.Current.AppMetadata.Length > 0)
-                {
-                    _applicationMetadatas.Add(_flightDataStream.Current.AppMetadata);
-                }
-
-                var header = _flightDataStream.Current.DataHeader.Memory;
-                if (header.IsEmpty)
-                {
-                    // Clients may send a first message with a descriptor only and no schema
-                    continue;
-                }
-
-                Message message = Message.GetRootAsMessage(ArrowReaderImplementation.CreateByteBuffer(header));
-
-                switch (message.HeaderType)
-                {
-                    case MessageHeader.Schema:
-                        _schema = FlightMessageSerializer.DecodeSchema(message.ByteBuffer);
-                        break;
-                    default:
-                        throw new Exception($"Expected schema as the first message, but got: {message.HeaderType.ToString()}");
-                }
-            }
-        }
-
-        public override async ValueTask<RecordBatch> ReadNextRecordBatchAsync(CancellationToken cancellationToken)
-        {
-            _applicationMetadatas.Clear(); //Clear any metadata from previous calls
-
-            if (!HasReadSchema)
-            {
-                await ReadSchemaAsync(cancellationToken).ConfigureAwait(false);
-            }
-            var moveNextResult = await _flightDataStream.MoveNext().ConfigureAwait(false);
-            if (moveNextResult)
-            {
-                //AppMetadata will never be null, but length 0 if empty
-                //Those are skipped
-                if (_flightDataStream.Current.AppMetadata.Length > 0)
-                {
-                    _applicationMetadatas.Add(_flightDataStream.Current.AppMetadata);
-                }
-
-                var header = _flightDataStream.Current.DataHeader.Memory;
-                Message message = Message.GetRootAsMessage(CreateByteBuffer(header));
-
-                switch (message.HeaderType)
-                {
-                    case MessageHeader.RecordBatch:
-                        var body = _flightDataStream.Current.DataBody.Memory;
-                        return CreateArrowObjectFromMessage(message, CreateByteBuffer(body.Slice(0, (int)message.BodyLength)), null);
-                    default:
-                        throw new NotImplementedException();
-                }
-            }
-            return null;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Internal/SchemaWriter.cs b/csharp/src/Apache.Arrow.Flight/Internal/SchemaWriter.cs
deleted file mode 100644
index be27cb1..0000000
--- a/csharp/src/Apache.Arrow.Flight/Internal/SchemaWriter.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flatbuf;
-using Apache.Arrow.Flight.Internal;
-using Apache.Arrow.Ipc;
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight.Internal
-{
-    /// <summary>
-    /// This class handles writing schemas
-    /// </summary>
-    internal class SchemaWriter : ArrowStreamWriter
-    {
-        internal SchemaWriter(Stream baseStream, Schema schema) : base(baseStream, schema)
-        {
-        }
-
-        public void WriteSchema(Schema schema, CancellationToken cancellationToken)
-        {
-            var offset = base.SerializeSchema(schema);
-            WriteMessage(MessageHeader.Schema, offset, 0);
-        }
-
-        public static ByteString SerializeSchema(Schema schema, CancellationToken cancellationToken = default(CancellationToken))
-        {
-            using(var memoryStream = new MemoryStream())
-            {
-                var writer = new SchemaWriter(memoryStream, schema);
-                writer.WriteSchema(schema, cancellationToken);
-
-                memoryStream.Position = 0;
-                return ByteString.FromStream(memoryStream);
-            }
-        }
-    }
-}
-
-public static class SchemaExtension
-{
-    // Translate an Apache.Arrow.Schema to FlatBuffer Schema to ByteString
-    public static ByteString ToByteString(this Apache.Arrow.Schema schema)
-    {
-        return SchemaWriter.SerializeSchema(schema);
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Internal/StreamReader.cs b/csharp/src/Apache.Arrow.Flight/Internal/StreamReader.cs
deleted file mode 100644
index b07509d..0000000
--- a/csharp/src/Apache.Arrow.Flight/Internal/StreamReader.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Internal
-{
-
-    /// <summary>
-    /// This is a helper class that allows conversions from gRPC types to the Arrow types.
-    /// It maintains the stream so data can be read as soon as possible.
-    /// </summary>
-    /// <typeparam name="TIn">In parameter from gRPC</typeparam>
-    /// <typeparam name="TOut">The arrow type returned</typeparam>
-    internal class StreamReader<TIn, TOut> : IAsyncStreamReader<TOut>
-    {
-        private readonly IAsyncStreamReader<TIn> _inputStream;
-        private readonly Func<TIn, TOut> _convertFunction;
-        internal StreamReader(IAsyncStreamReader<TIn> inputStream, Func<TIn, TOut> convertFunction)
-        {
-            _inputStream = inputStream;
-            _convertFunction = convertFunction;
-        }
-
-        public TOut Current { get; private set; }
-
-        public async Task<bool> MoveNext(CancellationToken cancellationToken)
-        {
-            var moveNextResult = await _inputStream.MoveNext(cancellationToken).ConfigureAwait(false);
-            if (moveNextResult)
-            {
-                Current = _convertFunction(_inputStream.Current);
-            }
-            return moveNextResult;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Internal/StreamWriter.cs b/csharp/src/Apache.Arrow.Flight/Internal/StreamWriter.cs
deleted file mode 100644
index c50b41e..0000000
--- a/csharp/src/Apache.Arrow.Flight/Internal/StreamWriter.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Internal
-{
-    internal class StreamWriter<TIn, TOut> : IAsyncStreamWriter<TIn>
-    {
-        private readonly IAsyncStreamWriter<TOut> _inputStream;
-        private readonly Func<TIn, TOut> _convertFunction;
-        internal StreamWriter(IAsyncStreamWriter<TOut> inputStream, Func<TIn, TOut> convertFunction)
-        {
-            _inputStream = inputStream;
-            _convertFunction = convertFunction;
-        }
-
-        public WriteOptions WriteOptions
-        {
-            get
-            {
-                return _inputStream.WriteOptions;
-            }
-            set
-            {
-                _inputStream.WriteOptions = value;
-            }
-        }
-
-        public Task WriteAsync(TIn message)
-        {
-            return _inputStream.WriteAsync(_convertFunction(message));
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Properties/AssemblyInfo.cs b/csharp/src/Apache.Arrow.Flight/Properties/AssemblyInfo.cs
deleted file mode 100644
index 07934ad..0000000
--- a/csharp/src/Apache.Arrow.Flight/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Runtime.CompilerServices;
-
-[assembly: InternalsVisibleTo("Apache.Arrow.Flight.AspNetCore, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e504183f6d470d6b67b6d19212be3e1f598f70c246a120194bc38130101d0c1853e4a0f2232cb12e37a7a90e707aabd38511dac4f25fcb0d691b2aa265900bf42de7f70468fc997551a40e1e0679b605aa2088a4a69e07c117e988f5b1738c570ee66997fba02485e7856a49eca5fd0706d09899b8312577cbb9034599fc92d4")]
diff --git a/csharp/src/Apache.Arrow.Flight/Server/FlightServer.cs b/csharp/src/Apache.Arrow.Flight/Server/FlightServer.cs
deleted file mode 100644
index 12dc9cf..0000000
--- a/csharp/src/Apache.Arrow.Flight/Server/FlightServer.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Threading.Tasks;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Server
-{
-    public abstract class FlightServer
-    {
-        public virtual Task DoPut(FlightServerRecordBatchStreamReader requestStream, IAsyncStreamWriter<FlightPutResult> responseStream, ServerCallContext context)
-        {
-            throw new NotImplementedException();
-        }
-
-        public virtual Task DoGet(FlightTicket ticket, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context)
-        {
-            throw new NotImplementedException();
-        }
-
-        public virtual Task ListFlights(FlightCriteria request, IAsyncStreamWriter<FlightInfo> responseStream, ServerCallContext context)
-        {
-            throw new NotImplementedException();
-        }
-
-        public virtual Task ListActions(IAsyncStreamWriter<FlightActionType> responseStream, ServerCallContext context)
-        {
-            throw new NotImplementedException();
-        }
-
-        public virtual Task DoAction(FlightAction request, IAsyncStreamWriter<FlightResult> responseStream, ServerCallContext context)
-        {
-            throw new NotImplementedException();
-        }
-
-        public virtual Task<Schema> GetSchema(FlightDescriptor request, ServerCallContext context)
-        {
-            throw new NotImplementedException();
-        }
-
-        public virtual Task<FlightInfo> GetFlightInfo(FlightDescriptor request, ServerCallContext context)
-        {
-            throw new NotImplementedException();
-        }
-
-        public virtual Task Handshake(IAsyncStreamReader<FlightHandshakeRequest> requestStream, IAsyncStreamWriter<FlightHandshakeResponse> responseStream, ServerCallContext context)
-        {
-            throw new NotImplementedException();
-        }
-
-        public virtual Task DoExchange(FlightServerRecordBatchStreamReader requestStream, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context)
-        {
-            throw new NotImplementedException();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Server/FlightServerRecordBatchStreamReader.cs b/csharp/src/Apache.Arrow.Flight/Server/FlightServerRecordBatchStreamReader.cs
deleted file mode 100644
index c52b761..0000000
--- a/csharp/src/Apache.Arrow.Flight/Server/FlightServerRecordBatchStreamReader.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Internal;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Server
-{
-    public class FlightServerRecordBatchStreamReader : FlightRecordBatchStreamReader
-    {
-        public FlightServerRecordBatchStreamReader(IAsyncStreamReader<FlightData> flightDataStream) : base(new StreamReader<FlightData, Protocol.FlightData>(flightDataStream, data => data.ToProtocol()))
-        {
-        }
-
-        internal FlightServerRecordBatchStreamReader(IAsyncStreamReader<Protocol.FlightData> flightDataStream) : base(flightDataStream)
-        {
-        }
-
-        public ValueTask<FlightDescriptor> FlightDescriptor => GetFlightDescriptor();
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Server/FlightServerRecordBatchStreamWriter.cs b/csharp/src/Apache.Arrow.Flight/Server/FlightServerRecordBatchStreamWriter.cs
deleted file mode 100644
index 7d1c89e..0000000
--- a/csharp/src/Apache.Arrow.Flight/Server/FlightServerRecordBatchStreamWriter.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Flight.Internal;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Server
-{
-    public class FlightServerRecordBatchStreamWriter : FlightRecordBatchStreamWriter, IServerStreamWriter<RecordBatch>
-    {
-        public FlightServerRecordBatchStreamWriter(IServerStreamWriter<FlightData> clientStreamWriter) : base(new StreamWriter<Protocol.FlightData, FlightData>(clientStreamWriter, data => new FlightData(data)), null)
-        {
-        }
-
-        internal FlightServerRecordBatchStreamWriter(IServerStreamWriter<Protocol.FlightData> clientStreamWriter) : base(clientStreamWriter, null)
-        {
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Server/GrpcCoreFlightServerExtensions.cs b/csharp/src/Apache.Arrow.Flight/Server/GrpcCoreFlightServerExtensions.cs
deleted file mode 100644
index bb3076a..0000000
--- a/csharp/src/Apache.Arrow.Flight/Server/GrpcCoreFlightServerExtensions.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#if NET47_OR_GREATER
-
-using Apache.Arrow.Flight.Protocol;
-using Apache.Arrow.Flight.Server.Internal;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Server
-{
-    public static class GrpcCoreFlightServerExtensions
-    {
-        /// <summary>
-        /// Create a ServerServiceDefinition for use with a <see href="https://grpc.github.io/grpc/csharp/api/Grpc.Core.Server.html">Grpc.Core Server</see>
-        //  This allows running a flight server on pre-Kestrel .net Framework versions
-        /// </summary>
-        /// <param name="flightServer"></param>
-        /// <returns></returns>
-        public static ServerServiceDefinition CreateServiceDefinition(this FlightServer flightServer)
-        {
-            return FlightService.BindService(new FlightServerImplementation(flightServer));
-        }
-    }
-}
-
-#endif
diff --git a/csharp/src/Apache.Arrow.Flight/Server/Internal/FlightServerImplementation.cs b/csharp/src/Apache.Arrow.Flight/Server/Internal/FlightServerImplementation.cs
deleted file mode 100644
index e675cb1..0000000
--- a/csharp/src/Apache.Arrow.Flight/Server/Internal/FlightServerImplementation.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Internal;
-using Apache.Arrow.Flight.Protocol;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Server.Internal
-{
-    /// <summary>
-    /// This class has to be internal, since the generated code from proto is set as internal.
-    /// </summary>
-    internal class FlightServerImplementation : FlightService.FlightServiceBase
-    {
-        private readonly FlightServer _flightServer;
-        public FlightServerImplementation(FlightServer flightServer)
-        {
-            _flightServer = flightServer;
-        }
-
-        public override async Task DoPut(IAsyncStreamReader<Protocol.FlightData> requestStream, IServerStreamWriter<Protocol.PutResult> responseStream, ServerCallContext context)
-        {
-            var readStream = new FlightServerRecordBatchStreamReader(requestStream);
-            var writeStream = new StreamWriter<FlightPutResult, PutResult>(responseStream, putResult => putResult.ToProtocol());
-
-            await _flightServer.DoPut(readStream, writeStream, context).ConfigureAwait(false);
-        }
-
-        public override Task DoGet(Protocol.Ticket request, IServerStreamWriter<Protocol.FlightData> responseStream, ServerCallContext context)
-        {
-            var flightTicket = new FlightTicket(request.Ticket_);
-            var flightServerRecordBatchStreamWriter = new FlightServerRecordBatchStreamWriter(responseStream);
-
-            return _flightServer.DoGet(flightTicket, flightServerRecordBatchStreamWriter, context);
-        }
-
-        public override Task ListFlights(Protocol.Criteria request, IServerStreamWriter<Protocol.FlightInfo> responseStream, ServerCallContext context)
-        {
-            var writeStream = new StreamWriter<FlightInfo, Protocol.FlightInfo>(responseStream, flightInfo => flightInfo.ToProtocol());
-
-            return _flightServer.ListFlights(new FlightCriteria(request), writeStream, context);
-        }
-
-        public override Task DoAction(Protocol.Action request, IServerStreamWriter<Protocol.Result> responseStream, ServerCallContext context)
-        {
-            var action = new FlightAction(request);
-            var writeStream = new StreamWriter<FlightResult, Protocol.Result>(responseStream, result => result.ToProtocol());
-
-            return _flightServer.DoAction(action, writeStream, context);
-        }
-
-        public override async Task<SchemaResult> GetSchema(Protocol.FlightDescriptor request, ServerCallContext context)
-        {
-            var flightDescriptor = new FlightDescriptor(request);
-            var schema = await _flightServer.GetSchema(flightDescriptor, context).ConfigureAwait(false);
-
-            return new SchemaResult()
-            {
-                Schema = SchemaWriter.SerializeSchema(schema)
-            };
-        }
-
-        public override async Task<Protocol.FlightInfo> GetFlightInfo(Protocol.FlightDescriptor request, ServerCallContext context)
-        {
-            var flightDescriptor = new FlightDescriptor(request);
-            FlightInfo flightInfo = await _flightServer.GetFlightInfo(flightDescriptor, context).ConfigureAwait(false);
-
-            return flightInfo.ToProtocol();
-        }
-
-        public override Task DoExchange(IAsyncStreamReader<Protocol.FlightData> requestStream, IServerStreamWriter<Protocol.FlightData> responseStream, ServerCallContext context)
-        {
-            var readStream = new FlightServerRecordBatchStreamReader(requestStream);
-            var writeStream = new FlightServerRecordBatchStreamWriter(responseStream);
-            return _flightServer.DoExchange(readStream, writeStream, context);
-        }
-
-        public override Task Handshake(IAsyncStreamReader<HandshakeRequest> requestStream, IServerStreamWriter<HandshakeResponse> responseStream, ServerCallContext context)
-        {
-            var readStream = new StreamReader<HandshakeRequest, FlightHandshakeRequest>(requestStream, request => new FlightHandshakeRequest(request));
-            var writeStream = new StreamWriter<FlightHandshakeResponse, Protocol.HandshakeResponse>(responseStream, result => result.ToProtocol());
-            return _flightServer.Handshake(readStream, writeStream, context);
-        }
-
-        public override async Task ListActions(Empty request, IServerStreamWriter<Protocol.ActionType> responseStream, ServerCallContext context)
-        {
-            var writeStream = new StreamWriter<FlightActionType, Protocol.ActionType>(responseStream, (actionType) => actionType.ToProtocol());
-            await _flightServer.ListActions(writeStream, context).ConfigureAwait(false);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow.Flight/Server/Internal/HandshakeAdapters.cs b/csharp/src/Apache.Arrow.Flight/Server/Internal/HandshakeAdapters.cs
deleted file mode 100644
index 40ac3be..0000000
--- a/csharp/src/Apache.Arrow.Flight/Server/Internal/HandshakeAdapters.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Protocol;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Server.Internal;
-
-internal class FlightHandshakeStreamWriterAdapter : IClientStreamWriter<FlightHandshakeRequest>
-{
-    private readonly IClientStreamWriter<HandshakeRequest> _writeStream;
-
-    public FlightHandshakeStreamWriterAdapter(IClientStreamWriter<HandshakeRequest> writeStream)
-    {
-        _writeStream = writeStream;
-    }
-
-    public Task WriteAsync(FlightHandshakeRequest message) => _writeStream.WriteAsync(message.ToProtocol());
-
-    public WriteOptions WriteOptions
-    {
-        get => _writeStream.WriteOptions;
-        set => _writeStream.WriteOptions = value;
-    }
-
-    public Task CompleteAsync() => _writeStream.CompleteAsync();
-}
diff --git a/csharp/src/Apache.Arrow/Apache.Arrow.csproj b/csharp/src/Apache.Arrow/Apache.Arrow.csproj
deleted file mode 100644
index 301894f..0000000
--- a/csharp/src/Apache.Arrow/Apache.Arrow.csproj
+++ /dev/null
@@ -1,55 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <DefineConstants>$(DefineConstants);UNSAFE_BYTEBUFFER;BYTEBUFFER_NO_BOUNDS_CHECK;ENABLE_SPAN_T</DefineConstants>
-    
-    <Description>Apache Arrow is a cross-language development platform for in-memory data. It specifies a standardized language-independent columnar memory format for flat and hierarchical data, organized for efficient analytic operations on modern hardware.</Description>
-  </PropertyGroup>
-
-  <PropertyGroup>
-    <TargetFrameworks>netstandard2.0;net6.0;net8.0;net462</TargetFrameworks>
-  </PropertyGroup>
-
-  <ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETStandard' or '$(TargetFramework)' == 'net462'">
-    <PackageReference Include="System.Buffers" Version="4.6.0" />
-    <PackageReference Include="System.Memory" Version="4.6.0" />
-    <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.0" />
-    <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.6.0" />
-    <PackageReference Include="System.ValueTuple" Version="4.5.0" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <Compile Update="Properties\Resources.Designer.cs">
-      <DesignTime>True</DesignTime>
-      <AutoGen>True</AutoGen>
-      <DependentUpon>Resources.resx</DependentUpon>
-    </Compile>
-  </ItemGroup>
-
-  <ItemGroup>
-    <EmbeddedResource Update="Properties\Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-    </EmbeddedResource>
-  </ItemGroup>
-
-  <ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETStandard' or '$(TargetFramework)' == 'net462'">
-    <Compile Remove="Extensions\StreamExtensions.netcoreapp.cs" />
-  </ItemGroup>
-  <ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
-    <Compile Remove="Extensions\StreamExtensions.netstandard.cs" />
-    <Compile Remove="Extensions\TupleExtensions.netstandard.cs" />
-  </ItemGroup>
-  <ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible($(TargetFramework), 'net5.0'))">
-    <Compile Remove="Arrays\HalfFloatArray.cs" />
-  </ItemGroup>
-  <ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible($(TargetFramework), 'net5.0'))">
-    <!-- Code targeting .NET 5+ should use [UnmanagedCallersOnly]. -->
-    <Compile Remove="C\NativeDelegate.cs" />
-  </ItemGroup>
-</Project>
diff --git a/csharp/src/Apache.Arrow/Arrays/Array.cs b/csharp/src/Apache.Arrow/Arrays/Array.cs
deleted file mode 100644
index 4abe63e..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Array.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace Apache.Arrow
-{
-    public abstract class Array : IArrowArray
-    {
-        public ArrayData Data { get; }
-
-        protected Array(ArrayData data)
-        {
-            Data = data ?? throw new ArgumentNullException(nameof(data));
-        }
-
-        public int Length => Data.Length;
-
-        public int Offset => Data.Offset;
-
-        public int NullCount => Data.GetNullCount();
-
-        public ArrowBuffer NullBitmapBuffer => Data.Buffers[0];
-
-        public virtual void Accept(IArrowArrayVisitor visitor)
-        {
-            Accept(this, visitor);
-        }
-
-        public bool IsValid(int index) =>
-            NullCount == 0 || NullBitmapBuffer.IsEmpty || BitUtility.GetBit(NullBitmapBuffer.Span, index + Offset);
-
-        public bool IsNull(int index) => !IsValid(index);
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        internal static void Accept<T>(T array, IArrowArrayVisitor visitor)
-            where T : class, IArrowArray
-        {
-            switch (visitor)
-            {
-                case IArrowArrayVisitor<T> typedVisitor:
-                    typedVisitor.Visit(array);
-                    break;
-                default:
-                    visitor.Visit(array);
-                    break;
-            }
-        }
-
-        public Array Slice(int offset, int length)
-        {
-            return ArrowArrayFactory.Slice(this, offset, length) as Array;
-        }
-
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                Data.Dispose();
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/ArrayData.cs b/csharp/src/Apache.Arrow/Arrays/ArrayData.cs
deleted file mode 100644
index cdb6ed6..0000000
--- a/csharp/src/Apache.Arrow/Arrays/ArrayData.cs
+++ /dev/null
@@ -1,183 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Apache.Arrow
-{
-    public sealed class ArrayData : IDisposable
-    {
-        private const int RecalculateNullCount = -1;
-
-        public readonly IArrowType DataType;
-        public readonly int Length;
-
-        /// <summary>
-        /// The number of null values in the Array. May be -1 if the null count has not been computed.
-        /// </summary>
-        public int NullCount;
-
-        public readonly int Offset;
-        public readonly ArrowBuffer[] Buffers;
-        public readonly ArrayData[] Children;
-        public readonly ArrayData Dictionary; // Only used for dictionary type
-
-        /// <summary>
-        /// Get the number of null values in the Array, computing the count if required.
-        /// </summary>
-        public int GetNullCount()
-        {
-            if (NullCount == RecalculateNullCount)
-            {
-                NullCount = ComputeNullCount();
-            }
-
-            return NullCount;
-        }
-
-        // This is left for compatibility with lower version binaries
-        // before the dictionary type was supported.
-        public ArrayData(
-            IArrowType dataType,
-            int length, int nullCount, int offset,
-            IEnumerable<ArrowBuffer> buffers, IEnumerable<ArrayData> children) :
-            this(dataType, length, nullCount, offset, buffers, children, null)
-        { }
-
-        // This is left for compatibility with lower version binaries
-        // before the dictionary type was supported.
-        public ArrayData(
-            IArrowType dataType,
-            int length, int nullCount, int offset,
-            ArrowBuffer[] buffers, ArrayData[] children) :
-            this(dataType, length, nullCount, offset, buffers, children, null)
-        { }
-
-        public ArrayData(
-            IArrowType dataType,
-            int length, int nullCount = 0, int offset = 0,
-            IEnumerable<ArrowBuffer> buffers = null, IEnumerable<ArrayData> children = null, ArrayData dictionary = null)
-        {
-            DataType = dataType ?? NullType.Default;
-            Length = length;
-            NullCount = nullCount;
-            Offset = offset;
-            Buffers = buffers?.ToArray();
-            Children = children?.ToArray();
-            Dictionary = dictionary;
-        }
-
-        public ArrayData(
-            IArrowType dataType,
-            int length, int nullCount = 0, int offset = 0,
-            ArrowBuffer[] buffers = null, ArrayData[] children = null, ArrayData dictionary = null)
-        {
-            DataType = dataType ?? NullType.Default;
-            Length = length;
-            NullCount = nullCount;
-            Offset = offset;
-            Buffers = buffers;
-            Children = children;
-            Dictionary = dictionary;
-        }
-
-        public void Dispose()
-        {
-            if (Buffers != null)
-            {
-                foreach (ArrowBuffer buffer in Buffers)
-                {
-                    buffer.Dispose();
-                }
-            }
-
-            if (Children != null)
-            {
-                foreach (ArrayData child in Children)
-                {
-                    child?.Dispose();
-                }
-            }
-
-            Dictionary?.Dispose();
-        }
-
-        public ArrayData Slice(int offset, int length)
-        {
-            if (offset > Length)
-            {
-                throw new ArgumentException($"Offset {offset} cannot be greater than Length {Length} for Array.Slice");
-            }
-
-            length = Math.Min(Length - offset, length);
-            offset += Offset;
-
-            int nullCount;
-            if (NullCount == 0)
-            {
-                nullCount = 0;
-            }
-            else if (NullCount == Length)
-            {
-                nullCount = length;
-            }
-            else if (offset == Offset && length == Length)
-            {
-                nullCount = NullCount;
-            }
-            else
-            {
-                nullCount = RecalculateNullCount;
-            }
-
-            return new ArrayData(DataType, length, nullCount, offset, Buffers, Children, Dictionary);
-        }
-
-        public ArrayData Clone(MemoryAllocator allocator = default)
-        {
-            return new ArrayData(
-                DataType,
-                Length,
-                NullCount,
-                Offset,
-                Buffers?.Select(b => b.Clone(allocator))?.ToArray(),
-                Children?.Select(b => b.Clone(allocator))?.ToArray(),
-                Dictionary?.Clone(allocator));
-        }
-
-        private int ComputeNullCount()
-        {
-            if (DataType.TypeId == ArrowTypeId.Union)
-            {
-                return UnionArray.ComputeNullCount(this);
-            }
-
-            if (Buffers == null || Buffers.Length == 0 || Buffers[0].IsEmpty)
-            {
-                return 0;
-            }
-
-            // Note: Dictionary arrays may be logically null if there is a null in the dictionary values,
-            // but this isn't accounted for by the IArrowArray.IsNull implementation,
-            // so we maintain consistency with that behaviour here.
-
-            return Length - BitUtility.CountBits(Buffers[0].Span, Offset, Length);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/ArrayDataConcatenator.cs b/csharp/src/Apache.Arrow/Arrays/ArrayDataConcatenator.cs
deleted file mode 100644
index fe2543b..0000000
--- a/csharp/src/Apache.Arrow/Arrays/ArrayDataConcatenator.cs
+++ /dev/null
@@ -1,548 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using Apache.Arrow.Scalars;
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Arrow
-{
-    public class ArrayDataConcatenator
-    {
-        public static ArrayData Concatenate(IReadOnlyList<ArrayData> arrayDataList, MemoryAllocator allocator = default)
-        {
-            if (arrayDataList == null || arrayDataList.Count == 0)
-            {
-                return null;
-            }
-
-            if (arrayDataList.Count == 1)
-            {
-                return arrayDataList[0];
-            }
-
-            var arrowArrayConcatenationVisitor = new ArrayDataConcatenationVisitor(arrayDataList, allocator);
-
-            IArrowType type = arrayDataList[0].DataType;
-            type.Accept(arrowArrayConcatenationVisitor);
-
-            return arrowArrayConcatenationVisitor.Result;
-        }
-
-        private class ArrayDataConcatenationVisitor :
-            IArrowTypeVisitor<BooleanType>,
-            IArrowTypeVisitor<FixedWidthType>,
-            IArrowTypeVisitor<BinaryType>,
-            IArrowTypeVisitor<BinaryViewType>,
-            IArrowTypeVisitor<StringType>,
-            IArrowTypeVisitor<StringViewType>,
-            IArrowTypeVisitor<ListType>,
-            IArrowTypeVisitor<ListViewType>,
-            IArrowTypeVisitor<FixedSizeListType>,
-            IArrowTypeVisitor<StructType>,
-            IArrowTypeVisitor<UnionType>,
-            IArrowTypeVisitor<MapType>
-        {
-            public ArrayData Result { get; private set; }
-            private readonly IReadOnlyList<ArrayData> _arrayDataList;
-            private readonly int _totalLength;
-            private readonly int _totalNullCount;
-            private readonly MemoryAllocator _allocator;
-
-            public ArrayDataConcatenationVisitor(IReadOnlyList<ArrayData> arrayDataList, MemoryAllocator allocator = default)
-            {
-                _arrayDataList = arrayDataList;
-                _allocator = allocator;
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    _totalLength += arrayData.Length;
-                    _totalNullCount += arrayData.GetNullCount();
-                }
-            }
-
-            public void Visit(BooleanType type)
-            {
-                CheckData(type, 2);
-                ArrowBuffer validityBuffer = ConcatenateValidityBuffer();
-                ArrowBuffer valueBuffer = ConcatenateBitmapBuffer(1);
-
-                Result = new ArrayData(type, _totalLength, _totalNullCount, 0, new ArrowBuffer[] { validityBuffer, valueBuffer });
-            }
-
-            public void Visit(FixedWidthType type)
-            {
-                CheckData(type, 2);
-                ArrowBuffer validityBuffer = ConcatenateValidityBuffer();
-                ArrowBuffer valueBuffer = ConcatenateFixedWidthTypeValueBuffer(1, type);
-
-                Result = new ArrayData(type, _totalLength, _totalNullCount, 0, new ArrowBuffer[] { validityBuffer, valueBuffer });
-            }
-
-            public void Visit(BinaryType type) => ConcatenateVariableBinaryArrayData(type);
-
-            public void Visit(BinaryViewType type) => ConcatenateBinaryViewArrayData(type);
-
-            public void Visit(StringType type) => ConcatenateVariableBinaryArrayData(type);
-
-            public void Visit(StringViewType type) => ConcatenateBinaryViewArrayData(type);
-
-            public void Visit(ListType type) => ConcatenateLists(type);
-
-            public void Visit(ListViewType type)
-            {
-                CheckData(type, 3);
-                ArrowBuffer validityBuffer = ConcatenateValidityBuffer();
-                ArrowBuffer sizesBuffer = ConcatenateFixedWidthTypeValueBuffer(2, Int32Type.Default);
-
-                var children = new List<ArrayData>(_arrayDataList.Count);
-                var offsetsBuilder = new ArrowBuffer.Builder<int>(_totalLength);
-                int baseOffset = 0;
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    if (arrayData.Length == 0)
-                    {
-                        continue;
-                    }
-
-                    var child = arrayData.Children[0];
-                    ReadOnlySpan<int> offsets = arrayData.Buffers[1].Span.CastTo<int>().Slice(arrayData.Offset, arrayData.Length);
-                    ReadOnlySpan<int> sizes = arrayData.Buffers[2].Span.CastTo<int>().Slice(arrayData.Offset, arrayData.Length);
-                    var minOffset = offsets[0];
-                    var maxEnd = 0;
-
-                    for (int i = 0; i < arrayData.Length; ++i)
-                    {
-                        minOffset = Math.Min(minOffset, offsets[i]);
-                        maxEnd = Math.Max(maxEnd, offsets[i] + sizes[i]);
-                    }
-
-                    foreach (int offset in offsets)
-                    {
-                        offsetsBuilder.Append(baseOffset + offset - minOffset);
-                    }
-
-                    var childLength = maxEnd - minOffset;
-                    if (minOffset != 0 || childLength != child.Length)
-                    {
-                        child = child.Slice(minOffset, childLength);
-                    }
-
-                    baseOffset += childLength;
-                    children.Add(child);
-                }
-
-                ArrowBuffer offsetBuffer = offsetsBuilder.Build(_allocator);
-                ArrayData combinedChild = Concatenate(children, _allocator);
-
-                Result = new ArrayData(type, _totalLength, _totalNullCount, 0, new ArrowBuffer[] { validityBuffer, offsetBuffer, sizesBuffer }, new[] { combinedChild });
-            }
-
-            public void Visit(FixedSizeListType type)
-            {
-                CheckData(type, 1);
-                var listSize = type.ListSize;
-                ArrowBuffer validityBuffer = ConcatenateValidityBuffer();
-
-                var children = new List<ArrayData>(_arrayDataList.Count);
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    var offset = arrayData.Offset;
-                    var length = arrayData.Length;
-                    var child = arrayData.Children[0];
-                    if (offset != 0 || child.Length != length * listSize)
-                    {
-                        child = child.Slice(offset * listSize, length * listSize);
-                    }
-
-                    children.Add(child);
-                }
-
-                ArrayData combinedChild = Concatenate(children, _allocator);
-
-                Result = new ArrayData(type, _totalLength, _totalNullCount, 0, new ArrowBuffer[] { validityBuffer }, new[] { combinedChild });
-            }
-
-            public void Visit(StructType type)
-            {
-                CheckData(type, 1);
-                ArrowBuffer validityBuffer = ConcatenateValidityBuffer();
-                List<ArrayData> children = new List<ArrayData>(type.Fields.Count);
-
-                for (int i = 0; i < type.Fields.Count; i++)
-                {
-                    children.Add(Concatenate(SelectSlicedChildren(i), _allocator));
-                }
-
-                Result = new ArrayData(type, _totalLength, _totalNullCount, 0, new ArrowBuffer[] { validityBuffer }, children);
-            }
-
-            public void Visit(UnionType type)
-            {
-                int bufferCount = type.Mode switch
-                {
-                    UnionMode.Sparse => 1,
-                    UnionMode.Dense => 2,
-                    _ => throw new InvalidOperationException("TODO"),
-                };
-
-                CheckData(type, bufferCount);
-                List<ArrayData> children = new List<ArrayData>(type.Fields.Count);
-
-                for (int i = 0; i < type.Fields.Count; i++)
-                {
-                    // For dense mode, the offsets aren't adjusted so are into the non-sliced child arrays
-                    var fieldChildren = type.Mode == UnionMode.Sparse
-                        ? SelectSlicedChildren(i)
-                        : SelectChildren(i);
-                    children.Add(Concatenate(fieldChildren, _allocator));
-                }
-
-                ArrowBuffer[] buffers = new ArrowBuffer[bufferCount];
-                buffers[0] = ConcatenateUnionTypeBuffer();
-                if (bufferCount > 1)
-                {
-                    buffers[1] = ConcatenateUnionOffsetBuffer();
-                }
-
-                Result = new ArrayData(type, _totalLength, _totalNullCount, 0, buffers, children);
-            }
-
-            public void Visit(MapType type) => ConcatenateLists(type.UnsortedKey()); /* Can't tell if the output is still sorted */
-
-            public void Visit(IArrowType type)
-            {
-                throw new NotImplementedException($"Concatenation for {type.Name} is not supported yet.");
-            }
-
-            private void CheckData(IArrowType type, int expectedBufferCount)
-            {
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    arrayData.EnsureDataType(type.TypeId);
-                    arrayData.EnsureBufferCount(expectedBufferCount);
-                }
-            }
-
-            private void CheckDataVariadicCount(IArrowType type, int expectedBufferCount)
-            {
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    arrayData.EnsureDataType(type.TypeId);
-                    arrayData.EnsureVariadicBufferCount(expectedBufferCount);
-                }
-            }
-
-            private void ConcatenateVariableBinaryArrayData(IArrowType type)
-            {
-                CheckData(type, 3);
-                ArrowBuffer validityBuffer = ConcatenateValidityBuffer();
-                ArrowBuffer offsetBuffer = ConcatenateOffsetBuffer();
-                ArrowBuffer valueBuffer = ConcatenateVariableBinaryValueBuffer();
-
-                Result = new ArrayData(type, _totalLength, _totalNullCount, 0, new ArrowBuffer[] { validityBuffer, offsetBuffer, valueBuffer });
-            }
-
-            private void ConcatenateBinaryViewArrayData(IArrowType type)
-            {
-                CheckDataVariadicCount(type, 2);
-                ArrowBuffer validityBuffer = ConcatenateValidityBuffer();
-                ArrowBuffer viewBuffer = ConcatenateViewBuffer(out int variadicBufferCount);
-                ArrowBuffer[] buffers = new ArrowBuffer[2 + variadicBufferCount];
-                buffers[0] = validityBuffer;
-                buffers[1] = viewBuffer;
-                int index = 2;
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    for (int i = 2; i < arrayData.Buffers.Length; i++)
-                    {
-                        buffers[index++] = arrayData.Buffers[i];
-                    }
-                }
-
-                Result = new ArrayData(type, _totalLength, _totalNullCount, 0, buffers);
-            }
-
-            private void ConcatenateLists(NestedType type)
-            {
-                CheckData(type, 2);
-                ArrowBuffer validityBuffer = ConcatenateValidityBuffer();
-                ArrowBuffer offsetBuffer = ConcatenateOffsetBuffer();
-
-                var children = new List<ArrayData>(_arrayDataList.Count);
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    if (arrayData.Length == 0)
-                    {
-                        continue;
-                    }
-
-                    var child = arrayData.Children[0];
-                    ReadOnlySpan<int> offsets = arrayData.Buffers[1].Span.CastTo<int>().Slice(arrayData.Offset, arrayData.Length + 1);
-                    var firstOffset = offsets[0];
-                    var lastOffset = offsets[arrayData.Length];
-                    if (firstOffset != 0 || lastOffset != child.Length)
-                    {
-                        child = child.Slice(firstOffset, lastOffset - firstOffset);
-                    }
-
-                    children.Add(child);
-                }
-
-                ArrayData combinedChild = Concatenate(children, _allocator);
-
-                Result = new ArrayData(type, _totalLength, _totalNullCount, 0, new ArrowBuffer[] { validityBuffer, offsetBuffer }, new[] { combinedChild });
-            }
-
-            private ArrowBuffer ConcatenateValidityBuffer()
-            {
-                if (_totalNullCount == 0)
-                {
-                    return ArrowBuffer.Empty;
-                }
-
-                var builder = new ArrowBuffer.BitmapBuilder(_totalLength);
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    int length = arrayData.Length;
-                    int offset = arrayData.Offset;
-                    ReadOnlySpan<byte> span = arrayData.Buffers[0].Span;
-
-                    if (length > 0 && span.Length == 0)
-                    {
-                        if (arrayData.NullCount == 0)
-                        {
-                            builder.AppendRange(true , length);
-                        }
-                        else if (arrayData.NullCount == length)
-                        {
-                            builder.AppendRange(false , length);
-                        }
-                        else
-                        {
-                            throw new Exception("Array has no validity buffer and null count != 0 or length");
-                        }
-                    }
-                    else if (offset == 0)
-                    {
-                        builder.Append(span, length);
-                    }
-                    else
-                    {
-                        for (int i = 0; i < length; ++i)
-                        {
-                            builder.Append(BitUtility.GetBit(span, offset + i));
-                        }
-                    }
-                }
-
-                return builder.Build(_allocator);
-            }
-
-            private ArrowBuffer ConcatenateBitmapBuffer(int bufferIndex)
-            {
-                var builder = new ArrowBuffer.BitmapBuilder(_totalLength);
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    int length = arrayData.Length;
-                    int offset = arrayData.Offset;
-                    ReadOnlySpan<byte> span = arrayData.Buffers[bufferIndex].Span;
-
-                    if (offset == 0)
-                    {
-                        builder.Append(span, length);
-                    }
-                    else
-                    {
-                        for (int i = 0; i < length; ++i)
-                        {
-                            builder.Append(BitUtility.GetBit(span, offset + i));
-                        }
-                    }
-                }
-
-                return builder.Build(_allocator);
-            }
-
-            private ArrowBuffer ConcatenateFixedWidthTypeValueBuffer(int bufferIndex, FixedWidthType type)
-            {
-                int typeByteWidth = type.BitWidth / 8;
-                var builder = new ArrowBuffer.Builder<byte>(_totalLength * typeByteWidth);
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    int byteLength = arrayData.Length * typeByteWidth;
-                    int byteOffset = arrayData.Offset * typeByteWidth;
-
-                    builder.Append(arrayData.Buffers[bufferIndex].Span.Slice(byteOffset, byteLength));
-                }
-
-                return builder.Build(_allocator);
-            }
-
-            private ArrowBuffer ConcatenateVariableBinaryValueBuffer()
-            {
-                var builder = new ArrowBuffer.Builder<byte>();
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    var offsets = arrayData.Buffers[1].Span.CastTo<int>().Slice(arrayData.Offset, arrayData.Length + 1);
-                    var firstOffset = offsets[0];
-                    var lastOffset = offsets[arrayData.Length];
-                    builder.Append(arrayData.Buffers[2].Span.Slice(firstOffset, lastOffset - firstOffset));
-                }
-
-                return builder.Build(_allocator);
-            }
-
-            private ArrowBuffer ConcatenateOffsetBuffer()
-            {
-                var builder = new ArrowBuffer.Builder<int>(_totalLength + 1);
-                int baseOffset = 0;
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    if (arrayData.Length == 0)
-                    {
-                        continue;
-                    }
-
-                    ReadOnlySpan<int> span = arrayData.Buffers[1].Span.CastTo<int>().Slice(arrayData.Offset, arrayData.Length + 1);
-                    // First offset may be non-zero for sliced arrays
-                    var firstOffset = span[0];
-
-                    foreach (int offset in span.Slice(0, arrayData.Length))
-                    {
-                        builder.Append(baseOffset + offset - firstOffset);
-                    }
-
-                    baseOffset += span[arrayData.Length] - firstOffset;
-                }
-
-                builder.Append(baseOffset);
-
-                return builder.Build(_allocator);
-            }
-
-            private ArrowBuffer ConcatenateViewBuffer(out int variadicBufferCount)
-            {
-                var builder = new ArrowBuffer.Builder<BinaryView>(_totalLength);
-                variadicBufferCount = 0;
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    if (arrayData.Length == 0)
-                    {
-                        continue;
-                    }
-
-                    ReadOnlySpan<BinaryView> span = arrayData.Buffers[1].Span.CastTo<BinaryView>().Slice(arrayData.Offset, arrayData.Length);
-                    foreach (BinaryView view in span)
-                    {
-                        if (view.Length > BinaryView.MaxInlineLength)
-                        {
-                            builder.Append(view.AdjustBufferIndex(variadicBufferCount));
-                        }
-                        else
-                        {
-                            builder.Append(view);
-                        }
-                    }
-
-                    variadicBufferCount += (arrayData.Buffers.Length - 2);
-                }
-
-                return builder.Build(_allocator);
-            }
-
-            private ArrowBuffer ConcatenateUnionTypeBuffer()
-            {
-                var builder = new ArrowBuffer.Builder<byte>(_totalLength);
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    builder.Append(arrayData.Buffers[0].Span.Slice(arrayData.Offset, arrayData.Length));
-                }
-
-                return builder.Build(_allocator);
-            }
-
-            private ArrowBuffer ConcatenateUnionOffsetBuffer()
-            {
-                var builder = new ArrowBuffer.Builder<int>(_totalLength);
-                var typeCount = _arrayDataList.Count > 0 ? _arrayDataList[0].Children.Length : 0;
-                var baseOffsets = new int[typeCount];
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    ReadOnlySpan<byte> typeSpan = arrayData.Buffers[0].Span.Slice(arrayData.Offset, arrayData.Length);
-                    ReadOnlySpan<int> offsetSpan = arrayData.Buffers[1].Span.CastTo<int>().Slice(arrayData.Offset, arrayData.Length);
-                    for (int i = 0; i < arrayData.Length; ++i)
-                    {
-                        var typeId = typeSpan[i];
-                        builder.Append(checked(baseOffsets[typeId] + offsetSpan[i]));
-                    }
-
-                    for (int i = 0; i < typeCount; ++i)
-                    {
-                        checked
-                        {
-                            baseOffsets[i] += arrayData.Children[i].Length;
-                        }
-                    }
-                }
-
-                return builder.Build(_allocator);
-            }
-
-            private List<ArrayData> SelectChildren(int index)
-            {
-                var children = new List<ArrayData>(_arrayDataList.Count);
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    children.Add(arrayData.Children[index]);
-                }
-
-                return children;
-            }
-
-            private List<ArrayData> SelectSlicedChildren(int index)
-            {
-                var children = new List<ArrayData>(_arrayDataList.Count);
-
-                foreach (ArrayData arrayData in _arrayDataList)
-                {
-                    var offset = arrayData.Offset;
-                    var length = arrayData.Length;
-                    var child = arrayData.Children[index];
-                    if (offset != 0 || child.Length != length)
-                    {
-                        child = child.Slice(offset, length);
-                    }
-
-                    children.Add(child);
-                }
-
-                return children;
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/ArrayDataTypeComparer.cs b/csharp/src/Apache.Arrow/Arrays/ArrayDataTypeComparer.cs
deleted file mode 100644
index 2a5c386..0000000
--- a/csharp/src/Apache.Arrow/Arrays/ArrayDataTypeComparer.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    internal sealed class ArrayDataTypeComparer :
-        IArrowTypeVisitor<TimestampType>,
-        IArrowTypeVisitor<Date32Type>,
-        IArrowTypeVisitor<Date64Type>,
-        IArrowTypeVisitor<TimeBasedType>,
-        IArrowTypeVisitor<FixedSizeBinaryType>,
-        IArrowTypeVisitor<ListType>,
-        IArrowTypeVisitor<FixedSizeListType>,
-        IArrowTypeVisitor<StructType>,
-        IArrowTypeVisitor<UnionType>,
-        IArrowTypeVisitor<MapType>,
-        IArrowTypeVisitor<IntervalType>
-    {
-        private readonly IArrowType _expectedType;
-        private bool _dataTypeMatch;
-
-        public ArrayDataTypeComparer(IArrowType expectedType)
-        {
-            _expectedType = expectedType;
-        }
-
-        public bool DataTypeMatch => _dataTypeMatch;
-
-        public void Visit(TimestampType actualType)
-        {
-            if (_expectedType is TimestampType expectedType
-                && expectedType.Timezone == actualType.Timezone
-                && expectedType.Unit == actualType.Unit)
-            {
-                _dataTypeMatch = true;
-            }
-        }
-
-        public void Visit(Date32Type actualType)
-        {
-            if (_expectedType is Date32Type expectedType
-                && expectedType.Unit == actualType.Unit)
-            {
-                _dataTypeMatch = true;
-            }
-        }
-
-        public void Visit(Date64Type actualType)
-        {
-            if (_expectedType is Date64Type expectedType
-                && expectedType.Unit == actualType.Unit)
-            {
-                _dataTypeMatch = true;
-            }
-        }
-
-        public void Visit(TimeBasedType actualType)
-        {
-            if (_expectedType.TypeId == actualType.TypeId
-                && _expectedType is TimeBasedType expectedType
-                && expectedType.Unit == actualType.Unit)
-            {
-                _dataTypeMatch = true;
-            }
-        }
-
-        public void Visit(FixedSizeBinaryType actualType)
-        {
-            if (_expectedType is FixedSizeBinaryType expectedType
-                && expectedType.ByteWidth == actualType.ByteWidth)
-            {
-                _dataTypeMatch = true;
-            }
-        }
-
-        public void Visit(ListType actualType)
-        {
-            if (_expectedType is ListType expectedType
-                && CompareNested(expectedType, actualType))
-            {
-                _dataTypeMatch = true;
-            }
-        }
-
-        public void Visit(FixedSizeListType actualType)
-        {
-            if (_expectedType is FixedSizeListType expectedType
-                && actualType.ListSize == expectedType.ListSize
-                && CompareNested(expectedType, actualType))
-            {
-                _dataTypeMatch = true;
-            }
-        }
-
-        public void Visit(StructType actualType)
-        {
-            if (_expectedType is StructType expectedType
-                && CompareNested(expectedType, actualType))
-            {
-                _dataTypeMatch = true;
-            }
-        }
-
-        public void Visit(UnionType actualType)
-        {
-            if (_expectedType is UnionType expectedType
-                && CompareNested(expectedType, actualType))
-            {
-                _dataTypeMatch = true;
-            }
-        }
-
-        public void Visit(MapType actualType)
-        {
-            if (_expectedType is MapType expectedType
-                && expectedType.KeySorted == actualType.KeySorted
-                && CompareNested(expectedType, actualType))
-            {
-                _dataTypeMatch = true;
-            }
-        }
-
-        public void Visit(IntervalType actualType)
-        {
-            if (_expectedType is IntervalType expectedType
-                && expectedType.Unit == actualType.Unit)
-            {
-                _dataTypeMatch = true;
-            }
-        }
-
-        private static bool CompareNested(NestedType expectedType, NestedType actualType)
-        {
-            if (expectedType.Fields.Count != actualType.Fields.Count)
-            {
-                return false;
-            }
-
-            for (int i = 0; i < expectedType.Fields.Count; i++)
-            {
-                if (expectedType.Fields[i].DataType.TypeId != actualType.Fields[i].DataType.TypeId)
-                {
-                    return false;
-                }
-
-                var dataTypeMatch = FieldComparer.Compare(expectedType.Fields[i], actualType.Fields[i]);
-
-                if (!dataTypeMatch)
-                {
-                    return false;
-                }
-            }
-
-            return true;   
-        }
-
-        public void Visit(IArrowType actualType)
-        {
-            if (_expectedType.TypeId == actualType.TypeId)
-            {
-                _dataTypeMatch = true;
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/ArrowArrayBuilderFactory.cs b/csharp/src/Apache.Arrow/Arrays/ArrowArrayBuilderFactory.cs
deleted file mode 100644
index 3fb77d2..0000000
--- a/csharp/src/Apache.Arrow/Arrays/ArrowArrayBuilderFactory.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-
-namespace Apache.Arrow
-{
-    static class ArrowArrayBuilderFactory
-    {
-        internal static IArrowArrayBuilder<IArrowArray, IArrowArrayBuilder<IArrowArray>> Build(IArrowType dataType)
-        {
-            switch (dataType.TypeId)
-            {
-                case ArrowTypeId.Boolean:
-                    return new BooleanArray.Builder();
-                case ArrowTypeId.UInt8:
-                    return new UInt8Array.Builder();
-                case ArrowTypeId.Int8:
-                    return new Int8Array.Builder();
-                case ArrowTypeId.UInt16:
-                    return new UInt16Array.Builder();
-                case ArrowTypeId.Int16:
-                    return new Int16Array.Builder();
-                case ArrowTypeId.UInt32:
-                    return new UInt32Array.Builder();
-                case ArrowTypeId.Int32:
-                    return new Int32Array.Builder();
-                case ArrowTypeId.UInt64:
-                    return new UInt64Array.Builder();
-                case ArrowTypeId.Int64:
-                    return new Int64Array.Builder();
-                case ArrowTypeId.HalfFloat:
-#if NET5_0_OR_GREATER
-                    return new HalfFloatArray.Builder();
-#else
-                    throw new NotSupportedException("Half-float arrays are not supported by this target framework.");
-#endif
-                case ArrowTypeId.Float:
-                    return new FloatArray.Builder();
-                case ArrowTypeId.Double:
-                    return new DoubleArray.Builder();
-                case ArrowTypeId.String:
-                    return new StringArray.Builder();
-                case ArrowTypeId.StringView:
-                    return new StringViewArray.Builder();
-                case ArrowTypeId.Binary:
-                    return new BinaryArray.Builder();
-                case ArrowTypeId.BinaryView:
-                    return new BinaryViewArray.Builder();
-                case ArrowTypeId.Timestamp:
-                    return new TimestampArray.Builder();
-                case ArrowTypeId.Date64:
-                    return new Date64Array.Builder();
-                case ArrowTypeId.Date32:
-                    return new Date32Array.Builder();
-                case ArrowTypeId.Time32:
-                    return new Time32Array.Builder(dataType as Time32Type);
-                case ArrowTypeId.Time64:
-                    return new Time64Array.Builder(dataType as Time64Type);
-                case ArrowTypeId.Duration:
-                    return new DurationArray.Builder(dataType as DurationType);
-                case ArrowTypeId.List:
-                    return new ListArray.Builder(dataType as ListType);
-                case ArrowTypeId.ListView:
-                    return new ListViewArray.Builder(dataType as ListViewType);
-                case ArrowTypeId.FixedSizeList:
-                    return new FixedSizeListArray.Builder(dataType as FixedSizeListType);
-                case ArrowTypeId.Decimal32:
-                    return new Decimal32Array.Builder(dataType as Decimal32Type);
-                case ArrowTypeId.Decimal64:
-                    return new Decimal64Array.Builder(dataType as Decimal64Type);
-                case ArrowTypeId.Decimal128:
-                    return new Decimal128Array.Builder(dataType as Decimal128Type);
-                case ArrowTypeId.Decimal256:
-                    return new Decimal256Array.Builder(dataType as Decimal256Type);
-                case ArrowTypeId.Interval:
-                    var intervalType = (IntervalType)dataType;
-                    return intervalType.Unit switch
-                    {
-                        IntervalUnit.YearMonth => new YearMonthIntervalArray.Builder(),
-                        IntervalUnit.DayTime => new DayTimeIntervalArray.Builder(),
-                        IntervalUnit.MonthDayNanosecond => new MonthDayNanosecondIntervalArray.Builder(),
-                        _ => throw new ArgumentOutOfRangeException($"unsupported interval unit <{intervalType.Unit}>")
-                    };
-                case ArrowTypeId.Map:
-                    return new MapArray.Builder(dataType as MapType);
-                case ArrowTypeId.Struct:
-                case ArrowTypeId.Union:
-                case ArrowTypeId.Dictionary:
-                case ArrowTypeId.FixedSizedBinary:
-                default:
-                    throw new NotSupportedException($"An ArrowArrayBuilder cannot be built for type {dataType.TypeId}.");
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/ArrowArrayConcatenator.cs b/csharp/src/Apache.Arrow/Arrays/ArrowArrayConcatenator.cs
deleted file mode 100644
index ac82522..0000000
--- a/csharp/src/Apache.Arrow/Arrays/ArrowArrayConcatenator.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using System.Collections.Generic;
-
-namespace Apache.Arrow
-{
-    public static class ArrowArrayConcatenator
-    {
-        public static IArrowArray Concatenate(IReadOnlyList<IArrowArray> arrowArrayList , MemoryAllocator allocator = default)
-        {
-            if(arrowArrayList == null || arrowArrayList.Count == 0)
-            {
-                return null;
-            }
-
-            if (arrowArrayList.Count == 1)
-            {
-                return arrowArrayList[0];
-            }
-
-            var arrayDataList = new List<ArrayData>(arrowArrayList.Count);
-
-            foreach(IArrowArray array in arrowArrayList)
-            {
-                arrayDataList.Add(array.Data);
-            }
-
-            return ArrowArrayFactory.BuildArray(ArrayDataConcatenator.Concatenate(arrayDataList, allocator));
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/ArrowArrayFactory.cs b/csharp/src/Apache.Arrow/Arrays/ArrowArrayFactory.cs
deleted file mode 100644
index 38092a7..0000000
--- a/csharp/src/Apache.Arrow/Arrays/ArrowArrayFactory.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Arrays;
-using Apache.Arrow.Types;
-using System;
-
-namespace Apache.Arrow
-{
-    public static class ArrowArrayFactory
-    {
-        public static IArrowArray BuildArray(ArrayData data)
-        {
-            switch (data.DataType.TypeId)
-            {
-                case ArrowTypeId.Null:
-                    return new NullArray(data);
-                case ArrowTypeId.Boolean:
-                    return new BooleanArray(data);
-                case ArrowTypeId.UInt8:
-                    return new UInt8Array(data);
-                case ArrowTypeId.Int8:
-                    return new Int8Array(data);
-                case ArrowTypeId.UInt16:
-                    return new UInt16Array(data);
-                case ArrowTypeId.Int16:
-                    return new Int16Array(data);
-                case ArrowTypeId.UInt32:
-                    return new UInt32Array(data);
-                case ArrowTypeId.Int32:
-                    return new Int32Array(data);
-                case ArrowTypeId.UInt64:
-                    return new UInt64Array(data);
-                case ArrowTypeId.Int64:
-                    return new Int64Array(data);
-                case ArrowTypeId.Float:
-                    return new FloatArray(data);
-                case ArrowTypeId.Double:
-                    return new DoubleArray(data);
-                case ArrowTypeId.String:
-                    return new StringArray(data);
-                case ArrowTypeId.StringView:
-                    return new StringViewArray(data);
-                case ArrowTypeId.LargeString:
-                    return new LargeStringArray(data);
-                case ArrowTypeId.FixedSizedBinary:
-                    return new FixedSizeBinaryArray(data);
-                case ArrowTypeId.Binary:
-                    return new BinaryArray(data);
-                case ArrowTypeId.BinaryView:
-                    return new BinaryViewArray(data);
-                case ArrowTypeId.LargeBinary:
-                    return new LargeBinaryArray(data);
-                case ArrowTypeId.Timestamp:
-                    return new TimestampArray(data);
-                case ArrowTypeId.List:
-                    return new ListArray(data);
-                case ArrowTypeId.ListView:
-                    return new ListViewArray(data);
-                case ArrowTypeId.LargeList:
-                    return new LargeListArray(data);
-                case ArrowTypeId.Map:
-                    return new MapArray(data);
-                case ArrowTypeId.Struct:
-                    return new StructArray(data);
-                case ArrowTypeId.Union:
-                    return UnionArray.Create(data);
-                case ArrowTypeId.Date64:
-                    return new Date64Array(data);
-                case ArrowTypeId.Date32:
-                    return new Date32Array(data);
-                case ArrowTypeId.Time32:
-                    return new Time32Array(data);
-                case ArrowTypeId.Time64:
-                    return new Time64Array(data);
-                case ArrowTypeId.Duration:
-                    return new DurationArray(data);
-                case ArrowTypeId.Decimal32:
-                    return new Decimal32Array(data);
-                case ArrowTypeId.Decimal64:
-                    return new Decimal64Array(data);
-                case ArrowTypeId.Decimal128:
-                    return new Decimal128Array(data);
-                case ArrowTypeId.Decimal256:
-                    return new Decimal256Array(data);
-                case ArrowTypeId.Dictionary:
-                    return new DictionaryArray(data);
-                case ArrowTypeId.HalfFloat:
-#if NET5_0_OR_GREATER
-                    return new HalfFloatArray(data);
-#else
-                    throw new NotSupportedException("Half-float arrays are not supported by this target framework.");
-#endif
-                case ArrowTypeId.FixedSizeList:
-                    return new FixedSizeListArray(data);
-                case ArrowTypeId.Interval:
-                    return IntervalArray.Create(data);
-                default:
-                    throw new NotSupportedException($"An ArrowArray cannot be built for type {data.DataType.TypeId}.");
-            }
-        }
-
-        public static IArrowArray Slice(IArrowArray array, int offset, int length)
-        {
-            ArrayData newData = array.Data.Slice(offset, length);
-            return BuildArray(newData);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/ArrowArrayVisitor.cs b/csharp/src/Apache.Arrow/Arrays/ArrowArrayVisitor.cs
deleted file mode 100644
index fc56b66..0000000
--- a/csharp/src/Apache.Arrow/Arrays/ArrowArrayVisitor.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow
-{
-    public abstract class ArrowArrayVisitor : IArrowArrayVisitor
-    {
-        public virtual void Visit(IArrowArray array) { }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/BinaryArray.cs b/csharp/src/Apache.Arrow/Arrays/BinaryArray.cs
deleted file mode 100644
index bd5d931..0000000
--- a/csharp/src/Apache.Arrow/Arrays/BinaryArray.cs
+++ /dev/null
@@ -1,409 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using Apache.Arrow.Memory;
-using System.Collections;
-
-namespace Apache.Arrow
-{
-    public class BinaryArray : Array, IReadOnlyList<byte[]>, ICollection<byte[]>
-    {
-        public class Builder : BuilderBase<BinaryArray, Builder>
-        {
-            public Builder() : base(BinaryType.Default) { }
-            public Builder(IArrowType dataType) : base(dataType) { }
-
-            protected override BinaryArray Build(ArrayData data)
-            {
-                return new BinaryArray(data);
-            }
-        }
-
-        public BinaryArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Binary);
-            data.EnsureBufferCount(3);
-        }
-
-        public BinaryArray(ArrowTypeId typeId, ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(typeId);
-            data.EnsureBufferCount(3);
-        }
-
-        public abstract class BuilderBase<TArray, TBuilder> : IArrowArrayBuilder<byte, TArray, TBuilder>
-            where TArray : IArrowArray
-            where TBuilder : class, IArrowArrayBuilder<byte, TArray, TBuilder>
-        {
-            protected IArrowType DataType { get; }
-            protected TBuilder Instance => this as TBuilder;
-            protected ArrowBuffer.Builder<int> ValueOffsets { get; }
-            protected ArrowBuffer.Builder<byte> ValueBuffer { get; }
-            protected ArrowBuffer.BitmapBuilder ValidityBuffer { get; }
-            protected int Offset { get; set; }
-            protected int NullCount => this.ValidityBuffer.UnsetBitCount;
-
-            protected BuilderBase(IArrowType dataType)
-            {
-                DataType = dataType;
-                ValueOffsets = new ArrowBuffer.Builder<int>();
-                ValueBuffer = new ArrowBuffer.Builder<byte>();
-                ValidityBuffer = new ArrowBuffer.BitmapBuilder();
-
-                // From the docs:
-                //
-                // The offsets buffer contains length + 1 signed integers (either 32-bit or 64-bit, depending on the
-                // logical type), which encode the start position of each slot in the data buffer. The length of the
-                // value in each slot is computed using the difference between the offset at that slot’s index and the
-                // subsequent offset.
-                //
-                // In this builder, we choose to append the first offset (zero) upon construction, and each trailing
-                // offset is then added after each individual item has been appended.
-                ValueOffsets.Append(this.Offset);
-            }
-
-            protected abstract TArray Build(ArrayData data);
-
-            /// <summary>
-            /// Gets the length of the array built so far.
-            /// </summary>
-            public int Length => ValueOffsets.Length - 1;
-
-            /// <summary>
-            /// Build an Arrow array from the appended contents so far.
-            /// </summary>
-            /// <param name="allocator">Optional memory allocator.</param>
-            /// <returns>Returns an array of type <typeparamref name="TArray"/>.</returns>
-            public TArray Build(MemoryAllocator allocator = default)
-            {
-                var bufs = new[]
-                {
-                    NullCount > 0 ? ValidityBuffer.Build(allocator) : ArrowBuffer.Empty,
-                    ValueOffsets.Build(allocator),
-                    ValueBuffer.Build(allocator),
-                };
-                var data = new ArrayData(
-                    DataType,
-                    length: Length,
-                    NullCount,
-                    offset: 0,
-                    bufs);
-
-                return Build(data);
-            }
-
-            /// <summary>
-            /// Append a single null value to the array.
-            /// </summary>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder AppendNull()
-            {
-                // Do not add to the value buffer in the case of a null.
-                // Note that we do not need to increment the offset as a result.
-                ValidityBuffer.Append(false);
-                ValueOffsets.Append(Offset);
-                return Instance;
-            }
-
-            /// <summary>
-            /// Appends a value, consisting of a single byte, to the array.
-            /// </summary>
-            /// <param name="value">Byte value to append.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder Append(byte value)
-            {
-                ValueBuffer.Append(value);
-                ValidityBuffer.Append(true);
-                Offset++;
-                ValueOffsets.Append(Offset);
-                return Instance;
-            }
-
-            /// <summary>
-            /// Append a value, consisting of a span of bytes, to the array.
-            /// </summary>
-            /// <remarks>
-            /// Note that a single value is added, which consists of arbitrarily many bytes.  If multiple values are
-            /// to be added, use the <see cref="AppendRange"/> method.
-            /// </remarks>
-            /// <param name="span">Span of bytes to add.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder Append(ReadOnlySpan<byte> span)
-            {
-                ValueBuffer.Append(span);
-                ValidityBuffer.Append(true);
-                Offset += span.Length;
-                ValueOffsets.Append(Offset);
-                return Instance;
-            }
-
-            /// <summary>
-            /// Append a value, consisting of an enumerable collection of bytes, to the array.
-            /// </summary>
-            /// <remarks>
-            /// Note that this method appends a single value, which may consist of arbitrarily many bytes.  If multiple
-            /// values are to be added, use the <see cref="AppendRange(IEnumerable{byte})"/> method instead.
-            /// </remarks>
-            /// <param name="value">Enumerable collection of bytes to add.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder Append(IEnumerable<byte> value)
-            {
-                if (value == null)
-                {
-                    return AppendNull();
-                }
-
-                // Note: by looking at the length of the value buffer before and after, we avoid having to iterate
-                // through the enumerable multiple times to get both length and contents.
-                int priorLength = ValueBuffer.Length;
-                ValueBuffer.AppendRange(value);
-                int valueLength = ValueBuffer.Length - priorLength;
-                Offset += valueLength;
-                ValidityBuffer.Append(true);
-                ValueOffsets.Append(Offset);
-                return Instance;
-            }
-
-            /// <summary>
-            /// Append an enumerable collection of single-byte values to the array.
-            /// </summary>
-            /// <remarks>
-            /// Note that this method appends multiple values, each of which is a single byte.  If a single value is
-            /// to be added, use the <see cref="Append(IEnumerable{byte})"/> method instead.
-            /// </remarks>
-            /// <param name="values">Single-byte values to add.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder AppendRange(IEnumerable<byte> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (byte b in values)
-                {
-                    Append(b);
-                }
-
-                return Instance;
-            }
-
-            /// <summary>
-            /// Append an enumerable collection of values to the array.
-            /// </summary>
-            /// <param name="values">Values to add.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder AppendRange(IEnumerable<byte[]> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (byte[] arr in values)
-                {
-                    if (arr == null)
-                    {
-                        AppendNull();
-                    }
-                    else
-                    {
-                        Append((ReadOnlySpan<byte>)arr);
-                    }
-                }
-
-                return Instance;
-            }
-
-            public TBuilder Reserve(int capacity)
-            {
-                // TODO: [ARROW-9366] Reserve capacity in the value buffer in a more sensible way.
-                ValueOffsets.Reserve(capacity + 1);
-                ValueBuffer.Reserve(capacity);
-                ValidityBuffer.Reserve(capacity);
-                return Instance;
-            }
-
-            public TBuilder Resize(int length)
-            {
-                // TODO: [ARROW-9366] Resize the value buffer to a safe length based on offsets, not `length`.
-                ValueOffsets.Resize(length + 1);
-                ValueBuffer.Resize(length);
-                ValidityBuffer.Resize(length);
-                return Instance;
-            }
-
-            public TBuilder Swap(int i, int j)
-            {
-                // TODO: Implement
-                throw new NotImplementedException();
-            }
-
-            public TBuilder Set(int index, byte value)
-            {
-                // TODO: Implement
-                throw new NotImplementedException();
-            }
-
-            /// <summary>
-            /// Clear all contents appended so far.
-            /// </summary>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder Clear()
-            {
-                ValueOffsets.Clear();
-                ValueBuffer.Clear();
-                ValidityBuffer.Clear();
-
-                // Always write the first offset before anything has been written.
-                Offset = 0;
-                ValueOffsets.Append(Offset);
-                return Instance;
-            }
-        }
-
-        public BinaryArray(IArrowType dataType, int length,
-            ArrowBuffer valueOffsetsBuffer,
-            ArrowBuffer dataBuffer,
-            ArrowBuffer nullBitmapBuffer,
-            int nullCount = 0, int offset = 0)
-        : this(new ArrayData(dataType, length, nullCount, offset,
-            new[] { nullBitmapBuffer, valueOffsetsBuffer, dataBuffer }))
-        { }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public ArrowBuffer ValueOffsetsBuffer => Data.Buffers[1];
-
-        public ArrowBuffer ValueBuffer => Data.Buffers[2];
-
-        public ReadOnlySpan<int> ValueOffsets => ValueOffsetsBuffer.Span.CastTo<int>().Slice(Offset, Length + 1);
-
-        public ReadOnlySpan<byte> Values => ValueBuffer.Span.CastTo<byte>();
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        [Obsolete("This method has been deprecated. Please use ValueOffsets[index] instead.")]
-        public int GetValueOffset(int index)
-        {
-            if (index < 0 || index > Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-            return ValueOffsets[index];
-        }
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public int GetValueLength(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-            if (!IsValid(index))
-            {
-                return 0;
-            }
-
-            ReadOnlySpan<int> offsets = ValueOffsets;
-            return offsets[index + 1] - offsets[index];
-        }
-
-        /// <summary>
-        /// Get the collection of bytes, as a read-only span, at a given index in the array.
-        /// </summary>
-        /// <remarks>
-        /// Note that this method cannot reliably identify null values, which are indistinguishable from empty byte
-        /// collection values when seen in the context of this method's return type of <see cref="ReadOnlySpan{Byte}"/>.
-        /// Use the <see cref="Array.IsNull"/> method or the <see cref="GetBytes(int, out bool)"/> overload instead
-        /// to reliably determine null values.
-        /// </remarks>
-        /// <param name="index">Index at which to get bytes.</param>
-        /// <returns>Returns a <see cref="ReadOnlySpan{Byte}"/> object.</returns>
-        /// <exception cref="ArgumentOutOfRangeException">If the index is negative or beyond the length of the array.
-        /// </exception>
-        public ReadOnlySpan<byte> GetBytes(int index) => GetBytes(index, out _);
-
-        /// <summary>
-        /// Get the collection of bytes, as a read-only span, at a given index in the array.
-        /// </summary>
-        /// <param name="index">Index at which to get bytes.</param>
-        /// <param name="isNull">Set to <see langword="true"/> if the value at the given index is null.</param>
-        /// <returns>Returns a <see cref="ReadOnlySpan{Byte}"/> object.</returns>
-        /// <exception cref="ArgumentOutOfRangeException">If the index is negative or beyond the length of the array.
-        /// </exception>
-        public ReadOnlySpan<byte> GetBytes(int index, out bool isNull)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            isNull = IsNull(index);
-
-            if (isNull)
-            {
-                // Note that `return null;` is valid syntax, but would be misleading as `null` in the context of a span
-                // is actually returned as an empty span.
-                return ReadOnlySpan<byte>.Empty;
-            }
-
-            return ValueBuffer.Span.Slice(ValueOffsets[index], GetValueLength(index));
-        }
-
-        int IReadOnlyCollection<byte[]>.Count => Length;
-        byte[] IReadOnlyList<byte[]>.this[int index] => GetBytes(index).ToArray();
-
-        IEnumerator<byte[]> IEnumerable<byte[]>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetBytes(index).ToArray();
-            }
-        }
-
-        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<byte[]>)this).GetEnumerator();
-
-        int ICollection<byte[]>.Count => Length;
-        bool ICollection<byte[]>.IsReadOnly => true;
-        void ICollection<byte[]>.Add(byte[] item) => throw new NotSupportedException("Collection is read-only.");
-        bool ICollection<byte[]>.Remove(byte[] item) => throw new NotSupportedException("Collection is read-only.");
-        void ICollection<byte[]>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-        bool ICollection<byte[]>.Contains(byte[] item)
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                if (GetBytes(index).SequenceEqual(item))
-                    return true;
-            }
-
-            return false;
-        }
-
-        void ICollection<byte[]>.CopyTo(byte[][] array, int arrayIndex)
-        {
-            for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-            {
-                array[destIndex] = GetBytes(srcIndex).ToArray();
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/BinaryViewArray.cs b/csharp/src/Apache.Arrow/Arrays/BinaryViewArray.cs
deleted file mode 100644
index b7c9b07..0000000
--- a/csharp/src/Apache.Arrow/Arrays/BinaryViewArray.cs
+++ /dev/null
@@ -1,344 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using Apache.Arrow.Scalars;
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using System.Collections;
-
-namespace Apache.Arrow
-{
-    public class BinaryViewArray : Array, IReadOnlyList<byte[]>
-    {
-        public class Builder : BuilderBase<BinaryViewArray, Builder>
-        {
-            public Builder() : base(BinaryViewType.Default) { }
-            public Builder(IArrowType dataType) : base(dataType) { }
-
-            protected override BinaryViewArray Build(ArrayData data)
-            {
-                return new BinaryViewArray(data);
-            }
-        }
-
-        public BinaryViewArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.BinaryView);
-            data.EnsureVariadicBufferCount(2);
-        }
-
-        public BinaryViewArray(ArrowTypeId typeId, ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(typeId);
-            data.EnsureVariadicBufferCount(2);
-        }
-
-        public abstract class BuilderBase<TArray, TBuilder> : IArrowArrayBuilder<byte, TArray, TBuilder>
-            where TArray : IArrowArray
-            where TBuilder : class, IArrowArrayBuilder<byte, TArray, TBuilder>
-        {
-            protected IArrowType DataType { get; }
-            protected TBuilder Instance => this as TBuilder;
-            protected ArrowBuffer.Builder<BinaryView> BinaryViews { get; }
-            protected ArrowBuffer.Builder<byte> ValueBuffer { get; }
-            protected ArrowBuffer.BitmapBuilder ValidityBuffer { get; }
-            protected int NullCount => this.ValidityBuffer.UnsetBitCount;
-
-            protected BuilderBase(IArrowType dataType)
-            {
-                DataType = dataType;
-                BinaryViews = new ArrowBuffer.Builder<BinaryView>();
-                ValueBuffer = new ArrowBuffer.Builder<byte>();
-                ValidityBuffer = new ArrowBuffer.BitmapBuilder();
-            }
-
-            protected abstract TArray Build(ArrayData data);
-
-            /// <summary>
-            /// Gets the length of the array built so far.
-            /// </summary>
-            public int Length => BinaryViews.Length;
-
-            /// <summary>
-            /// Build an Arrow array from the appended contents so far.
-            /// </summary>
-            /// <param name="allocator">Optional memory allocator.</param>
-            /// <returns>Returns an array of type <typeparamref name="TArray"/>.</returns>
-            public TArray Build(MemoryAllocator allocator = default)
-            {
-                bool hasValues = ValueBuffer.Length > 0;
-                var bufs = new ArrowBuffer[hasValues ? 3 : 2];
-                bufs[0] = NullCount > 0 ? ValidityBuffer.Build(allocator) : ArrowBuffer.Empty;
-                bufs[1] = BinaryViews.Build(allocator);
-                if (hasValues) { bufs[2] = ValueBuffer.Build(allocator); }
-
-                var data = new ArrayData(
-                    DataType,
-                    length: Length,
-                    NullCount,
-                    offset: 0,
-                    bufs);
-
-                return Build(data);
-            }
-
-            /// <summary>
-            /// Append a single null value to the array.
-            /// </summary>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder AppendNull()
-            {
-                // Do not add to the value buffer in the case of a null.
-                // Note that we do not need to increment the offset as a result.
-                ValidityBuffer.Append(false);
-                BinaryViews.Append(default(BinaryView));
-                return Instance;
-            }
-
-            /// <summary>
-            /// Appends a value, consisting of a single byte, to the array.
-            /// </summary>
-            /// <param name="value">Byte value to append.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder Append(byte value)
-            {
-                ValidityBuffer.Append(true);
-                Span<byte> buf = stackalloc[] { value };
-                BinaryViews.Append(new BinaryView(buf));
-                return Instance;
-            }
-
-            /// <summary>
-            /// Append a value, consisting of a span of bytes, to the array.
-            /// </summary>
-            /// <remarks>
-            /// Note that a single value is added, which consists of arbitrarily many bytes.  If multiple values are
-            /// to be added, use the <see cref="AppendRange"/> method.
-            /// </remarks>
-            /// <param name="span">Span of bytes to add.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder Append(ReadOnlySpan<byte> span)
-            {
-                if (span.Length > BinaryView.MaxInlineLength)
-                {
-                    int offset = ValueBuffer.Length;
-                    ValueBuffer.Append(span);
-                    BinaryViews.Append(new BinaryView(span.Length, span.Slice(0, 4), 0, offset));
-                }
-                else
-                {
-                    BinaryViews.Append(new BinaryView(span));
-                }
-                ValidityBuffer.Append(true);
-                return Instance;
-            }
-
-            /// <summary>
-            /// Append an enumerable collection of single-byte values to the array.
-            /// </summary>
-            /// <remarks>
-            /// Note that this method appends multiple values, each of which is a single byte
-            /// </remarks>
-            /// <param name="values">Single-byte values to add.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder AppendRange(IEnumerable<byte> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (byte b in values)
-                {
-                    Append(b);
-                }
-
-                return Instance;
-            }
-
-            /// <summary>
-            /// Append an enumerable collection of values to the array.
-            /// </summary>
-            /// <param name="values">Values to add.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder AppendRange(IEnumerable<byte[]> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (byte[] arr in values)
-                {
-                    if (arr == null)
-                    {
-                        AppendNull();
-                    }
-                    else
-                    {
-                        Append((ReadOnlySpan<byte>)arr);
-                    }
-                }
-
-                return Instance;
-            }
-
-            public TBuilder Reserve(int capacity)
-            {
-                // TODO: [ARROW-9366] Reserve capacity in the value buffer in a more sensible way.
-                BinaryViews.Reserve(capacity);
-                ValueBuffer.Reserve(capacity);
-                ValidityBuffer.Reserve(capacity);
-                return Instance;
-            }
-
-            public TBuilder Resize(int length)
-            {
-                // TODO: [ARROW-9366] Resize the value buffer to a safe length based on offsets, not `length`.
-                BinaryViews.Resize(length);
-                ValueBuffer.Resize(length);
-                ValidityBuffer.Resize(length);
-                return Instance;
-            }
-
-            public TBuilder Swap(int i, int j)
-            {
-                ValidityBuffer.Swap(i, j);
-                BinaryView view = BinaryViews.Span[i];
-                BinaryViews.Span[i] = BinaryViews.Span[j];
-                BinaryViews.Span[j] = view;
-                return Instance;
-            }
-
-            public TBuilder Set(int index, byte value)
-            {
-                // TODO: Implement
-                throw new NotImplementedException();
-            }
-
-            /// <summary>
-            /// Clear all contents appended so far.
-            /// </summary>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public TBuilder Clear()
-            {
-                BinaryViews.Clear();
-                ValueBuffer.Clear();
-                ValidityBuffer.Clear();
-                return Instance;
-            }
-        }
-
-        public BinaryViewArray(IArrowType dataType, int length,
-            ArrowBuffer binaryViewsBuffer,
-            ArrowBuffer dataBuffer,
-            ArrowBuffer nullBitmapBuffer,
-            int nullCount = 0, int offset = 0)
-        : this(new ArrayData(dataType, length, nullCount, offset,
-            new[] { nullBitmapBuffer, binaryViewsBuffer, dataBuffer }))
-        { }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public ArrowBuffer ViewsBuffer => Data.Buffers[1];
-
-        public int DataBufferCount => Data.Buffers.Length - 2;
-
-        public ArrowBuffer DataBuffer(int index) => Data.Buffers[index + 2];
-
-        public ReadOnlySpan<BinaryView> Views => ViewsBuffer.Span.CastTo<BinaryView>().Slice(Offset, Length);
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public int GetValueLength(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-            if (!IsValid(index))
-            {
-                return 0;
-            }
-
-            return Views[index].Length;
-        }
-
-        /// <summary>
-        /// Get the collection of bytes, as a read-only span, at a given index in the array.
-        /// </summary>
-        /// <remarks>
-        /// Note that this method cannot reliably identify null values, which are indistinguishable from empty byte
-        /// collection values when seen in the context of this method's return type of <see cref="ReadOnlySpan{Byte}"/>.
-        /// Use the <see cref="Array.IsNull"/> method or the <see cref="GetBytes(int, out bool)"/> overload instead
-        /// to reliably determine null values.
-        /// </remarks>
-        /// <param name="index">Index at which to get bytes.</param>
-        /// <returns>Returns a <see cref="ReadOnlySpan{Byte}"/> object.</returns>
-        /// <exception cref="ArgumentOutOfRangeException">If the index is negative or beyond the length of the array.
-        /// </exception>
-        public ReadOnlySpan<byte> GetBytes(int index) => GetBytes(index, out _);
-
-        /// <summary>
-        /// Get the collection of bytes, as a read-only span, at a given index in the array.
-        /// </summary>
-        /// <param name="index">Index at which to get bytes.</param>
-        /// <param name="isNull">Set to <see langword="true"/> if the value at the given index is null.</param>
-        /// <returns>Returns a <see cref="ReadOnlySpan{Byte}"/> object.</returns>
-        /// <exception cref="ArgumentOutOfRangeException">If the index is negative or beyond the length of the array.
-        /// </exception>
-        public ReadOnlySpan<byte> GetBytes(int index, out bool isNull)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            isNull = IsNull(index);
-
-            if (isNull)
-            {
-                // Note that `return null;` is valid syntax, but would be misleading as `null` in the context of a span
-                // is actually returned as an empty span.
-                return ReadOnlySpan<byte>.Empty;
-            }
-
-            BinaryView binaryView = Views[index];
-            if (binaryView.IsInline)
-            {
-                return ViewsBuffer.Span.Slice(16 * (Offset + index) + 4, binaryView.Length);
-            }
-
-            return DataBuffer(binaryView._bufferIndex).Span.Slice(binaryView._bufferOffset, binaryView.Length);
-        }
-
-        int IReadOnlyCollection<byte[]>.Count => Length;
-        byte[] IReadOnlyList<byte[]>.this[int index] => GetBytes(index).ToArray();
-
-        IEnumerator<byte[]> IEnumerable<byte[]>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetBytes(index).ToArray();
-            }
-        }
-
-        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<byte[]>)this).GetEnumerator();
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/BooleanArray.cs b/csharp/src/Apache.Arrow/Arrays/BooleanArray.cs
deleted file mode 100644
index 19d4d0b..0000000
--- a/csharp/src/Apache.Arrow/Arrays/BooleanArray.cs
+++ /dev/null
@@ -1,234 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace Apache.Arrow
-{
-    public class BooleanArray: Array, IReadOnlyList<bool?>, ICollection<bool?>
-    {
-        public class Builder : IArrowArrayBuilder<bool, BooleanArray, Builder>
-        {
-            private ArrowBuffer.BitmapBuilder ValueBuffer { get; }
-            private ArrowBuffer.BitmapBuilder ValidityBuffer { get; }
-
-            public int Length => ValueBuffer.Length;
-            public int Capacity => ValueBuffer.Capacity;
-            public int NullCount => ValidityBuffer.UnsetBitCount;
-
-            public Builder()
-            {
-                ValueBuffer = new ArrowBuffer.BitmapBuilder();
-                ValidityBuffer = new ArrowBuffer.BitmapBuilder();
-            }
-
-            public Builder Append(bool value)
-            {
-                return NullableAppend(value);
-            }
-
-            public Builder NullableAppend(bool? value)
-            {
-                // Note that we rely on the fact that null values are false in the value buffer.
-                ValueBuffer.Append(value ?? false);
-                ValidityBuffer.Append(value.HasValue);
-                return this;
-            }
-
-            public Builder Append(ReadOnlySpan<bool> span)
-            {
-                foreach (bool value in span)
-                {
-                    Append(value);
-                }
-                return this;
-            }
-
-            public Builder AppendRange(IEnumerable<bool> values)
-            {
-                foreach (bool value in values)
-                {
-                    Append(value);
-                }
-                return this;
-            }
-
-            public Builder AppendNull()
-            {
-                return NullableAppend(null);
-            }
-
-            public BooleanArray Build(MemoryAllocator allocator = default)
-            {
-                ArrowBuffer validityBuffer = NullCount > 0
-                                        ? ValidityBuffer.Build(allocator)
-                                        : ArrowBuffer.Empty;
-
-                return new BooleanArray(
-                    ValueBuffer.Build(allocator), validityBuffer,
-                    Length, NullCount, 0);
-            }
-
-            public Builder Clear()
-            {
-                ValueBuffer.Clear();
-                ValidityBuffer.Clear();
-                return this;
-            }
-
-            public Builder Reserve(int capacity)
-            {
-                if (capacity < 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(capacity));
-                }
-
-                ValueBuffer.Reserve(capacity);
-                ValidityBuffer.Reserve(capacity);
-                return this;
-            }
-
-            public Builder Resize(int length)
-            {
-                if (length < 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(length));
-                }
-
-                ValueBuffer.Resize(length);
-                ValidityBuffer.Resize(length);
-                return this;
-            }
-
-            public Builder Toggle(int index)
-            {
-                CheckIndex(index);
-
-                // If there is a null at this index, assume it was set to false in the value buffer, and so becomes
-                // true/non-null after toggling.
-                ValueBuffer.Toggle(index);
-                ValidityBuffer.Set(index);
-                return this;
-            }
-
-            public Builder Set(int index)
-            {
-                CheckIndex(index);
-                ValueBuffer.Set(index);
-                ValidityBuffer.Set(index);
-                return this;
-            }
-
-            public Builder Set(int index, bool value)
-            {
-                CheckIndex(index);
-                ValueBuffer.Set(index, value);
-                ValidityBuffer.Set(index);
-                return this;
-            }
-
-            public Builder Swap(int i, int j)
-            {
-                CheckIndex(i);
-                CheckIndex(j);
-                ValueBuffer.Swap(i, j);
-                ValidityBuffer.Swap(i, j);
-                return this;
-            }
-
-            private void CheckIndex(int index)
-            {
-                if (index < 0 || index >= Length)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(index));
-                }
-            }
-        }
-
-        public ArrowBuffer ValueBuffer => Data.Buffers[1];
-        public ReadOnlySpan<byte> Values => ValueBuffer.Span.Slice(0, (int) Math.Ceiling(Length / 8.0));
-
-        public BooleanArray(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(BooleanType.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public BooleanArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Boolean);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        [Obsolete("GetBoolean does not support null values. Use GetValue instead (which this method invokes internally).")]
-        public bool GetBoolean(int index)
-        {
-            return GetValue(index).GetValueOrDefault();
-        }
-
-        public bool? GetValue(int index)
-        {
-            return IsNull(index)
-                ? null
-                : BitUtility.GetBit(ValueBuffer.Span, index + Offset);
-        }
-
-        int IReadOnlyCollection<bool?>.Count => Length;
-
-        bool? IReadOnlyList<bool?>.this[int index] => GetValue(index);
-
-        IEnumerator<bool?> IEnumerable<bool?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetValue(index);
-            }
-        }
-
-        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<bool?>)this).GetEnumerator();
-
-        int ICollection<bool?>.Count => Length;
-        bool ICollection<bool?>.IsReadOnly => true;
-        void ICollection<bool?>.Add(bool? item) => throw new NotSupportedException("Collection is read-only.");
-        bool ICollection<bool?>.Remove(bool? item) => throw new NotSupportedException("Collection is read-only.");
-        void ICollection<bool?>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-        bool ICollection<bool?>.Contains(bool? item)
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                if (GetValue(index).Equals(item))
-                    return true;
-            }
-
-            return false;
-        }
-
-        void ICollection<bool?>.CopyTo(bool?[] array, int arrayIndex)
-        {
-            for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-            {
-                array[destIndex] = GetValue(srcIndex);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Date32Array.cs b/csharp/src/Apache.Arrow/Arrays/Date32Array.cs
deleted file mode 100644
index 55864e8..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Date32Array.cs
+++ /dev/null
@@ -1,215 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Arrow
-{
-    /// <summary>
-    /// The <see cref="Date32Array"/> class holds an array of dates in the <c>Date32</c> format, where each date is
-    /// stored as the number of days since the dawn of (UNIX) time.
-    /// </summary>
-    public class Date32Array : PrimitiveArray<int>, IReadOnlyList<DateTime?>, ICollection<DateTime?>
-#if NET6_0_OR_GREATER
-        , IReadOnlyList<DateOnly?>, ICollection<DateOnly?>
-#endif
-    {
-        private static readonly DateTime _epochDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Unspecified);
-#if NET6_0_OR_GREATER
-        private static readonly int _epochDayNumber = new DateOnly(1970, 1, 1).DayNumber;
-#endif
-
-        /// <summary>
-        /// The <see cref="Builder"/> class can be used to fluently build <see cref="Date32Array"/> objects.
-        /// </summary>
-        public class Builder : DateArrayBuilder<int, Date32Array, Builder>
-        {
-            private class DateBuilder : PrimitiveArrayBuilder<int, Date32Array, DateBuilder>
-            {
-                protected override Date32Array Build(ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer, int length,
-                    int nullCount, int offset) =>
-                    new(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-            }
-
-            /// <summary>
-            /// Construct a new instance of the <see cref="Builder"/> class.
-            /// </summary>
-            public Builder() : base(new DateBuilder()) { }
-
-            protected override int Convert(DateTime dateTime)
-            {
-                return (int)(dateTime.Date - _epochDate).TotalDays;
-            }
-
-            protected override int Convert(DateTimeOffset dateTimeOffset)
-            {
-                // The internal value stored for a DateTimeOffset can be thought of as the number of 24-hour "blocks"
-                // of time that have elapsed since the UNIX epoch.  This is the same as converting it to UTC first and
-                // then taking the date element from that.  It is not the same as what would result from looking at the
-                // DateTimeOffset.Date property.
-                return (int)(dateTimeOffset.UtcDateTime.Date - _epochDate).TotalDays;
-            }
-
-#if NET6_0_OR_GREATER
-            protected override int Convert(DateOnly date)
-            {
-                return (int)(date.DayNumber - _epochDayNumber);
-            }
-#endif
-        }
-
-        public Date32Array(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(Date32Type.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public Date32Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Date32);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        [Obsolete("Use `GetDateTimeOffset()` instead")]
-        public DateTimeOffset? GetDate(int index) => GetDateTimeOffset(index);
-
-        /// <summary>
-        /// Get the date at the specified index in the form of a <see cref="DateTime"/> object.
-        /// </summary>
-        /// <remarks>
-        /// The <see cref="DateTime.Kind"/> property of the returned object is set to
-        /// <see cref="DateTimeKind.Unspecified"/>.
-        /// </remarks>
-        /// <param name="index">Index at which to get the date.</param>
-        /// <returns>Returns a <see cref="DateTime"/> object, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public DateTime? GetDateTime(int index)
-        {
-            int? value = GetValue(index);
-            return value.HasValue
-                ? _epochDate.AddDays(value.Value)
-                : default(DateTime?);
-        }
-
-        /// <summary>
-        /// Get the date at the specified index in the form of a <see cref="DateTimeOffset"/> object.
-        /// </summary>
-        /// <param name="index">Index at which to get the date.</param>
-        /// <returns>Returns a <see cref="DateTimeOffset"/> object, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public DateTimeOffset? GetDateTimeOffset(int index)
-        {
-            int? value = GetValue(index);
-            return value.HasValue
-                ? new DateTimeOffset(_epochDate.AddDays(value.Value), TimeSpan.Zero)
-                : default(DateTimeOffset?);
-        }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Get the date at the specified index
-        /// </summary>
-        /// <param name="index">Index at which to get the date.</param>
-        /// <returns>Returns a <see cref="DateOnly" />, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public DateOnly? GetDateOnly(int index)
-        {
-            int? value = GetValue(index);
-            return value.HasValue
-                ? DateOnly.FromDayNumber(_epochDayNumber + value.Value)
-                : default(DateOnly?);
-        }
-
-        int IReadOnlyCollection<DateOnly?>.Count => Length;
-
-        DateOnly? IReadOnlyList<DateOnly?>.this[int index] => GetDateOnly(index);
-
-        IEnumerator<DateOnly?> IEnumerable<DateOnly?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetDateOnly(index);
-            };
-        }
-
-        int ICollection<DateOnly?>.Count => Length;
-        bool ICollection<DateOnly?>.IsReadOnly => true;
-        void ICollection<DateOnly?>.Add(DateOnly? item) => throw new NotSupportedException("Collection is read-only.");
-        bool ICollection<DateOnly?>.Remove(DateOnly? item) => throw new NotSupportedException("Collection is read-only.");
-        void ICollection<DateOnly?>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-        bool ICollection<DateOnly?>.Contains(DateOnly? item)
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                if (GetDateOnly(index).Equals(item))
-                    return true;
-            }
-
-            return false;
-        }
-
-        void ICollection<DateOnly?>.CopyTo(DateOnly?[] array, int arrayIndex)
-        {
-            for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-            {
-                array[destIndex] = GetDateOnly(srcIndex);
-            }
-        }
-#endif
-
-        int IReadOnlyCollection<DateTime?>.Count => Length;
-
-        DateTime? IReadOnlyList<DateTime?>.this[int index] => GetDateTime(index);
-
-        IEnumerator<DateTime?> IEnumerable<DateTime?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetDateTime(index);
-            }
-        }
-
-        int ICollection<DateTime?>.Count => Length;
-        bool ICollection<DateTime?>.IsReadOnly => true;
-        void ICollection<DateTime?>.Add(DateTime? item) => throw new NotSupportedException("Collection is read-only.");
-        bool ICollection<DateTime?>.Remove(DateTime? item) => throw new NotSupportedException("Collection is read-only.");
-        void ICollection<DateTime?>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-        bool ICollection<DateTime?>.Contains(DateTime? item)
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                if (GetDateTime(index).Equals(item))
-                    return true;
-            }
-
-            return false;
-        }
-
-        void ICollection<DateTime?>.CopyTo(DateTime?[] array, int arrayIndex)
-        {
-            for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-            {
-                array[destIndex] = GetDateTime(srcIndex);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Date64Array.cs b/csharp/src/Apache.Arrow/Arrays/Date64Array.cs
deleted file mode 100644
index bf53574..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Date64Array.cs
+++ /dev/null
@@ -1,212 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Arrow
-{
-    /// <summary>
-    /// The <see cref="Date64Array"/> class holds an array of dates in the <c>Date64</c> format, where each date is
-    /// stored as the number of milliseconds since the dawn of (UNIX) time, excluding leap seconds, in multiples of
-    /// 86400000.
-    /// </summary>
-    public class Date64Array : PrimitiveArray<long>, IReadOnlyList<DateTime?>, ICollection<DateTime?>
-#if NET6_0_OR_GREATER
-        , IReadOnlyList<DateOnly?>, ICollection<DateOnly?>
-#endif
-    {
-        private const long MillisecondsPerDay = 86400000;
-
-        public Date64Array(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(Date64Type.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        /// <summary>
-        /// The <see cref="Builder"/> class can be used to fluently build <see cref="Date64Array"/> objects.
-        /// </summary>
-        public class Builder : DateArrayBuilder<long, Date64Array, Builder>
-        {
-            private class DateBuilder : PrimitiveArrayBuilder<long, Date64Array, DateBuilder>
-            {
-                protected override Date64Array Build(ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer, int length,
-                    int nullCount, int offset) =>
-                    new(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-            }
-
-            /// <summary>
-            /// Construct a new instance of the <see cref="Builder"/> class.
-            /// </summary>
-            public Builder() : base(new DateBuilder()) { }
-
-            protected override long Convert(DateTime dateTime)
-            {
-                var dateTimeOffset = new DateTimeOffset(
-                    DateTime.SpecifyKind(dateTime.Date, DateTimeKind.Unspecified),
-                    TimeSpan.Zero);
-                return dateTimeOffset.ToUnixTimeMilliseconds();
-            }
-
-            protected override long Convert(DateTimeOffset dateTimeOffset)
-            {
-                return new DateTimeOffset(dateTimeOffset.UtcDateTime.Date, TimeSpan.Zero).ToUnixTimeMilliseconds();
-            }
-
-#if NET6_0_OR_GREATER
-            protected override long Convert(DateOnly date)
-            {
-                return ((long)date.DayNumber - _epochDayNumber) * MillisecondsPerDay;
-            }
-#endif
-        }
-
-        public Date64Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Date64);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        [Obsolete("Use `GetDateTimeOffset()` instead")]
-        public DateTimeOffset? GetDate(int index) => GetDateTimeOffset(index);
-
-        /// <summary>
-        /// Get the date at the specified index in the form of a <see cref="DateTime"/> object.
-        /// </summary>
-        /// <remarks>
-        /// The <see cref="DateTime.Kind"/> property of the returned object is set to
-        /// <see cref="DateTimeKind.Unspecified"/>.
-        /// </remarks>
-        /// <param name="index">Index at which to get the date.</param>
-        /// <returns>Returns a <see cref="DateTime"/> object, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public DateTime? GetDateTime(int index)
-        {
-            long? value = GetValue(index);
-            return value.HasValue
-                ? DateTimeOffset.FromUnixTimeMilliseconds(value.Value).Date
-                : default(DateTime?);
-        }
-
-        /// <summary>
-        /// Get the date at the specified index in the form of a <see cref="DateTimeOffset"/> object.
-        /// </summary>
-        /// <param name="index">Index at which to get the date.</param>
-        /// <returns>Returns a <see cref="DateTimeOffset"/> object, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public DateTimeOffset? GetDateTimeOffset(int index)
-        {
-            long? value = GetValue(index);
-            return value.HasValue
-                ? DateTimeOffset.FromUnixTimeMilliseconds(value.Value)
-                : default(DateTimeOffset?);
-        }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Get the date at the specified index
-        /// </summary>
-        /// <param name="index">Index at which to get the date.</param>
-        /// <returns>Returns a <see cref="DateOnly" />, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public DateOnly? GetDateOnly(int index)
-        {
-            long? value = GetValue(index);
-            return value.HasValue
-                ? DateOnly.FromDateTime(DateTimeOffset.FromUnixTimeMilliseconds(value.Value).UtcDateTime)
-                : default(DateOnly?);
-        }
-
-        int IReadOnlyCollection<DateOnly?>.Count => Length;
-
-        DateOnly? IReadOnlyList<DateOnly?>.this[int index] => GetDateOnly(index);
-
-        IEnumerator<DateOnly?> IEnumerable<DateOnly?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetDateOnly(index);
-            };
-        }
-
-        int ICollection<DateOnly?>.Count => Length;
-        bool ICollection<DateOnly?>.IsReadOnly => true;
-        void ICollection<DateOnly?>.Add(DateOnly? item) => throw new NotSupportedException("Collection is read-only.");
-        bool ICollection<DateOnly?>.Remove(DateOnly? item) => throw new NotSupportedException("Collection is read-only.");
-        void ICollection<DateOnly?>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-        bool ICollection<DateOnly?>.Contains(DateOnly? item)
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                if (GetDateOnly(index).Equals(item))
-                    return true;
-            }
-
-            return false;
-        }
-
-        void ICollection<DateOnly?>.CopyTo(DateOnly?[] array, int arrayIndex)
-        {
-            for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-            {
-                array[destIndex] = GetDateOnly(srcIndex);
-            }
-        }
-#endif
-
-        int IReadOnlyCollection<DateTime?>.Count => Length;
-
-        DateTime? IReadOnlyList<DateTime?>.this[int index] => GetDateTime(index);
-
-        IEnumerator<DateTime?> IEnumerable<DateTime?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetDateTime(index);
-            }
-        }
-
-        int ICollection<DateTime?>.Count => Length;
-        bool ICollection<DateTime?>.IsReadOnly => true;
-        void ICollection<DateTime?>.Add(DateTime? item) => throw new NotSupportedException("Collection is read-only.");
-        bool ICollection<DateTime?>.Remove(DateTime? item) => throw new NotSupportedException("Collection is read-only.");
-        void ICollection<DateTime?>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-        bool ICollection<DateTime?>.Contains(DateTime? item)
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                if (GetDateTime(index).Equals(item))
-                    return true;
-            }
-
-            return false;
-        }
-
-        void ICollection<DateTime?>.CopyTo(DateTime?[] array, int arrayIndex)
-        {
-            for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-            {
-                array[destIndex] = GetDateTime(srcIndex);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/DateArrayBuilder.cs b/csharp/src/Apache.Arrow/Arrays/DateArrayBuilder.cs
deleted file mode 100644
index 29246fa..0000000
--- a/csharp/src/Apache.Arrow/Arrays/DateArrayBuilder.cs
+++ /dev/null
@@ -1,279 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Apache.Arrow
-{
-    /// <summary>
-    /// The <see cref="DateArrayBuilder{TUnderlying,TArray,TBuilder}"/> class is an abstract array builder that can
-    /// accept dates in the form of <see cref="DateTime"/> or <see cref="DateTimeOffset"/> and convert to some
-    /// underlying date representation.
-    /// </summary>
-    public abstract class DateArrayBuilder<TUnderlying, TArray, TBuilder> :
-        DelegatingArrayBuilder<TUnderlying, TArray, TBuilder>,
-        IArrowArrayBuilder<DateTime, TArray, TBuilder>,
-        IArrowArrayBuilder<DateTimeOffset, TArray, TBuilder>
-#if NET6_0_OR_GREATER
-        , IArrowArrayBuilder<DateOnly, TArray, TBuilder>
-#endif
-        where TArray : IArrowArray
-        where TBuilder : class, IArrowArrayBuilder<TArray>
-    {
-#if NET6_0_OR_GREATER
-        protected static readonly long _epochDayNumber = new DateOnly(1970, 1, 1).DayNumber;
-#endif
-
-        /// <summary>
-        /// Construct a new instance of the <see cref="DateArrayBuilder{TUnderlying,TArray,TBuilder}"/> class.
-        /// </summary>
-        /// <param name="innerBuilder">Inner builder that will produce arrays of type <typeparamref name="TArray"/>.
-        /// </param>
-        protected DateArrayBuilder(IArrowArrayBuilder<TUnderlying, TArray, IArrowArrayBuilder<TArray>> innerBuilder)
-            : base(innerBuilder)
-        { }
-
-        /// <summary>
-        /// Append a date in the form of a <see cref="DateTime"/> object to the array.
-        /// </summary>
-        /// <remarks>
-        /// The value of <see cref="DateTime.Kind"/> on the input does not have any effect on the behaviour of this
-        /// method.
-        /// </remarks>
-        /// <param name="value">Date to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Append(DateTime value)
-        {
-            InnerBuilder.Append(Convert(value));
-            return this as TBuilder;
-        }
-
-        /// <summary>
-        /// Append a date from a <see cref="DateTimeOffset"/> object to the array.
-        /// </summary>
-        /// <remarks>
-        /// Note that to convert the supplied <paramref name="value"/> parameter to a date, it is first converted to
-        /// UTC and the date then taken from the UTC date/time.  Depending on the value of its
-        /// <see cref="DateTimeOffset.Offset"/> property, this may not necessarily be the same as the date obtained by
-        /// calling its <see cref="DateTimeOffset.Date"/> property.
-        /// </remarks>
-        /// <param name="value">Date to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Append(DateTimeOffset value)
-        {
-            InnerBuilder.Append(Convert(value));
-            return this as TBuilder;
-        }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Append a date from a <see cref="DateOnly"/> object to the array.
-        /// </summary>
-        /// </remarks>
-        /// <param name="value">Date to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Append(DateOnly value)
-        {
-            InnerBuilder.Append(Convert(value));
-            return this as TBuilder;
-        }
-#endif
-
-        /// <summary>
-        /// Append a span of dates in the form of <see cref="DateTime"/> objects to the array.
-        /// </summary>
-        /// <remarks>
-        /// The value of <see cref="DateTime.Kind"/> on any of the inputs does not have any effect on the behaviour of
-        /// this method.
-        /// </remarks>
-        /// <param name="span">Span of dates to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Append(ReadOnlySpan<DateTime> span)
-        {
-            InnerBuilder.Reserve(span.Length);
-            foreach (var item in span)
-            {
-                InnerBuilder.Append(Convert(item));
-            }
-
-            return this as TBuilder;
-        }
-
-        /// <summary>
-        /// Append a span of dates in the form of <see cref="DateTimeOffset"/> objects to the array.
-        /// </summary>
-        /// <remarks>
-        /// Note that to convert the <see cref="DateTimeOffset"/> objects in the <paramref name="span"/> parameter to
-        /// dates, they are first converted to UTC and the date then taken from the UTC date/times.  Depending on the
-        /// value of each <see cref="DateTimeOffset.Offset"/> property, this may not necessarily be the same as the
-        /// date obtained by calling the <see cref="DateTimeOffset.Date"/> property.
-        /// </remarks>
-        /// <param name="span">Span of dates to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Append(ReadOnlySpan<DateTimeOffset> span)
-        {
-            InnerBuilder.Reserve(span.Length);
-            foreach (var item in span)
-            {
-                InnerBuilder.Append(Convert(item));
-            }
-
-            return this as TBuilder;
-        }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Append a span of dates in the form of <see cref="DateOnly"/> objects to the array.
-        /// </summary>
-        /// <param name="span">Span of dates to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Append(ReadOnlySpan<DateOnly> span)
-        {
-            InnerBuilder.Reserve(span.Length);
-            foreach (var item in span)
-            {
-                InnerBuilder.Append(Convert(item));
-            }
-
-            return this as TBuilder;
-        }
-#endif
-
-        /// <summary>
-        /// Append a null date to the array.
-        /// </summary>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public override TBuilder AppendNull()
-        {
-            InnerBuilder.AppendNull();
-            return this as TBuilder;
-        }
-
-        /// <summary>
-        /// Append a collection of dates in the form of <see cref="DateTime"/> objects to the array.
-        /// </summary>
-        /// <remarks>
-        /// The value of <see cref="DateTime.Kind"/> on any of the inputs does not have any effect on the behaviour of
-        /// this method.
-        /// </remarks>
-        /// <param name="values">Collection of dates to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder AppendRange(IEnumerable<DateTime> values)
-        {
-            InnerBuilder.AppendRange(values.Select(Convert));
-            return this as TBuilder;
-        }
-
-        /// <summary>
-        /// Append a collection of dates in the form of <see cref="DateTimeOffset"/> objects to the array.
-        /// </summary>
-        /// <remarks>
-        /// Note that to convert the <see cref="DateTimeOffset"/> objects in the <paramref name="values"/> parameter to
-        /// dates, they are first converted to UTC and the date then taken from the UTC date/times.  Depending on the
-        /// value of each <see cref="DateTimeOffset.Offset"/> property, this may not necessarily be the same as the
-        /// date obtained by calling the <see cref="DateTimeOffset.Date"/> property.
-        /// </remarks>
-        /// <param name="values">Collection of dates to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder AppendRange(IEnumerable<DateTimeOffset> values)
-        {
-            InnerBuilder.AppendRange(values.Select(Convert));
-            return this as TBuilder;
-        }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Append a collection of dates in the form of <see cref="DateOnly"/> objects to the array.
-        /// </summary>
-        /// <param name="values">Collection of dates to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder AppendRange(IEnumerable<DateOnly> values)
-        {
-            InnerBuilder.AppendRange(values.Select(Convert));
-            return this as TBuilder;
-        }
-#endif
-
-        /// <summary>
-        /// Set the value of a date in the form of a <see cref="DateTime"/> object at the specified index.
-        /// </summary>
-        /// <remarks>
-        /// The value of <see cref="DateTime.Kind"/> on the input does not have any effect on the behaviour of this
-        /// method.
-        /// </remarks>
-        /// <param name="index">Index at which to set value.</param>
-        /// <param name="value">Date to set.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Set(int index, DateTime value)
-        {
-            InnerBuilder.Set(index, Convert(value));
-            return this as TBuilder;
-        }
-
-        /// <summary>
-        /// Set the value of a date in the form of a <see cref="DateTimeOffset"/> object at the specified index.
-        /// </summary>
-        /// <remarks>
-        /// Note that to convert the supplied <paramref name="value"/> parameter to a date, it is first converted to
-        /// UTC and the date then taken from the UTC date/time.  Depending on the value of its
-        /// <see cref="DateTimeOffset.Offset"/> property, this may not necessarily be the same as the date obtained by
-        /// calling its <see cref="DateTimeOffset.Date"/> property.
-        /// </remarks>
-        /// <param name="index">Index at which to set value.</param>
-        /// <param name="value">Date to set.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Set(int index, DateTimeOffset value)
-        {
-            InnerBuilder.Set(index, Convert(value));
-            return this as TBuilder;
-        }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Set the value of a date in the form of a <see cref="DateOnly"/> object at the specified index.
-        /// </summary>
-        /// <param name="index">Index at which to set value.</param>
-        /// <param name="value">Date to set.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Set(int index, DateOnly value)
-        {
-            InnerBuilder.Set(index, Convert(value));
-            return this as TBuilder;
-        }
-#endif
-
-        /// <summary>
-        /// Swap the values of the dates at the specified indices.
-        /// </summary>
-        /// <param name="i">First index.</param>
-        /// <param name="j">Second index.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Swap(int i, int j)
-        {
-            InnerBuilder.Swap(i, j);
-            return this as TBuilder;
-        }
-
-        protected abstract TUnderlying Convert(DateTime dateTime);
-
-        protected abstract TUnderlying Convert(DateTimeOffset dateTimeOffset);
-
-#if NET6_0_OR_GREATER
-        protected abstract TUnderlying Convert(DateOnly date);
-#endif
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Decimal128Array.cs b/csharp/src/Apache.Arrow/Arrays/Decimal128Array.cs
deleted file mode 100644
index 2fb6f4c..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Decimal128Array.cs
+++ /dev/null
@@ -1,206 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Data.SqlTypes;
-using System.Diagnostics;
-using Apache.Arrow.Arrays;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class Decimal128Array : FixedSizeBinaryArray, IReadOnlyList<SqlDecimal?>
-    {
-        public class Builder : BuilderBase<Decimal128Array, Builder>
-        {
-            public Builder(Decimal128Type type) : base(type, 16)
-            {
-                DataType = type;
-            }
-
-            protected new Decimal128Type DataType { get; }
-
-            protected override Decimal128Array Build(ArrayData data)
-            {
-                return new Decimal128Array(data);
-            }
-
-            public Builder Append(decimal value)
-            {
-                Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, DataType.ByteWidth, bytes);
-
-                return Append(bytes);
-            }
-
-            public Builder AppendRange(IEnumerable<decimal> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (decimal d in values)
-                {
-                    Append(d);
-                }
-
-                return Instance;
-            }
-
-            public Builder Append(string value)
-            {
-                if (value == null)
-                {
-                    AppendNull();
-                }
-                else
-                {
-                    Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                    DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, ByteWidth, bytes);
-                    Append(bytes);
-                }
-
-                return Instance;
-            }
-
-            public Builder AppendRange(IEnumerable<string> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (string s in values)
-                {
-                    Append(s);
-                }
-
-                return Instance;
-            }
-
-            public Builder Append(SqlDecimal value)
-            {
-                Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, bytes);
-
-                return Append(bytes);
-            }
-
-            public Builder AppendRange(IEnumerable<SqlDecimal> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (SqlDecimal d in values)
-                {
-                    Append(d);
-                }
-
-                return Instance;
-            }
-
-            public Builder Set(int index, decimal value)
-            {
-                Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, DataType.ByteWidth, bytes);
-
-                return Set(index, bytes);
-            }
-        }
-
-        public Decimal128Array(ArrayData data)
-            : base(ArrowTypeId.Decimal128, data)
-        {
-            data.EnsureDataType(ArrowTypeId.Decimal128);
-            data.EnsureBufferCount(2);
-            Debug.Assert(Data.DataType is Decimal128Type);
-        }
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public int Scale => ((Decimal128Type)Data.DataType).Scale;
-        public int Precision => ((Decimal128Type)Data.DataType).Precision;
-        public int ByteWidth => ((Decimal128Type)Data.DataType).ByteWidth;
-
-        public decimal? GetValue(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-            return DecimalUtility.GetDecimal(ValueBuffer, Offset + index, Scale, ByteWidth);
-        }
-
-        public IList<decimal?> ToList(bool includeNulls = false)
-        {
-            var list = new List<decimal?>(Length);
-
-            for (int i = 0; i < Length; i++)
-            {
-                decimal? value = GetValue(i);
-
-                if (value.HasValue)
-                {
-                    list.Add(value.Value);
-                }
-                else
-                {
-                    if (includeNulls)
-                    {
-                        list.Add(null);
-                    }
-                }
-            }
-
-            return list;
-        }
-
-        public string GetString(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-            return DecimalUtility.GetString(ValueBuffer, Offset + index, Precision, Scale, ByteWidth);
-        }
-
-        public SqlDecimal? GetSqlDecimal(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-
-            return DecimalUtility.GetSqlDecimal128(ValueBuffer, Offset + index, Precision, Scale);
-        }
-
-        int IReadOnlyCollection<SqlDecimal?>.Count => Length;
-        SqlDecimal? IReadOnlyList<SqlDecimal?>.this[int index] => GetSqlDecimal(index);
-
-        IEnumerator<SqlDecimal?> IEnumerable<SqlDecimal?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetSqlDecimal(index);
-            }
-        }
-
-        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<SqlDecimal>)this).GetEnumerator();
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Decimal256Array.cs b/csharp/src/Apache.Arrow/Arrays/Decimal256Array.cs
deleted file mode 100644
index 52bfb9e..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Decimal256Array.cs
+++ /dev/null
@@ -1,248 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#nullable enable
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Data.SqlTypes;
-using System.Diagnostics;
-using Apache.Arrow.Arrays;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class Decimal256Array : FixedSizeBinaryArray, IReadOnlyList<SqlDecimal?>, IReadOnlyList<string?>
-    {
-        public class Builder : BuilderBase<Decimal256Array, Builder>
-        {
-            public Builder(Decimal256Type type) : base(type, 32)
-            {
-                DataType = type;
-            }
-
-            protected new Decimal256Type DataType { get; }
-
-            protected override Decimal256Array Build(ArrayData data)
-            {
-                return new Decimal256Array(data);
-            }
-
-            public Builder Append(decimal value)
-            {
-                Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, DataType.ByteWidth, bytes);
-
-                return Append(bytes);
-            }
-
-            public Builder AppendRange(IEnumerable<decimal> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (decimal d in values)
-                {
-                    Append(d);
-                }
-
-                return Instance;
-            }
-
-            public Builder Append(string value)
-            {
-                if (value == null)
-                {
-                    AppendNull();
-                }
-                else
-                {
-                    Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                    DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, ByteWidth, bytes);
-                    Append(bytes);
-                }
-
-                return Instance;
-            }
-
-            public Builder AppendRange(IEnumerable<string> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (string s in values)
-                {
-                    Append(s);
-                }
-
-                return Instance;
-            }
-
-            public Builder Append(SqlDecimal value)
-            {
-                Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, bytes);
-                if (!value.IsPositive)
-                {
-                    var span = bytes.CastTo<long>();
-                    span[2] = -1;
-                    span[3] = -1;
-                }
-
-                return Append(bytes);
-            }
-
-            public Builder AppendRange(IEnumerable<SqlDecimal> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (SqlDecimal d in values)
-                {
-                    Append(d);
-                }
-
-                return Instance;
-            }
-
-            public Builder Set(int index, decimal value)
-            {
-                Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, DataType.ByteWidth, bytes);
-
-                return Set(index, bytes);
-            }
-        }
-
-        public Decimal256Array(ArrayData data)
-            : base(ArrowTypeId.Decimal256, data)
-        {
-            data.EnsureDataType(ArrowTypeId.Decimal256);
-            data.EnsureBufferCount(2);
-            Debug.Assert(Data.DataType is Decimal256Type);
-        }
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public int Scale => ((Decimal256Type)Data.DataType).Scale;
-        public int Precision => ((Decimal256Type)Data.DataType).Precision;
-        public int ByteWidth => ((Decimal256Type)Data.DataType).ByteWidth;
-
-        public decimal? GetValue(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-
-            return DecimalUtility.GetDecimal(ValueBuffer, Offset + index, Scale, ByteWidth);
-        }
-
-        public IList<decimal?> ToList(bool includeNulls = false)
-        {
-            var list = new List<decimal?>(Length);
-
-            for (int i = 0; i < Length; i++)
-            {
-                decimal? value = GetValue(i);
-
-                if (value.HasValue)
-                {
-                    list.Add(value.Value);
-                }
-                else
-                {
-                    if (includeNulls)
-                    {
-                        list.Add(null);
-                    }
-                }
-            }
-
-            return list;
-        }
-
-        public string? GetString(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-            return DecimalUtility.GetString(ValueBuffer, Offset + index, Precision, Scale, ByteWidth);
-        }
-
-        public bool TryGetSqlDecimal(int index, out SqlDecimal? value)
-        {
-            if (IsNull(index))
-            {
-                value = null;
-                return true;
-            }
-
-            const int longWidth = 4;
-            var span = ValueBuffer.Span.CastTo<long>().Slice((Offset + index) * longWidth);
-            if ((span[2] == 0 && span[3] == 0) ||
-                (span[2] == -1 && span[3] == -1))
-            {
-                value = DecimalUtility.GetSqlDecimal128(ValueBuffer, 2 * (Offset + index), Precision, Scale);
-                return true;
-            }
-
-            value = null;
-            return false;
-        }
-
-        private SqlDecimal? GetSqlDecimal(int index)
-        {
-            SqlDecimal? value;
-            if (TryGetSqlDecimal(index, out value))
-            {
-                return value;
-            }
-
-            throw new OverflowException("decimal256 value out of range of SqlDecimal");
-        }
-
-        int IReadOnlyCollection<SqlDecimal?>.Count => Length;
-        SqlDecimal? IReadOnlyList<SqlDecimal?>.this[int index] => GetSqlDecimal(index);
-
-        IEnumerator<SqlDecimal?> IEnumerable<SqlDecimal?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetSqlDecimal(index);
-            }
-        }
-
-        int IReadOnlyCollection<string?>.Count => Length;
-        string? IReadOnlyList<string?>.this[int index] => GetString(index);
-
-        IEnumerator<string?> IEnumerable<string?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetString(index);
-            }
-        }
-
-        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<string?>)this).GetEnumerator();
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Decimal32Array.cs b/csharp/src/Apache.Arrow/Arrays/Decimal32Array.cs
deleted file mode 100644
index 21dee11..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Decimal32Array.cs
+++ /dev/null
@@ -1,182 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using Apache.Arrow.Arrays;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class Decimal32Array : FixedSizeBinaryArray, IReadOnlyList<decimal?>
-    {
-        public class Builder : BuilderBase<Decimal32Array, Builder>
-        {
-            public Builder(Decimal32Type type) : base(type, 4)
-            {
-                DataType = type;
-            }
-
-            protected new Decimal32Type DataType { get; }
-
-            protected override Decimal32Array Build(ArrayData data)
-            {
-                return new Decimal32Array(data);
-            }
-
-            public Builder Append(decimal value)
-            {
-                Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, DataType.ByteWidth, bytes);
-
-                return Append(bytes);
-            }
-
-            public Builder AppendRange(IEnumerable<decimal> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (decimal d in values)
-                {
-                    Append(d);
-                }
-
-                return Instance;
-            }
-
-            public Builder Append(string value)
-            {
-                if (value == null)
-                {
-                    AppendNull();
-                }
-                else
-                {
-                    Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                    DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, ByteWidth, bytes);
-                    Append(bytes);
-                }
-
-                return Instance;
-            }
-
-            public Builder AppendRange(IEnumerable<string> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (string s in values)
-                {
-                    Append(s);
-                }
-
-                return Instance;
-            }
-
-            public Builder Set(int index, decimal value)
-            {
-                Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, DataType.ByteWidth, bytes);
-
-                return Set(index, bytes);
-            }
-        }
-
-        public Decimal32Array(ArrayData data)
-            : base(ArrowTypeId.Decimal32, data)
-        {
-            data.EnsureDataType(ArrowTypeId.Decimal32);
-            data.EnsureBufferCount(2);
-            Debug.Assert(Data.DataType is Decimal32Type);
-        }
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public int Scale => ((Decimal32Type)Data.DataType).Scale;
-        public int Precision => ((Decimal32Type)Data.DataType).Precision;
-        public int ByteWidth => ((Decimal32Type)Data.DataType).ByteWidth;
-
-        public decimal? GetValue(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-            return DecimalUtility.GetDecimal(ValueBuffer, Offset + index, Scale, ByteWidth);
-        }
-
-        public IList<decimal?> ToList(bool includeNulls = false)
-        {
-            var list = new List<decimal?>(Length);
-
-            for (int i = 0; i < Length; i++)
-            {
-                decimal? value = GetValue(i);
-
-                if (value.HasValue)
-                {
-                    list.Add(value.Value);
-                }
-                else
-                {
-                    if (includeNulls)
-                    {
-                        list.Add(null);
-                    }
-                }
-            }
-
-            return list;
-        }
-
-        public string GetString(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-            return DecimalUtility.GetString(ValueBuffer, Offset + index, Precision, Scale, ByteWidth);
-        }
-
-        public decimal? GetDecimal(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-
-            return DecimalUtility.GetDecimal(ValueBuffer, Offset + index, Scale, ByteWidth);
-        }
-
-        int IReadOnlyCollection<decimal?>.Count => Length;
-        decimal? IReadOnlyList<decimal?>.this[int index] => GetDecimal(index);
-
-        IEnumerator<decimal?> IEnumerable<decimal?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetDecimal(index);
-            }
-        }
-
-        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<decimal>)this).GetEnumerator();
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Decimal64Array.cs b/csharp/src/Apache.Arrow/Arrays/Decimal64Array.cs
deleted file mode 100644
index b50baef..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Decimal64Array.cs
+++ /dev/null
@@ -1,182 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using Apache.Arrow.Arrays;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class Decimal64Array : FixedSizeBinaryArray, IReadOnlyList<decimal?>
-    {
-        public class Builder : BuilderBase<Decimal64Array, Builder>
-        {
-            public Builder(Decimal64Type type) : base(type, 8)
-            {
-                DataType = type;
-            }
-
-            protected new Decimal64Type DataType { get; }
-
-            protected override Decimal64Array Build(ArrayData data)
-            {
-                return new Decimal64Array(data);
-            }
-
-            public Builder Append(decimal value)
-            {
-                Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, DataType.ByteWidth, bytes);
-
-                return Append(bytes);
-            }
-
-            public Builder AppendRange(IEnumerable<decimal> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (decimal d in values)
-                {
-                    Append(d);
-                }
-
-                return Instance;
-            }
-
-            public Builder Append(string value)
-            {
-                if (value == null)
-                {
-                    AppendNull();
-                }
-                else
-                {
-                    Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                    DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, ByteWidth, bytes);
-                    Append(bytes);
-                }
-
-                return Instance;
-            }
-
-            public Builder AppendRange(IEnumerable<string> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (string s in values)
-                {
-                    Append(s);
-                }
-
-                return Instance;
-            }
-
-            public Builder Set(int index, decimal value)
-            {
-                Span<byte> bytes = stackalloc byte[DataType.ByteWidth];
-                DecimalUtility.GetBytes(value, DataType.Precision, DataType.Scale, DataType.ByteWidth, bytes);
-
-                return Set(index, bytes);
-            }
-        }
-
-        public Decimal64Array(ArrayData data)
-            : base(ArrowTypeId.Decimal64, data)
-        {
-            data.EnsureDataType(ArrowTypeId.Decimal64);
-            data.EnsureBufferCount(2);
-            Debug.Assert(Data.DataType is Decimal64Type);
-        }
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public int Scale => ((Decimal64Type)Data.DataType).Scale;
-        public int Precision => ((Decimal64Type)Data.DataType).Precision;
-        public int ByteWidth => ((Decimal64Type)Data.DataType).ByteWidth;
-
-        public decimal? GetValue(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-            return DecimalUtility.GetDecimal(ValueBuffer, Offset + index, Scale, ByteWidth);
-        }
-
-        public IList<decimal?> ToList(bool includeNulls = false)
-        {
-            var list = new List<decimal?>(Length);
-
-            for (int i = 0; i < Length; i++)
-            {
-                decimal? value = GetValue(i);
-
-                if (value.HasValue)
-                {
-                    list.Add(value.Value);
-                }
-                else
-                {
-                    if (includeNulls)
-                    {
-                        list.Add(null);
-                    }
-                }
-            }
-
-            return list;
-        }
-
-        public string GetString(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-            return DecimalUtility.GetString(ValueBuffer, Offset + index, Precision, Scale, ByteWidth);
-        }
-
-        public decimal? GetDecimal(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-
-            return DecimalUtility.GetDecimal(ValueBuffer, Offset + index, Scale, ByteWidth);
-        }
-
-        int IReadOnlyCollection<decimal?>.Count => Length;
-        decimal? IReadOnlyList<decimal?>.this[int index] => GetDecimal(index);
-
-        IEnumerator<decimal?> IEnumerable<decimal?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetDecimal(index);
-            }
-        }
-
-        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<decimal>)this).GetEnumerator();
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/DelegatingArrayBuilder.cs b/csharp/src/Apache.Arrow/Arrays/DelegatingArrayBuilder.cs
deleted file mode 100644
index 827b00c..0000000
--- a/csharp/src/Apache.Arrow/Arrays/DelegatingArrayBuilder.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Memory;
-
-namespace Apache.Arrow
-{
-    /// <summary>
-    /// The <see cref="DelegatingArrayBuilder{T,TArray,TBuilder}"/> class can be used as the base for any array builder
-    /// that needs to delegate most of its functionality to an inner array builder.
-    /// </summary>
-    /// <remarks>
-    /// The typical use case is when an array builder may accept a number of different types as input, but which are
-    /// all internally converted to a single type for assembly into an array.
-    /// </remarks>
-    /// <typeparam name="T">Type of item accepted by inner array builder.</typeparam>
-    /// <typeparam name="TArray">Type of array produced by this (and the inner) builder.</typeparam>
-    /// <typeparam name="TBuilder">Type of builder (see Curiously-Recurring Template Pattern).</typeparam>
-    public abstract class DelegatingArrayBuilder<T, TArray, TBuilder> : IArrowArrayBuilder<TArray, TBuilder>
-        where TArray : IArrowArray
-        where TBuilder : class, IArrowArrayBuilder<TArray>
-    {
-        /// <summary>
-        /// Gets the inner array builder.
-        /// </summary>
-        protected IArrowArrayBuilder<T, TArray, IArrowArrayBuilder<TArray>> InnerBuilder { get; }
-
-        /// <summary>
-        /// Gets the number of items added to the array so far.
-        /// </summary>
-        public int Length => InnerBuilder.Length;
-
-        /// <summary>
-        /// Construct a new instance of the <see cref="DelegatingArrayBuilder{T,TArray,TBuilder}"/> class.
-        /// </summary>
-        /// <param name="innerBuilder">Inner array builder.</param>
-        protected DelegatingArrayBuilder(IArrowArrayBuilder<T, TArray, IArrowArrayBuilder<TArray>> innerBuilder)
-        {
-            InnerBuilder = innerBuilder ?? throw new ArgumentNullException(nameof(innerBuilder));
-        }
-
-        /// <summary>
-        /// Build an Arrow Array from the appended contents so far.
-        /// </summary>
-        /// <param name="allocator">Optional memory allocator.</param>
-        /// <returns>Returns the built array.</returns>
-        public TArray Build(MemoryAllocator allocator = default) => InnerBuilder.Build(allocator);
-
-        /// <summary>
-        /// Reserve a given number of items' additional capacity.
-        /// </summary>
-        /// <param name="additionalCapacity">Number of items of required additional capacity.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Reserve(int additionalCapacity)
-        {
-            InnerBuilder.Reserve(additionalCapacity);
-            return this as TBuilder;
-        }
-
-        /// <summary>
-        /// Resize the array to a given size.
-        /// </summary>
-        /// <remarks>
-        /// Note that if the required capacity is larger than the current length of the populated array so far,
-        /// the array's contents in the new, expanded region are undefined.
-        /// </remarks>
-        /// <remarks>
-        /// Note that if the required capacity is smaller than the current length of the populated array so far,
-        /// the array will be truncated and items at the end of the array will be lost.
-        /// </remarks>
-        /// <param name="capacity">Number of items of required capacity.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Resize(int capacity)
-        {
-            InnerBuilder.Resize(capacity);
-            return this as TBuilder;
-        }
-
-        /// <summary>
-        /// Clear all contents appended so far.
-        /// </summary>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Clear()
-        {
-            InnerBuilder.Clear();
-            return this as TBuilder;
-        }
-
-        /// <summary>
-        /// Appends a null value
-        /// </summary>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public abstract TBuilder AppendNull();
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/DenseUnionArray.cs b/csharp/src/Apache.Arrow/Arrays/DenseUnionArray.cs
deleted file mode 100644
index 79880c8..0000000
--- a/csharp/src/Apache.Arrow/Arrays/DenseUnionArray.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Apache.Arrow
-{
-    public class DenseUnionArray : UnionArray
-    {
-        public ArrowBuffer ValueOffsetBuffer => Data.Buffers[1];
-
-        public ReadOnlySpan<int> ValueOffsets => ValueOffsetBuffer.Span.CastTo<int>().Slice(Offset, Length);
-
-        public DenseUnionArray(
-            IArrowType dataType,
-            int length,
-            IEnumerable<IArrowArray> children,
-            ArrowBuffer typeIds,
-            ArrowBuffer valuesOffsetBuffer,
-            int nullCount = 0,
-            int offset = 0)
-            : base(new ArrayData(
-                dataType, length, nullCount, offset, new[] { typeIds, valuesOffsetBuffer },
-                children.Select(child => child.Data)))
-        {
-            ValidateMode(UnionMode.Dense, Type.Mode);
-        }
-
-        public DenseUnionArray(ArrayData data) 
-            : base(data)
-        {
-            ValidateMode(UnionMode.Dense, Type.Mode);
-            data.EnsureBufferCount(2);
-        }
-
-        protected override bool FieldIsValid(IArrowArray fieldArray, int index)
-        {
-            return fieldArray.IsValid(ValueOffsets[index]);
-        }
-
-        internal new static int ComputeNullCount(ArrayData data)
-        {
-            var offset = data.Offset;
-            var length = data.Length;
-            var typeIds = data.Buffers[0].Span.Slice(offset, length);
-            var valueOffsets = data.Buffers[1].Span.CastTo<int>().Slice(offset, length);
-            var childArrays = new IArrowArray[data.Children.Length];
-            for (var childIdx = 0; childIdx < data.Children.Length; ++childIdx)
-            {
-                childArrays[childIdx] = ArrowArrayFactory.BuildArray(data.Children[childIdx]);
-            }
-
-            var nullCount = 0;
-            for (var i = 0; i < length; ++i)
-            {
-                var typeId = typeIds[i];
-                var valueOffset = valueOffsets[i];
-                nullCount += childArrays[typeId].IsNull(valueOffset) ? 1 : 0;
-            }
-
-            return nullCount;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/DictionaryArray.cs b/csharp/src/Apache.Arrow/Arrays/DictionaryArray.cs
deleted file mode 100644
index 29c0f5c..0000000
--- a/csharp/src/Apache.Arrow/Arrays/DictionaryArray.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class DictionaryArray : Array
-    {
-        public IArrowArray Dictionary { get; }
-        public IArrowArray Indices { get; }
-        public ArrowBuffer IndicesBuffer => Data.Buffers[1];
-
-        public DictionaryArray(ArrayData data) : base(data)
-        {
-            data.EnsureBufferCount(2);
-            data.EnsureDataType(ArrowTypeId.Dictionary);
-
-            if (data.Dictionary == null)
-            {
-                throw new ArgumentException($"{nameof(data.Dictionary)} must not be null");
-            }
-
-            var dicType = (DictionaryType)data.DataType;
-            data.Dictionary.EnsureDataType(dicType.ValueType.TypeId);
-
-            var indicesData = new ArrayData(dicType.IndexType, data.Length, data.NullCount, data.Offset, data.Buffers, data.Children);
-
-            Indices = ArrowArrayFactory.BuildArray(indicesData);
-            Dictionary = ArrowArrayFactory.BuildArray(data.Dictionary);
-        }
-
-        public DictionaryArray(DictionaryType dataType, IArrowArray indicesArray, IArrowArray dictionary) :
-            base(new ArrayData(dataType, indicesArray.Length, indicesArray.Data.NullCount, indicesArray.Data.Offset, indicesArray.Data.Buffers, indicesArray.Data.Children, dictionary.Data))
-        {
-            Data.EnsureBufferCount(2);
-
-            indicesArray.Data.EnsureDataType(dataType.IndexType.TypeId);
-            dictionary.Data.EnsureDataType(dataType.ValueType.TypeId);
-
-            Indices = indicesArray;
-            Dictionary = dictionary;
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/DoubleArray.cs b/csharp/src/Apache.Arrow/Arrays/DoubleArray.cs
deleted file mode 100644
index 6450aa1..0000000
--- a/csharp/src/Apache.Arrow/Arrays/DoubleArray.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class DoubleArray : PrimitiveArray<double>
-    {
-        public class Builder : PrimitiveArrayBuilder<double, DoubleArray, Builder>
-        {
-            protected override DoubleArray Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new DoubleArray(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public DoubleArray(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(DoubleType.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public DoubleArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Double);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/DurationArray.cs b/csharp/src/Apache.Arrow/Arrays/DurationArray.cs
deleted file mode 100644
index f725a71..0000000
--- a/csharp/src/Apache.Arrow/Arrays/DurationArray.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class DurationArray : PrimitiveArray<long>, IReadOnlyList<TimeSpan?>
-    {
-        public class Builder : PrimitiveArrayBuilder<long, DurationArray, Builder>
-        {
-            public DurationType DataType { get; }
-
-            public Builder(DurationType dataType)
-            {
-                DataType = dataType;
-            }
-
-            protected override DurationArray Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new DurationArray(DataType, valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-
-            /// <summary>
-            /// Append a duration in the form of a <see cref="TimeSpan"/> object to the array.
-            /// </summary>
-            /// <param name="value">TimeSpan to add.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public Builder Append(TimeSpan value)
-            {
-                Append(DataType.Unit.ConvertFromTicks(value.Ticks));
-                return this;
-            }
-
-            /// <summary>
-            /// Append a duration in the form of a <see cref="TimeSpan"/> object to the array.
-            /// </summary>
-            /// <param name="value">TimeSpan to add.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public Builder Append(TimeSpan? value) =>
-                (value == null) ? AppendNull() : Append(value.Value);
-        }
-
-        public DurationArray(
-            DurationType type,
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(type, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public DurationArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Duration);
-        }
-
-        public DurationType DataType => (DurationType)this.Data.DataType;
-
-        public TimeSpan? GetTimeSpan(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-            return IsValid(index) ? new TimeSpan(DataType.Unit.ConvertToTicks(Values[index])) : null;
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        int IReadOnlyCollection<TimeSpan?>.Count => Length;
-        TimeSpan? IReadOnlyList<TimeSpan?>.this[int index] => GetTimeSpan(index);
-
-        IEnumerator<TimeSpan?> IEnumerable<TimeSpan?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetTimeSpan(index);
-            }
-        }
-
-        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<TimeSpan?>)this).GetEnumerator();
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/FieldComparer.cs b/csharp/src/Apache.Arrow/Arrays/FieldComparer.cs
deleted file mode 100644
index 9c5192c..0000000
--- a/csharp/src/Apache.Arrow/Arrays/FieldComparer.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Linq;
-
-namespace Apache.Arrow
-{
-    internal static class FieldComparer
-    {
-        public static bool Compare(Field expected, Field actual)
-        {
-            if (ReferenceEquals(expected, actual))
-            {
-                return true;
-            }
-
-            if (expected.Name != actual.Name || expected.IsNullable != actual.IsNullable ||
-                expected.HasMetadata != actual.HasMetadata)
-            {
-                return false;
-            }
-
-            if (expected.HasMetadata)
-            {
-                if (expected.Metadata.Count != actual.Metadata.Count)
-                {
-                    return false;
-                }
-
-                if (!expected.Metadata.Keys.All(k => actual.Metadata.ContainsKey(k) && expected.Metadata[k] == actual.Metadata[k]))
-                {
-                    return false;
-                }
-            }
-
-            var dataTypeComparer = new ArrayDataTypeComparer(expected.DataType);
-
-            actual.DataType.Accept(dataTypeComparer);
-
-            if (!dataTypeComparer.DataTypeMatch)
-            {
-                return false;
-            }
-
-            return true;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/FixedSizeBinaryArray.cs b/csharp/src/Apache.Arrow/Arrays/FixedSizeBinaryArray.cs
deleted file mode 100644
index 9d597ef..0000000
--- a/csharp/src/Apache.Arrow/Arrays/FixedSizeBinaryArray.cs
+++ /dev/null
@@ -1,239 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow.Arrays
-{
-    public class FixedSizeBinaryArray : Array, IReadOnlyList<byte[]>
-    {
-        public FixedSizeBinaryArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.FixedSizedBinary);
-            data.EnsureBufferCount(2);
-        }
-
-        public FixedSizeBinaryArray(ArrowTypeId typeId, ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(typeId);
-            data.EnsureBufferCount(2);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public ArrowBuffer ValueBuffer => Data.Buffers[1];
-
-        /// <summary>
-        /// Get the collection of bytes, as a read-only span, at a given index in the array.
-        /// </summary>
-        /// <remarks>
-        /// Note that this method cannot reliably identify null values, which are indistinguishable from empty byte
-        /// collection values when seen in the context of this method's return type of <see cref="ReadOnlySpan{Byte}"/>.
-        /// Use the <see cref="Array.IsNull"/> method instead to reliably determine null values.
-        /// </remarks>
-        /// <param name="index">Index at which to get bytes.</param>
-        /// <returns>Returns a <see cref="ReadOnlySpan{Byte}"/> object.</returns>
-        /// <exception cref="ArgumentOutOfRangeException">If the index is negative or beyond the length of the array.
-        /// </exception>
-        public ReadOnlySpan<byte> GetBytes(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            if (IsNull(index))
-            {
-                // Note that `return null;` is valid syntax, but would be misleading as `null` in the context of a span
-                // is actually returned as an empty span.
-                return ReadOnlySpan<byte>.Empty;
-            }
-
-            int size = ((FixedSizeBinaryType)Data.DataType).ByteWidth;
-            return ValueBuffer.Span.Slice((Offset + index) * size, size);
-        }
-
-        int IReadOnlyCollection<byte[]>.Count => Length;
-        byte[] IReadOnlyList<byte[]>.this[int index] => GetBytes(index).ToArray();
-
-        IEnumerator<byte[]> IEnumerable<byte[]>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetBytes(index).ToArray();
-            }
-        }
-
-        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<byte[]>)this).GetEnumerator();
-
-        public abstract class BuilderBase<TArray, TBuilder> : IArrowArrayBuilder<byte[], TArray, TBuilder>
-            where TArray : IArrowArray
-            where TBuilder : class, IArrowArrayBuilder<byte[], TArray, TBuilder>
-        {
-            protected IArrowType DataType { get; }
-            protected TBuilder Instance => this as TBuilder;
-            protected int ByteWidth { get; }
-            protected ArrowBuffer.Builder<byte> ValueBuffer { get; }
-            protected ArrowBuffer.BitmapBuilder ValidityBuffer { get; }
-            public int Length => ValueBuffer.Length / ByteWidth;
-            protected int NullCount => this.ValidityBuffer.UnsetBitCount;
-            protected abstract TArray Build(ArrayData data);
-
-            protected BuilderBase(IArrowType dataType, int byteWidth)
-            {
-                DataType = dataType;
-                ByteWidth = byteWidth;
-                ValueBuffer = new ArrowBuffer.Builder<byte>();
-                ValidityBuffer = new ArrowBuffer.BitmapBuilder();
-            }
-
-            public TArray Build(MemoryAllocator allocator = default)
-            {
-                var bufs = new[]
-                {
-                    NullCount > 0 ? ValidityBuffer.Build(allocator) : ArrowBuffer.Empty,
-                    ValueBuffer.Build(ByteWidth, allocator),
-                };
-                var data = new ArrayData(
-                    DataType,
-                    Length,
-                    NullCount,
-                    0,
-                    bufs);
-
-                return Build(data);
-            }
-
-            public TBuilder Reserve(int capacity)
-            {
-                ValueBuffer.Reserve(capacity * ByteWidth);
-                ValidityBuffer.Reserve(capacity);
-                return Instance;
-            }
-
-            public TBuilder Resize(int length)
-            {
-                ValueBuffer.Resize(length * ByteWidth);
-                ValidityBuffer.Resize(length);
-                return Instance;
-            }
-
-            public TBuilder Clear() {
-
-                ValueBuffer.Clear();
-                ValidityBuffer.Clear();
-
-                return Instance;
-            }
-
-            public TBuilder Append(byte[] value)
-            {
-                if(value.Length % ByteWidth != 0)
-                    throw new ArgumentOutOfRangeException("Bytes of length: " + value.Length + " do not conform to the fixed size: " + ByteWidth);
-                return Append(value.AsSpan());
-            }
-            public TBuilder Append(ReadOnlySpan<byte[]> span)
-            {
-                foreach (var b in span)
-                {
-                    Append(b);
-                }
-
-                return Instance;
-            }
-
-            public TBuilder AppendRange(IEnumerable<byte[]> values)
-            {
-                if (values == null)
-                {
-                    throw new ArgumentNullException(nameof(values));
-                }
-
-                foreach (byte[] b in values)
-                {
-                    Append(b);
-                }
-
-                return Instance;
-            }
-
-            public TBuilder Append(ReadOnlySpan<byte> span)
-            {
-                ValueBuffer.Append(span);
-                ValidityBuffer.Append(true);
-                return Instance;
-            }
-
-            public TBuilder AppendNull()
-            {
-                ValueBuffer.Append(new byte[ByteWidth]);
-                ValidityBuffer.Append(false);
-                return Instance;
-            }
-
-            public TBuilder Swap(int i, int j)
-            {
-                int iStart = i * ByteWidth;
-                int jStart = j * ByteWidth;
-                byte[] iBytes = ValueBuffer.Span.Slice(iStart, ByteWidth).ToArray();
-                Span<byte> jBytes = ValueBuffer.Span.Slice(jStart, ByteWidth);
-
-                for (int m = 0; m < ByteWidth; m++)
-                {
-                    ValueBuffer.Span[iStart + m] = jBytes[m];
-                    ValueBuffer.Span[jStart + m] = iBytes[m];
-                }
-
-                ValidityBuffer.Swap(i, j);
-                return Instance;
-            }
-
-            public TBuilder Set(int index, byte[] value)
-            {
-                return Set(index, value.AsSpan());
-            }
-
-            public TBuilder Set(int index, ReadOnlySpan<byte> value)
-            {
-                int startIndex = index * ByteWidth;
-                for (int i = 0; i < ByteWidth; i++)
-                {
-                    ValueBuffer.Span[startIndex + i] = value[i];
-                }
-
-                ValidityBuffer.Set(index, true);
-                return Instance;
-            }
-
-            public TBuilder SetNull(int index)
-            {
-                int startIndex = index * ByteWidth;
-                for (int i = 0; i < ByteWidth; i++)
-                {
-                    ValueBuffer.Span[startIndex + i] = 0;
-                }
-
-                ValidityBuffer.Set(index, false);
-                return Instance;
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/FixedSizeListArray.cs b/csharp/src/Apache.Arrow/Arrays/FixedSizeListArray.cs
deleted file mode 100644
index f60daed..0000000
--- a/csharp/src/Apache.Arrow/Arrays/FixedSizeListArray.cs
+++ /dev/null
@@ -1,190 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class FixedSizeListArray : Array
-    {
-        public class Builder : IArrowArrayBuilder<FixedSizeListArray, Builder>
-        {
-            public IArrowArrayBuilder<IArrowArray, IArrowArrayBuilder<IArrowArray>> ValueBuilder { get; }
-
-            public int Length { get; protected set; }
-
-            private ArrowBuffer.BitmapBuilder ValidityBufferBuilder { get; }
-
-            public int NullCount => ValidityBufferBuilder.UnsetBitCount;
-
-            private FixedSizeListType DataType { get; }
-
-            private int ExpectedValueLength => Length * DataType.ListSize;
-
-            public Builder(IArrowType valueDataType, int listSize) : this(new FixedSizeListType(valueDataType, listSize))
-            {
-            }
-
-            public Builder(Field valueField, int listSize) : this(new FixedSizeListType(valueField, listSize))
-            {
-            }
-
-            internal Builder(FixedSizeListType dataType)
-            {
-                ValueBuilder = ArrowArrayBuilderFactory.Build(dataType.ValueDataType);
-                ValidityBufferBuilder = new ArrowBuffer.BitmapBuilder();
-                DataType = dataType;
-            }
-
-            /// <summary>
-            /// Start a new fixed-length list slot
-            ///
-            /// This function should be called before beginning to append elements to the
-            /// value builder
-            /// </summary>
-            /// <returns></returns>
-            public Builder Append()
-            {
-                ValidateChildLength();
-
-                ValidityBufferBuilder.Append(true);
-                Length++;
-
-                return this;
-            }
-
-            public Builder AppendNull()
-            {
-                ValidateChildLength();
-
-                ValidityBufferBuilder.Append(false);
-                for (int i = 0; i < DataType.ListSize; i++)
-                {
-                    ValueBuilder.AppendNull();
-                }
-                Length++;
-
-                return this;
-            }
-
-            public FixedSizeListArray Build(MemoryAllocator allocator = default)
-            {
-                ValidateChildLength();
-
-                int nullCount = NullCount;
-                ArrowBuffer validityBuffer = nullCount > 0
-                                        ? ValidityBufferBuilder.Build(allocator)
-                                        : ArrowBuffer.Empty;
-
-                return new FixedSizeListArray(DataType, Length,
-                    ValueBuilder.Build(allocator),
-                    validityBuffer, nullCount, 0);
-            }
-
-            public Builder Reserve(int capacity)
-            {
-                ValidityBufferBuilder.Reserve(capacity);
-                ValueBuilder.Reserve(DataType.ListSize * capacity);
-                return this;
-            }
-
-            public Builder Resize(int length)
-            {
-                ValidateChildLength();
-
-                ValidityBufferBuilder.Resize(length);
-                ValueBuilder.Resize(DataType.ListSize * length);
-                Length = length;
-                return this;
-            }
-
-            public Builder Clear()
-            {
-                ValueBuilder.Clear();
-                ValidityBufferBuilder.Clear();
-                Length = 0;
-                return this;
-            }
-
-            void ValidateChildLength()
-            {
-                if (ValueBuilder.Length != ExpectedValueLength)
-                {
-                    int actualLength = ValueBuilder.Length - ExpectedValueLength + DataType.ListSize;
-                    throw new ArgumentOutOfRangeException($"Lists of length: {actualLength} do not conform to the fixed size: " + DataType.ListSize);
-                }
-            }
-        }
-
-        public IArrowArray Values { get; }
-
-        public FixedSizeListArray(IArrowType dataType, int length,
-            IArrowArray values, ArrowBuffer nullBitmapBuffer,
-            int nullCount = 0, int offset = 0)
-            : this(new ArrayData(dataType, length, nullCount, offset,
-                new[] { nullBitmapBuffer }, new[] { values.Data }),
-                values)
-        {
-        }
-
-        public FixedSizeListArray(ArrayData data)
-            : this(data, ArrowArrayFactory.BuildArray(data.Children[0]))
-        {
-        }
-
-        private FixedSizeListArray(ArrayData data, IArrowArray values) : base(data)
-        {
-            data.EnsureBufferCount(1);
-            data.EnsureDataType(ArrowTypeId.FixedSizeList);
-            Values = values;
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public IArrowArray GetSlicedValues(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            if (IsNull(index))
-            {
-                return null;
-            }
-
-            if (!(Values is Array array))
-            {
-                return default;
-            }
-
-            index += Data.Offset;
-
-            int length = ((FixedSizeListType)Data.DataType).ListSize;
-            return array.Slice(index * length, length);
-        }
-
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                Values?.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/FloatArray.cs b/csharp/src/Apache.Arrow/Arrays/FloatArray.cs
deleted file mode 100644
index 8feca32..0000000
--- a/csharp/src/Apache.Arrow/Arrays/FloatArray.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class FloatArray : PrimitiveArray<float>
-    {
-        public class Builder : PrimitiveArrayBuilder<float, FloatArray, Builder>
-        {
-            protected override FloatArray Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new FloatArray(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public FloatArray(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(FloatType.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public FloatArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Float);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/HalfFloatArray.cs b/csharp/src/Apache.Arrow/Arrays/HalfFloatArray.cs
deleted file mode 100644
index 072629e..0000000
--- a/csharp/src/Apache.Arrow/Arrays/HalfFloatArray.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-
-namespace Apache.Arrow
-{
-    public class HalfFloatArray : PrimitiveArray<Half>
-    {
-        public class Builder : PrimitiveArrayBuilder<Half, HalfFloatArray, Builder>
-        {
-            protected override HalfFloatArray Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new HalfFloatArray(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public HalfFloatArray(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(HalfFloatType.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public HalfFloatArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.HalfFloat);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Int16Array.cs b/csharp/src/Apache.Arrow/Arrays/Int16Array.cs
deleted file mode 100644
index 0401865..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Int16Array.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class Int16Array : PrimitiveArray<short>
-    {
-        public class Builder : PrimitiveArrayBuilder<short, Int16Array, Builder>
-        {
-            protected override Int16Array Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer, 
-                int length, int nullCount, int offset) =>
-                new Int16Array(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public Int16Array(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(Int16Type.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public Int16Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Int16);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Int32Array.cs b/csharp/src/Apache.Arrow/Arrays/Int32Array.cs
deleted file mode 100644
index ef356c7..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Int32Array.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class Int32Array : PrimitiveArray<int>
-    {
-        public class Builder : PrimitiveArrayBuilder<int, Int32Array, Builder>
-        {
-            protected override Int32Array Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new Int32Array(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public Int32Array(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(Int32Type.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public Int32Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Int32);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Int64Array.cs b/csharp/src/Apache.Arrow/Arrays/Int64Array.cs
deleted file mode 100644
index fe8fbc6..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Int64Array.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class Int64Array : PrimitiveArray<long>
-    {
-        public class Builder : PrimitiveArrayBuilder<long, Int64Array, Builder>
-        {
-            protected override Int64Array Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new Int64Array(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public Int64Array(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(Int64Type.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public Int64Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Int64);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Int8Array.cs b/csharp/src/Apache.Arrow/Arrays/Int8Array.cs
deleted file mode 100644
index 58d543a..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Int8Array.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class Int8Array : PrimitiveArray<sbyte>
-    {
-        public class Builder : PrimitiveArrayBuilder<sbyte, Int8Array, Builder>
-        {
-            protected override Int8Array Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new Int8Array(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public Int8Array(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(Int8Type.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public Int8Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Int8);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/IntervalArray.cs b/csharp/src/Apache.Arrow/Arrays/IntervalArray.cs
deleted file mode 100644
index 3949af8..0000000
--- a/csharp/src/Apache.Arrow/Arrays/IntervalArray.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Scalars;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    internal static class IntervalArray
-    {
-        internal static IArrowArray Create(ArrayData data) => ((IntervalType)data.DataType).Unit switch
-        {
-            IntervalUnit.YearMonth => new YearMonthIntervalArray(data),
-            IntervalUnit.DayTime => new DayTimeIntervalArray(data),
-            IntervalUnit.MonthDayNanosecond => new MonthDayNanosecondIntervalArray(data),
-            _ => throw new InvalidOperationException($"Unsupported interval unit {((IntervalType)data.DataType).Unit}"),
-        };
-    }
-
-    public abstract class IntervalArray<T> : PrimitiveArray<T>
-        where T : struct, IEquatable<T>
-    {
-        protected IntervalArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureBufferCount(2);
-            data.EnsureDataType(ArrowTypeId.Interval);
-        }
-
-        public IntervalType Type => (IntervalType)Data.DataType;
-
-        public IntervalUnit Unit => Type.Unit;
-
-        internal static IArrowArray Create(ArrayData data) => ((IntervalType)data.DataType).Unit switch
-        {
-            IntervalUnit.YearMonth => new YearMonthIntervalArray(data),
-            IntervalUnit.DayTime => new DayTimeIntervalArray(data),
-            IntervalUnit.MonthDayNanosecond => new MonthDayNanosecondIntervalArray(data),
-            _ => throw new InvalidOperationException($"Unsupported interval unit {((IntervalType)data.DataType).Unit}"),
-        };
-
-        internal static void ValidateUnit(IntervalUnit expected, IntervalUnit actual)
-        {
-            if (expected != actual)
-            {
-                throw new ArgumentException(
-                    $"Specified interval unit <{actual}> does not match expected unit <{expected}>",
-                    "Unit");
-            }
-        }
-    }
-
-    public sealed class YearMonthIntervalArray : IntervalArray<YearMonthInterval>
-    {
-        public class Builder : PrimitiveArrayBuilder<YearMonthInterval, YearMonthIntervalArray, Builder>
-        {
-            protected override YearMonthIntervalArray Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new YearMonthIntervalArray(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public YearMonthIntervalArray(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(IntervalType.YearMonth, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public YearMonthIntervalArray(ArrayData data) : base(data)
-        {
-            ValidateUnit(IntervalUnit.YearMonth, Unit);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-    }
-
-    public sealed class DayTimeIntervalArray : IntervalArray<DayTimeInterval>
-    {
-        public class Builder : PrimitiveArrayBuilder<DayTimeInterval, DayTimeIntervalArray, Builder>
-        {
-            protected override DayTimeIntervalArray Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new DayTimeIntervalArray(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public DayTimeIntervalArray(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(IntervalType.DayTime, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public DayTimeIntervalArray(ArrayData data) : base(data)
-        {
-            ValidateUnit(IntervalUnit.DayTime, Unit);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-    }
-
-    public sealed class MonthDayNanosecondIntervalArray : IntervalArray<MonthDayNanosecondInterval>
-    {
-        public class Builder : PrimitiveArrayBuilder<MonthDayNanosecondInterval, MonthDayNanosecondIntervalArray, Builder>
-        {
-            protected override MonthDayNanosecondIntervalArray Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new MonthDayNanosecondIntervalArray(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public MonthDayNanosecondIntervalArray(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(IntervalType.MonthDayNanosecond, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public MonthDayNanosecondIntervalArray(ArrayData data) : base(data)
-        {
-            ValidateUnit(IntervalUnit.MonthDayNanosecond, Unit);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/LargeBinaryArray.cs b/csharp/src/Apache.Arrow/Arrays/LargeBinaryArray.cs
deleted file mode 100644
index 9eddbed..0000000
--- a/csharp/src/Apache.Arrow/Arrays/LargeBinaryArray.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-
-namespace Apache.Arrow;
-
-public class LargeBinaryArray : Array, IReadOnlyList<byte[]>, ICollection<byte[]>
-{
-    public LargeBinaryArray(ArrayData data)
-        : base(data)
-    {
-        data.EnsureDataType(ArrowTypeId.LargeBinary);
-        data.EnsureBufferCount(3);
-    }
-
-    public LargeBinaryArray(ArrowTypeId typeId, ArrayData data)
-        : base(data)
-    {
-        data.EnsureDataType(typeId);
-        data.EnsureBufferCount(3);
-    }
-
-    public LargeBinaryArray(IArrowType dataType, int length,
-        ArrowBuffer valueOffsetsBuffer,
-        ArrowBuffer dataBuffer,
-        ArrowBuffer nullBitmapBuffer,
-        int nullCount = 0, int offset = 0)
-    : this(new ArrayData(dataType, length, nullCount, offset,
-        new[] { nullBitmapBuffer, valueOffsetsBuffer, dataBuffer }))
-    { }
-
-    public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-    public ArrowBuffer ValueOffsetsBuffer => Data.Buffers[1];
-
-    public ArrowBuffer ValueBuffer => Data.Buffers[2];
-
-    public ReadOnlySpan<long> ValueOffsets => ValueOffsetsBuffer.Span.CastTo<long>().Slice(Offset, Length + 1);
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    public int GetValueLength(int index)
-    {
-        if (index < 0 || index >= Length)
-        {
-            throw new ArgumentOutOfRangeException(nameof(index));
-        }
-        if (!IsValid(index))
-        {
-            return 0;
-        }
-
-        ReadOnlySpan<long> offsets = ValueOffsets;
-        return checked((int)(offsets[index + 1] - offsets[index]));
-    }
-
-    /// <summary>
-    /// Get the collection of bytes, as a read-only span, at a given index in the array.
-    /// </summary>
-    /// <remarks>
-    /// Note that this method cannot reliably identify null values, which are indistinguishable from empty byte
-    /// collection values when seen in the context of this method's return type of <see cref="ReadOnlySpan{Byte}"/>.
-    /// Use the <see cref="Array.IsNull"/> method or the <see cref="GetBytes(int, out bool)"/> overload instead
-    /// to reliably determine null values.
-    /// </remarks>
-    /// <param name="index">Index at which to get bytes.</param>
-    /// <returns>Returns a <see cref="ReadOnlySpan{Byte}"/> object.</returns>
-    /// <exception cref="ArgumentOutOfRangeException">If the index is negative or beyond the length of the array.
-    /// </exception>
-    public ReadOnlySpan<byte> GetBytes(int index) => GetBytes(index, out _);
-
-    /// <summary>
-    /// Get the collection of bytes, as a read-only span, at a given index in the array.
-    /// </summary>
-    /// <param name="index">Index at which to get bytes.</param>
-    /// <param name="isNull">Set to <see langword="true"/> if the value at the given index is null.</param>
-    /// <returns>Returns a <see cref="ReadOnlySpan{Byte}"/> object.</returns>
-    /// <exception cref="ArgumentOutOfRangeException">If the index is negative or beyond the length of the array.
-    /// </exception>
-    public ReadOnlySpan<byte> GetBytes(int index, out bool isNull)
-    {
-        if (index < 0 || index >= Length)
-        {
-            throw new ArgumentOutOfRangeException(nameof(index));
-        }
-
-        isNull = IsNull(index);
-
-        if (isNull)
-        {
-            // Note that `return null;` is valid syntax, but would be misleading as `null` in the context of a span
-            // is actually returned as an empty span.
-            return ReadOnlySpan<byte>.Empty;
-        }
-
-        var offset = checked((int)ValueOffsets[index]);
-        return ValueBuffer.Span.Slice(offset, GetValueLength(index));
-    }
-
-    int IReadOnlyCollection<byte[]>.Count => Length;
-
-    byte[] IReadOnlyList<byte[]>.this[int index] => GetBytes(index).ToArray();
-
-    IEnumerator<byte[]> IEnumerable<byte[]>.GetEnumerator()
-    {
-        for (int index = 0; index < Length; index++)
-        {
-            yield return GetBytes(index).ToArray();
-        }
-    }
-
-    IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<byte[]>)this).GetEnumerator();
-
-    int ICollection<byte[]>.Count => Length;
-    bool ICollection<byte[]>.IsReadOnly => true;
-    void ICollection<byte[]>.Add(byte[] item) => throw new NotSupportedException("Collection is read-only.");
-    bool ICollection<byte[]>.Remove(byte[] item) => throw new NotSupportedException("Collection is read-only.");
-    void ICollection<byte[]>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-    bool ICollection<byte[]>.Contains(byte[] item)
-    {
-        for (int index = 0; index < Length; index++)
-        {
-            if (GetBytes(index).SequenceEqual(item))
-                return true;
-        }
-
-        return false;
-    }
-
-    void ICollection<byte[]>.CopyTo(byte[][] array, int arrayIndex)
-    {
-        for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-        {
-            array[destIndex] = GetBytes(srcIndex).ToArray();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/LargeListArray.cs b/csharp/src/Apache.Arrow/Arrays/LargeListArray.cs
deleted file mode 100644
index 6e37aa4..0000000
--- a/csharp/src/Apache.Arrow/Arrays/LargeListArray.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class LargeListArray : Array
-    {
-        public IArrowArray Values { get; }
-
-        public ArrowBuffer ValueOffsetsBuffer => Data.Buffers[1];
-
-        public ReadOnlySpan<long> ValueOffsets => ValueOffsetsBuffer.Span.CastTo<long>().Slice(Offset, Length + 1);
-
-        public LargeListArray(IArrowType dataType, int length,
-            ArrowBuffer valueOffsetsBuffer, IArrowArray values,
-            ArrowBuffer nullBitmapBuffer, int nullCount = 0, int offset = 0)
-            : this(new ArrayData(dataType, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueOffsetsBuffer }, new[] { values.Data }),
-                values)
-        {
-        }
-
-        public LargeListArray(ArrayData data)
-            : this(data, ArrowArrayFactory.BuildArray(data.Children[0]))
-        {
-        }
-
-        private LargeListArray(ArrayData data, IArrowArray values) : base(data)
-        {
-            data.EnsureBufferCount(2);
-            data.EnsureDataType(ArrowTypeId.LargeList);
-            Values = values;
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public int GetValueLength(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            if (IsNull(index))
-            {
-                return 0;
-            }
-
-            ReadOnlySpan<long> offsets = ValueOffsets;
-            return checked((int)(offsets[index + 1] - offsets[index]));
-        }
-
-        public IArrowArray GetSlicedValues(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            if (IsNull(index))
-            {
-                return null;
-            }
-
-            if (!(Values is Array array))
-            {
-                return default;
-            }
-
-            return array.Slice(checked((int)ValueOffsets[index]), GetValueLength(index));
-        }
-
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                Values?.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/LargeStringArray.cs b/csharp/src/Apache.Arrow/Arrays/LargeStringArray.cs
deleted file mode 100644
index 2a65b82..0000000
--- a/csharp/src/Apache.Arrow/Arrays/LargeStringArray.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Text;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow;
-
-public class LargeStringArray: LargeBinaryArray, IReadOnlyList<string>, ICollection<string>
-{
-    public static readonly Encoding DefaultEncoding = StringArray.DefaultEncoding;
-
-    public LargeStringArray(ArrayData data)
-        : base(ArrowTypeId.LargeString, data) { }
-
-    public LargeStringArray(int length,
-        ArrowBuffer valueOffsetsBuffer,
-        ArrowBuffer dataBuffer,
-        ArrowBuffer nullBitmapBuffer,
-        int nullCount = 0, int offset = 0)
-        : this(new ArrayData(LargeStringType.Default, length, nullCount, offset,
-            new[] { nullBitmapBuffer, valueOffsetsBuffer, dataBuffer }))
-    { }
-
-    public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-    /// <summary>
-    /// Get the string value at the given index
-    /// </summary>
-    /// <param name="index">Input index</param>
-    /// <param name="encoding">Optional: the string encoding, default is UTF8</param>
-    /// <returns>The string object at the given index</returns>
-    public string GetString(int index, Encoding encoding = default)
-    {
-        encoding ??= DefaultEncoding;
-
-        ReadOnlySpan<byte> bytes = GetBytes(index, out bool isNull);
-
-        if (isNull)
-        {
-            return null;
-        }
-
-        if (bytes.Length == 0)
-        {
-            return string.Empty;
-        }
-
-        unsafe
-        {
-            fixed (byte* data = &MemoryMarshal.GetReference(bytes))
-            {
-                return encoding.GetString(data, bytes.Length);
-            }
-        }
-    }
-
-
-    int IReadOnlyCollection<string>.Count => Length;
-
-    string IReadOnlyList<string>.this[int index] => GetString(index);
-
-    IEnumerator<string> IEnumerable<string>.GetEnumerator()
-    {
-        for (int index = 0; index < Length; index++)
-        {
-            yield return GetString(index);
-        };
-    }
-
-    IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<string>)this).GetEnumerator();
-
-    int ICollection<string>.Count => Length;
-    bool ICollection<string>.IsReadOnly => true;
-    void ICollection<string>.Add(string item) => throw new NotSupportedException("Collection is read-only.");
-    bool ICollection<string>.Remove(string item) => throw new NotSupportedException("Collection is read-only.");
-    void ICollection<string>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-    bool ICollection<string>.Contains(string item)
-    {
-        for (int index = 0; index < Length; index++)
-        {
-            if (GetString(index) == item)
-                return true;
-        }
-
-        return false;
-    }
-
-    void ICollection<string>.CopyTo(string[] array, int arrayIndex)
-    {
-        for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-        {
-            array[destIndex] = GetString(srcIndex);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/ListArray.cs b/csharp/src/Apache.Arrow/Arrays/ListArray.cs
deleted file mode 100644
index 4d2ff96..0000000
--- a/csharp/src/Apache.Arrow/Arrays/ListArray.cs
+++ /dev/null
@@ -1,208 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class ListArray : Array
-    {
-        public class Builder : IArrowArrayBuilder<ListArray, Builder>
-        {
-            public IArrowArrayBuilder<IArrowArray, IArrowArrayBuilder<IArrowArray>> ValueBuilder { get; }
-
-            public int Length => ValueOffsetsBufferBuilder.Length;
-
-            private ArrowBuffer.Builder<int> ValueOffsetsBufferBuilder { get; }
-
-            private ArrowBuffer.BitmapBuilder ValidityBufferBuilder { get; }
-
-            public int NullCount { get; protected set; }
-
-            private IArrowType DataType { get; }
-
-            public Builder(IArrowType valueDataType) : this(new ListType(valueDataType))
-            {
-            }
-
-            public Builder(Field valueField) : this(new ListType(valueField))
-            {
-            }
-
-            internal Builder(ListType dataType)
-            {
-                ValueBuilder = ArrowArrayBuilderFactory.Build(dataType.ValueDataType);
-                ValueOffsetsBufferBuilder = new ArrowBuffer.Builder<int>();
-                ValidityBufferBuilder = new ArrowBuffer.BitmapBuilder();
-                DataType = dataType;
-            }
-
-            /// <summary>
-            /// Start a new variable-length list slot
-            ///
-            /// This function should be called before beginning to append elements to the
-            /// value builder
-            /// </summary>
-            /// <returns></returns>
-            public Builder Append()
-            {
-                ValueOffsetsBufferBuilder.Append(ValueBuilder.Length);
-                ValidityBufferBuilder.Append(true);
-
-                return this;
-            }
-
-            public Builder AppendNull()
-            {
-                ValueOffsetsBufferBuilder.Append(ValueBuilder.Length);
-                ValidityBufferBuilder.Append(false);
-                NullCount++;
-
-                return this;
-            }
-
-            public ListArray Build(MemoryAllocator allocator = default)
-            {
-                ValueOffsetsBufferBuilder.Append(ValueBuilder.Length);
-
-                ArrowBuffer validityBuffer = NullCount > 0
-                                        ? ValidityBufferBuilder.Build(allocator)
-                                        : ArrowBuffer.Empty;
-
-                return new ListArray(DataType, Length - 1,
-                    ValueOffsetsBufferBuilder.Build(allocator), ValueBuilder.Build(allocator),
-                    validityBuffer, NullCount, 0);
-            }
-
-            public Builder Reserve(int capacity)
-            {
-                ValueOffsetsBufferBuilder.Reserve(capacity + 1);
-                ValidityBufferBuilder.Reserve(capacity);
-                return this;
-            }
-
-            public Builder Resize(int length)
-            {
-                ValueOffsetsBufferBuilder.Resize(length + 1);
-                ValidityBufferBuilder.Resize(length);
-                return this;
-            }
-
-            public Builder Clear()
-            {
-                ValueOffsetsBufferBuilder.Clear();
-                ValueBuilder.Clear();
-                ValidityBufferBuilder.Clear();
-                return this;
-            }
-
-        }
-
-        public IArrowArray Values { get; }
-
-        public ArrowBuffer ValueOffsetsBuffer => Data.Buffers[1];
-
-        public ReadOnlySpan<int> ValueOffsets => ValueOffsetsBuffer.Span.CastTo<int>().Slice(Offset, Length + 1);
-
-        public ListArray(IArrowType dataType, int length,
-            ArrowBuffer valueOffsetsBuffer, IArrowArray values,
-            ArrowBuffer nullBitmapBuffer, int nullCount = 0, int offset = 0)
-            : this(new ArrayData(dataType, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueOffsetsBuffer }, new[] { values.Data }),
-                values)
-        {
-        }
-
-        public ListArray(ArrayData data)
-            : this(data, ArrowArrayFactory.BuildArray(data.Children[0]))
-        {
-        }
-
-        private ListArray(ArrayData data, IArrowArray values) : base(data)
-        {
-            data.EnsureBufferCount(2);
-            data.EnsureDataType(ArrowTypeId.List);
-            Values = values;
-        }
-
-        // Constructor for child MapArray
-        internal ListArray(ArrayData data, IArrowArray values, ArrowTypeId typeId) : base(data)
-        {
-            data.EnsureBufferCount(2);
-            data.EnsureDataType(typeId);
-            Values = values;
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-
-        [Obsolete("This method has been deprecated. Please use ValueOffsets[index] instead.")]
-        public int GetValueOffset(int index)
-        {
-            if (index < 0 || index > Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-            return ValueOffsets[index];
-        }
-
-        public int GetValueLength(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            if (IsNull(index))
-            {
-                return 0;
-            }
-
-            ReadOnlySpan<int> offsets = ValueOffsets;
-            return offsets[index + 1] - offsets[index];
-        }
-
-        public IArrowArray GetSlicedValues(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            if (IsNull(index))
-            {
-                return null;
-            }
-
-            if (!(Values is Array array))
-            {
-                return default;
-            }
-
-            return array.Slice(ValueOffsets[index], GetValueLength(index));
-        }
-
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                Values?.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/ListViewArray.cs b/csharp/src/Apache.Arrow/Arrays/ListViewArray.cs
deleted file mode 100644
index 081385d..0000000
--- a/csharp/src/Apache.Arrow/Arrays/ListViewArray.cs
+++ /dev/null
@@ -1,217 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class ListViewArray : Array
-    {
-        public class Builder : IArrowArrayBuilder<ListViewArray, Builder>
-        {
-            public IArrowArrayBuilder<IArrowArray, IArrowArrayBuilder<IArrowArray>> ValueBuilder { get; }
-
-            public int Length => ValueOffsetsBufferBuilder.Length;
-
-            private ArrowBuffer.Builder<int> ValueOffsetsBufferBuilder { get; }
-
-            private ArrowBuffer.Builder<int> SizesBufferBuilder { get; }
-
-            private ArrowBuffer.BitmapBuilder ValidityBufferBuilder { get; }
-
-            public int NullCount { get; protected set; }
-
-            private IArrowType DataType { get; }
-
-            private int Start { get; set; }
-
-            public Builder(IArrowType valueDataType) : this(new ListViewType(valueDataType))
-            {
-            }
-
-            public Builder(Field valueField) : this(new ListViewType(valueField))
-            {
-            }
-
-            internal Builder(ListViewType dataType)
-            {
-                ValueBuilder = ArrowArrayBuilderFactory.Build(dataType.ValueDataType);
-                ValueOffsetsBufferBuilder = new ArrowBuffer.Builder<int>();
-                SizesBufferBuilder = new ArrowBuffer.Builder<int>();
-                ValidityBufferBuilder = new ArrowBuffer.BitmapBuilder();
-                DataType = dataType;
-                Start = -1;
-            }
-
-            /// <summary>
-            /// Start a new variable-length list slot
-            ///
-            /// This function should be called before beginning to append elements to the
-            /// value builder. TODO: Consider adding builder APIs to support construction
-            /// of overlapping lists.
-            /// </summary>
-            public Builder Append()
-            {
-                AppendPrevious();
-
-                ValidityBufferBuilder.Append(true);
-
-                return this;
-            }
-
-            public Builder AppendNull()
-            {
-                AppendPrevious();
-
-                ValidityBufferBuilder.Append(false);
-                ValueOffsetsBufferBuilder.Append(Start);
-                SizesBufferBuilder.Append(0);
-                NullCount++;
-                Start = -1;
-
-                return this;
-            }
-
-            private void AppendPrevious()
-            {
-                if (Start >= 0)
-                {
-                    ValueOffsetsBufferBuilder.Append(Start);
-                    SizesBufferBuilder.Append(ValueBuilder.Length - Start);
-                }
-                Start = ValueBuilder.Length;
-            }
-
-            public ListViewArray Build(MemoryAllocator allocator = default)
-            {
-                AppendPrevious();
-
-                ArrowBuffer validityBuffer = NullCount > 0
-                                        ? ValidityBufferBuilder.Build(allocator)
-                                        : ArrowBuffer.Empty;
-
-                return new ListViewArray(DataType, Length,
-                    ValueOffsetsBufferBuilder.Build(allocator), SizesBufferBuilder.Build(allocator),
-                    ValueBuilder.Build(allocator),
-                    validityBuffer, NullCount, 0);
-            }
-
-            public Builder Reserve(int capacity)
-            {
-                ValueOffsetsBufferBuilder.Reserve(capacity);
-                SizesBufferBuilder.Reserve(capacity);
-                ValidityBufferBuilder.Reserve(capacity);
-                return this;
-            }
-
-            public Builder Resize(int length)
-            {
-                ValueOffsetsBufferBuilder.Resize(length);
-                SizesBufferBuilder.Resize(length);
-                ValidityBufferBuilder.Resize(length);
-                return this;
-            }
-
-            public Builder Clear()
-            {
-                ValueOffsetsBufferBuilder.Clear();
-                SizesBufferBuilder.Clear();
-                ValueBuilder.Clear();
-                ValidityBufferBuilder.Clear();
-                return this;
-            }
-
-        }
-
-        public IArrowArray Values { get; }
-
-        public ArrowBuffer ValueOffsetsBuffer => Data.Buffers[1];
-
-        public ReadOnlySpan<int> ValueOffsets => ValueOffsetsBuffer.Span.CastTo<int>().Slice(Offset, Length);
-
-        public ArrowBuffer SizesBuffer => Data.Buffers[2];
-
-        public ReadOnlySpan<int> Sizes => SizesBuffer.Span.CastTo<int>().Slice(Offset, Length);
-
-        public ListViewArray(IArrowType dataType, int length,
-            ArrowBuffer valueOffsetsBuffer, ArrowBuffer sizesBuffer, IArrowArray values,
-            ArrowBuffer nullBitmapBuffer, int nullCount = 0, int offset = 0)
-            : this(new ArrayData(dataType, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueOffsetsBuffer, sizesBuffer }, new[] { values.Data }),
-                values)
-        {
-        }
-
-        public ListViewArray(ArrayData data)
-            : this(data, ArrowArrayFactory.BuildArray(data.Children[0]))
-        {
-        }
-
-        private ListViewArray(ArrayData data, IArrowArray values) : base(data)
-        {
-            data.EnsureBufferCount(3);
-            data.EnsureDataType(ArrowTypeId.ListView);
-            Values = values;
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public int GetValueLength(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            if (IsNull(index))
-            {
-                return 0;
-            }
-
-            return Sizes[index];
-        }
-
-        public IArrowArray GetSlicedValues(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            if (IsNull(index))
-            {
-                return null;
-            }
-
-            if (!(Values is Array array))
-            {
-                return default;
-            }
-
-            return array.Slice(ValueOffsets[index], GetValueLength(index));
-        }
-
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                Values?.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/MapArray.cs b/csharp/src/Apache.Arrow/Arrays/MapArray.cs
deleted file mode 100644
index c1dc968..0000000
--- a/csharp/src/Apache.Arrow/Arrays/MapArray.cs
+++ /dev/null
@@ -1,185 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class MapArray : ListArray // MapArray = ListArray(StructArray("key", "value")) 
-    {
-        // Same as ListArray.Builder, but with KeyBuilder
-        public new class Builder : IArrowArrayBuilder<MapArray, Builder>
-        {
-            public IArrowArrayBuilder<IArrowArray, IArrowArrayBuilder<IArrowArray>> KeyBuilder { get; }
-            public IArrowArrayBuilder<IArrowArray, IArrowArrayBuilder<IArrowArray>> ValueBuilder { get; }
-
-            public int Length => ValueOffsetsBufferBuilder.Length;
-
-            private ArrowBuffer.Builder<int> ValueOffsetsBufferBuilder { get; }
-
-            private ArrowBuffer.BitmapBuilder ValidityBufferBuilder { get; }
-
-            public int NullCount { get; protected set; }
-
-            public MapType DataType { get; }
-
-            public Builder(MapType type)
-            {
-                KeyBuilder = ArrowArrayBuilderFactory.Build(type.KeyField.DataType);
-                ValueBuilder = ArrowArrayBuilderFactory.Build(type.ValueField.DataType);
-                ValueOffsetsBufferBuilder = new ArrowBuffer.Builder<int>();
-                ValidityBufferBuilder = new ArrowBuffer.BitmapBuilder();
-                DataType = type;
-            }
-
-            /// <summary>
-            /// Start a new variable-length list slot
-            ///
-            /// This function should be called before beginning to append elements to the
-            /// value builder
-            /// </summary>
-            /// <returns></returns>
-            public Builder Append()
-            {
-                ValueOffsetsBufferBuilder.Append(KeyBuilder.Length);
-                ValidityBufferBuilder.Append(true);
-
-                return this;
-            }
-
-            public Builder AppendNull()
-            {
-                ValueOffsetsBufferBuilder.Append(KeyBuilder.Length);
-                ValidityBufferBuilder.Append(false);
-                NullCount++;
-
-                return this;
-            }
-
-            public MapArray Build(MemoryAllocator allocator = default)
-            {
-                ValueOffsetsBufferBuilder.Append(KeyBuilder.Length);
-
-                ArrowBuffer validityBuffer = NullCount > 0 ? ValidityBufferBuilder.Build(allocator) : ArrowBuffer.Empty;
-
-                StructArray structs = new StructArray(
-                    DataType.KeyValueType, KeyBuilder.Length,
-                    new IArrowArray[] { KeyBuilder.Build(allocator), ValueBuilder.Build(allocator) },
-                    ArrowBuffer.Empty, 0
-                );
-
-                return new MapArray(DataType, Length - 1, ValueOffsetsBufferBuilder.Build(allocator), structs, validityBuffer, NullCount);
-            }
-
-            public Builder Reserve(int capacity)
-            {
-                ValueOffsetsBufferBuilder.Reserve(capacity + 1);
-                ValidityBufferBuilder.Reserve(capacity);
-                return this;
-            }
-
-            public Builder Resize(int length)
-            {
-                ValueOffsetsBufferBuilder.Resize(length + 1);
-                ValidityBufferBuilder.Resize(length);
-                return this;
-            }
-
-            public Builder Clear()
-            {
-                ValueOffsetsBufferBuilder.Clear();
-                KeyBuilder.Clear();
-                ValueBuilder.Clear();
-                ValidityBufferBuilder.Clear();
-                return this;
-            }
-
-        }
-
-        public StructArray KeyValues => base.Values as StructArray;
-        public IArrowArray Keys => KeyValues.Fields[0];
-        public new IArrowArray Values => KeyValues.Fields[1];
-
-        public MapArray(IArrowType dataType, int length,
-            ArrowBuffer valueOffsetsBuffer, IArrowArray structs,
-            ArrowBuffer nullBitmapBuffer, int nullCount = 0, int offset = 0)
-            : this(
-                  new ArrayData(
-                      dataType, length, nullCount, offset, new[] { nullBitmapBuffer, valueOffsetsBuffer },
-                      new[] { structs.Data }
-                  ), structs)
-        {
-        }
-
-        public MapArray(ArrayData data)
-            : this(data, ArrowArrayFactory.BuildArray(data.Children[0]))
-        {
-        }
-
-        private MapArray(ArrayData data, IArrowArray structs) : base(data, structs, ArrowTypeId.Map)
-        {
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor)
-        {
-            switch (visitor)
-            {
-                case IArrowArrayVisitor<MapArray> typedVisitor:
-                    typedVisitor.Visit(this);
-                    break;
-                default:
-                    base.Accept(visitor);
-                    break;
-            }
-        }
-
-        public IEnumerable<Tuple<K, V>> GetTuples<TKeyArray, K, TValueArray, V>(int index, Func<TKeyArray, int, K> getKey, Func<TValueArray, int, V> getValue)
-            where TKeyArray : Array where TValueArray : Array
-        {
-            ReadOnlySpan<int> offsets = ValueOffsets;
-            // Get key values
-            int start = offsets[index];
-            int end = offsets[index + 1];
-
-            TKeyArray keyArray = KeyValues.Fields[0] as TKeyArray;
-            TValueArray valueArray = KeyValues.Fields[1] as TValueArray;
-
-            for (int i = start; i < end; i++)
-            {
-                yield return new Tuple<K, V>(getKey(keyArray, i), getValue(valueArray, i));
-            }
-        }
-
-        public IEnumerable<KeyValuePair<K,V>> GetKeyValuePairs<TKeyArray, K, TValueArray, V>(int index, Func<TKeyArray, int, K> getKey, Func<TValueArray, int, V> getValue)
-            where TKeyArray : Array where TValueArray : Array
-        {
-            ReadOnlySpan<int> offsets = ValueOffsets;
-            // Get key values
-            int start = offsets[index];
-            int end = offsets[index + 1];
-
-            TKeyArray keyArray = KeyValues.Fields[0] as TKeyArray;
-            TValueArray valueArray = KeyValues.Fields[1] as TValueArray;
-
-            for (int i = start; i < end; i++)
-            {
-                yield return new KeyValuePair<K,V>(getKey(keyArray, i), getValue(valueArray, i));
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/NullArray.cs b/csharp/src/Apache.Arrow/Arrays/NullArray.cs
deleted file mode 100644
index 7f3e183..0000000
--- a/csharp/src/Apache.Arrow/Arrays/NullArray.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Types;
-using Apache.Arrow.Memory;
-
-namespace Apache.Arrow
-{
-    public class NullArray : IArrowArray
-    {
-        public class Builder : IArrowArrayBuilder<NullArray, Builder>
-        {
-            private int _length;
-
-            public int Length => _length;
-            public int Capacity => _length;
-            public int NullCount => _length;
-
-            public Builder()
-            {
-            }
-
-            public Builder AppendNull()
-            {
-                _length++;
-                return this;
-            }
-
-            public NullArray Build(MemoryAllocator allocator = default)
-            {
-                return new NullArray(_length);
-            }
-
-            public Builder Clear()
-            {
-                _length = 0;
-                return this;
-            }
-
-            public Builder Reserve(int capacity)
-            {
-                if (capacity < 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(capacity));
-                }
-
-                return this;
-            }
-
-            public Builder Resize(int length)
-            {
-                if (length < 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(length));
-                }
-
-                _length = length;
-                return this;
-            }
-        }
-
-        public ArrayData Data { get; }
-
-        public NullArray(ArrayData data)
-        {
-            if (data.Length != data.NullCount)
-            {
-                throw new ArgumentException("Length must equal null count", nameof(data));
-            }
-
-            data.EnsureDataType(ArrowTypeId.Null);
-            data.EnsureBufferCount(0);
-            Data = data;
-        }
-
-        public NullArray(int length)
-            : this(new ArrayData(NullType.Default, length, length, buffers: System.Array.Empty<ArrowBuffer>()))
-        {
-        }
-
-        public int Length => Data.Length;
-
-        public int Offset => Data.Offset;
-
-        public int NullCount => Data.GetNullCount();
-
-        public void Dispose() { }
-        public bool IsNull(int index) => true;
-        public bool IsValid(int index) => false;
-
-        public void Accept(IArrowArrayVisitor visitor) => Array.Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/PrimitiveArray.cs b/csharp/src/Apache.Arrow/Arrays/PrimitiveArray.cs
deleted file mode 100644
index 05d659b..0000000
--- a/csharp/src/Apache.Arrow/Arrays/PrimitiveArray.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-
-namespace Apache.Arrow
-{
-    public abstract class PrimitiveArray<T> : Array, IReadOnlyList<T?>, ICollection<T?>
-        where T : struct, IEquatable<T>
-    {
-        protected PrimitiveArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureBufferCount(2);
-        }
-
-        public ArrowBuffer ValueBuffer => Data.Buffers[1];
-
-        public ReadOnlySpan<T> Values => ValueBuffer.Span.CastTo<T>().Slice(Offset, Length);
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public T? GetValue(int index)
-        {
-            if (index < 0 || index >= Length)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-            return IsValid(index) ? Values[index] : null;
-        }
-
-        public IList<T?> ToList(bool includeNulls = false)
-        {
-            ReadOnlySpan<T> span = Values;
-            var list = new List<T?>(span.Length);
-
-            for (int i = 0; i < span.Length; i++)
-            {
-                T? value = GetValue(i);
-
-                if (value.HasValue)
-                {
-                    list.Add(value.Value);
-                }
-                else
-                {
-                    if (includeNulls)
-                    {
-                        list.Add(null);
-                    }
-                }
-            }
-
-            return list;
-        }
-
-        int IReadOnlyCollection<T?>.Count => Length;
-        T? IReadOnlyList<T?>.this[int index] => GetValue(index);
-
-        IEnumerator<T?> IEnumerable<T?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return IsValid(index) ? Values[index] : null;
-            }
-        }
-
-        IEnumerator IEnumerable.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return IsValid(index) ? Values[index] : null;
-            }
-        }
-
-        int ICollection<T?>.Count => Length;
-        bool ICollection<T?>.IsReadOnly => true;
-        void ICollection<T?>.Add(T? item) => throw new NotSupportedException("Collection is read-only.");
-        bool ICollection<T?>.Remove(T? item) => throw new NotSupportedException("Collection is read-only.");
-        void ICollection<T?>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-        bool ICollection<T?>.Contains(T? item)
-        {
-            if (item == null)
-            {
-                return NullCount > 0;
-            }
-
-            ReadOnlySpan<T> values = Values;
-            while (values.Length > 0)
-            {
-                int index = Values.IndexOf(item.Value);
-                if (index < 0 || IsValid(index)) { return index >= 0; }
-                values = values.Slice(index + 1);
-            }
-            return false;
-        }
-
-        void ICollection<T?>.CopyTo(T?[] array, int arrayIndex)
-        {
-            for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-            {
-                array[destIndex] = GetValue(srcIndex);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/PrimitiveArrayBuilder.cs b/csharp/src/Apache.Arrow/Arrays/PrimitiveArrayBuilder.cs
deleted file mode 100644
index b358384..0000000
--- a/csharp/src/Apache.Arrow/Arrays/PrimitiveArrayBuilder.cs
+++ /dev/null
@@ -1,206 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Apache.Arrow
-{
-    public abstract class PrimitiveArrayBuilder<TFrom, TTo, TArray, TBuilder> : IArrowArrayBuilder<TFrom, TArray, TBuilder>
-        where TTo : struct
-        where TArray : IArrowArray
-        where TBuilder : class, IArrowArrayBuilder<TArray>
-    {
-        protected TBuilder Instance => this as TBuilder;
-        protected IArrowArrayBuilder<TTo, TArray, IArrowArrayBuilder<TArray>> ArrayBuilder { get; }
-
-        public int Length => ArrayBuilder.Length;
-
-        public PrimitiveArrayBuilder(IArrowArrayBuilder<TTo, TArray, IArrowArrayBuilder<TArray>> builder)
-        {
-            ArrayBuilder = builder ?? throw new ArgumentNullException(nameof(builder));
-        }
-
-        public TArray Build(MemoryAllocator allocator = default) => ArrayBuilder.Build(allocator);
-
-        public TBuilder Append(TFrom value)
-        {
-            ArrayBuilder.Append(ConvertTo(value));
-            return Instance;
-        }
-
-        public TBuilder Append(ReadOnlySpan<TFrom> span)
-        {
-            ArrayBuilder.Reserve(span.Length);
-            foreach (TFrom value in span)
-            {
-                Append(value);
-            }
-            return Instance;
-        }
-
-        public TBuilder AppendRange(IEnumerable<TFrom> values)
-        {
-            ArrayBuilder.AppendRange(values.Select(ConvertTo));
-            return Instance;
-        }
-
-        public TBuilder AppendNull()
-        {
-            ArrayBuilder.AppendNull();
-            return Instance;
-        }
-
-        public TBuilder Reserve(int capacity)
-        {
-            ArrayBuilder.Reserve(capacity);
-            return Instance;
-        }
-
-        public TBuilder Resize(int length)
-        {
-            ArrayBuilder.Resize(length);
-            return Instance;
-        }
-
-        public TBuilder Swap(int i, int j)
-        {
-            ArrayBuilder.Swap(i, j);
-            return Instance;
-        }
-
-        public TBuilder Set(int index, TFrom value)
-        {
-            ArrayBuilder.Set(index, ConvertTo(value));
-            return Instance;
-        }
-
-        public TBuilder Clear()
-        {
-            ArrayBuilder.Clear();
-            return Instance;
-        }
-
-        protected abstract TTo ConvertTo(TFrom value);
-    }
-
-    public abstract class PrimitiveArrayBuilder<T, TArray, TBuilder> : IArrowArrayBuilder<T, TArray, TBuilder>
-        where T : struct
-        where TArray : IArrowArray
-        where TBuilder : class, IArrowArrayBuilder<TArray>
-    {
-        protected TBuilder Instance => this as TBuilder;
-        protected ArrowBuffer.Builder<T> ValueBuffer { get; }
-        protected ArrowBuffer.BitmapBuilder ValidityBuffer { get; }
-
-        public int Length => ValueBuffer.Length;
-        protected int NullCount => ValidityBuffer.UnsetBitCount;
-
-        public PrimitiveArrayBuilder()
-        {
-            ValueBuffer = new ArrowBuffer.Builder<T>();
-            ValidityBuffer = new ArrowBuffer.BitmapBuilder();
-        }
-
-        public TBuilder Resize(int length)
-        {
-            ValueBuffer.Resize(length);
-            ValidityBuffer.Resize(length);
-            return Instance;
-        }
-
-        public TBuilder Reserve(int capacity)
-        {
-            ValueBuffer.Reserve(capacity);
-            ValidityBuffer.Reserve(capacity);
-            return Instance;
-        }
-
-        public TBuilder Append(T value)
-        {
-            ValueBuffer.Append(value);
-            ValidityBuffer.Append(true);
-            return Instance;
-        }
-
-        public TBuilder Append(T? value) =>
-            (value == null) ? AppendNull() : Append(value.Value);
-
-        public TBuilder Append(ReadOnlySpan<T> span)
-        {
-            int len = ValueBuffer.Length;
-            ValueBuffer.Append(span);
-            int additionalBitsCount = ValueBuffer.Length - len;
-            ValidityBuffer.AppendRange(true, additionalBitsCount);
-            return Instance;
-        }
-
-        public TBuilder AppendRange(IEnumerable<T> values)
-        {
-            int len = ValueBuffer.Length;
-            ValueBuffer.AppendRange(values);
-            var additionalBitsCount = ValueBuffer.Length - len;
-            ValidityBuffer.AppendRange(true, additionalBitsCount);
-            return Instance;
-        }
-
-        public TBuilder AppendNull()
-        {
-            ValidityBuffer.Append(false);
-            ValueBuffer.Append(default(T));
-            return Instance;
-        }
-
-        public TBuilder Clear()
-        {
-            ValueBuffer.Clear();
-            ValidityBuffer.Clear();
-            return Instance;
-        }
-
-        public TBuilder Set(int index, T value)
-        {
-            ValueBuffer.Span[index] = value;
-            ValidityBuffer.Set(index, true);
-            return Instance;
-        }
-
-        public TBuilder Swap(int i, int j)
-        {
-            T x = ValueBuffer.Span[i];
-            ValueBuffer.Span[i] = ValueBuffer.Span[j];
-            ValueBuffer.Span[j] = x;
-            ValidityBuffer.Swap(i, j);
-            return Instance;
-        }
-
-        public TArray Build(MemoryAllocator allocator = default)
-        {
-            ArrowBuffer validityBuffer = NullCount > 0
-                                    ? ValidityBuffer.Build(allocator)
-                                    : ArrowBuffer.Empty;
-
-            return Build(
-                ValueBuffer.Build(allocator), validityBuffer,
-                ValueBuffer.Length, NullCount, 0);
-        }
-
-        protected abstract TArray Build(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/SparseUnionArray.cs b/csharp/src/Apache.Arrow/Arrays/SparseUnionArray.cs
deleted file mode 100644
index 5b29489..0000000
--- a/csharp/src/Apache.Arrow/Arrays/SparseUnionArray.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Apache.Arrow
-{
-    public class SparseUnionArray : UnionArray
-    {
-        public SparseUnionArray(
-            IArrowType dataType,
-            int length,
-            IEnumerable<IArrowArray> children,
-            ArrowBuffer typeIds,
-            int nullCount = 0,
-            int offset = 0)
-            : base(new ArrayData(
-                dataType, length, nullCount, offset, new[] { typeIds },
-                children.Select(child => child.Data)))
-        {
-            ValidateMode(UnionMode.Sparse, Type.Mode);
-        }
-
-        public SparseUnionArray(ArrayData data) 
-            : base(data)
-        {
-            ValidateMode(UnionMode.Sparse, Type.Mode);
-            data.EnsureBufferCount(1);
-        }
-
-        protected override bool FieldIsValid(IArrowArray fieldArray, int index)
-        {
-            return fieldArray.IsValid(index);
-        }
-
-        internal new static int ComputeNullCount(ArrayData data)
-        {
-            var offset = data.Offset;
-            var length = data.Length;
-            var typeIds = data.Buffers[0].Span.Slice(offset, length);
-            var childArrays = new IArrowArray[data.Children.Length];
-            for (var childIdx = 0; childIdx < data.Children.Length; ++childIdx)
-            {
-                childArrays[childIdx] = ArrowArrayFactory.BuildArray(data.Children[childIdx]);
-            }
-
-            var nullCount = 0;
-            for (var i = 0; i < data.Length; ++i)
-            {
-                var typeId = typeIds[i];
-                nullCount += childArrays[typeId].IsNull(offset + i) ? 1 : 0;
-            }
-
-            return nullCount;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/StringArray.cs b/csharp/src/Apache.Arrow/Arrays/StringArray.cs
deleted file mode 100644
index ab44805..0000000
--- a/csharp/src/Apache.Arrow/Arrays/StringArray.cs
+++ /dev/null
@@ -1,193 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Text;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class StringArray: BinaryArray, IReadOnlyList<string>, ICollection<string>
-    {
-        public static readonly Encoding DefaultEncoding = Encoding.UTF8;
-
-        private Dictionary<Encoding, string[]> materializedStringStore;
-
-        public new class Builder : BuilderBase<StringArray, Builder>
-        {
-            public Builder() : base(StringType.Default) { }
-
-            protected override StringArray Build(ArrayData data)
-            {
-                return new StringArray(data);
-            }
-
-            public Builder Append(string value, Encoding encoding = null)
-            {
-                if (value == null)
-                {
-                    return AppendNull();
-                }
-                encoding = encoding ?? DefaultEncoding;
-                byte[] span = encoding.GetBytes(value);
-                return Append(span.AsSpan());
-            }
-
-            public Builder AppendRange(IEnumerable<string> values, Encoding encoding = null)
-            {
-                foreach (string value in values)
-                {
-                    Append(value, encoding);
-                }
-
-                return this;
-            }
-        }
-
-        public StringArray(ArrayData data)
-            : base(ArrowTypeId.String, data) { }
-
-        public StringArray(int length,
-            ArrowBuffer valueOffsetsBuffer,
-            ArrowBuffer dataBuffer,
-            ArrowBuffer nullBitmapBuffer,
-            int nullCount = 0, int offset = 0)
-            : this(new ArrayData(StringType.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueOffsetsBuffer, dataBuffer }))
-        { }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        /// <summary>
-        /// Get the string value at the given index
-        /// </summary>
-        /// <param name="index">Input index</param>
-        /// <param name="encoding">Optional: the string encoding, default is UTF8</param>
-        /// <returns>The string object at the given index</returns>
-        public string GetString(int index, Encoding encoding = default)
-        {
-            encoding ??= DefaultEncoding;
-
-            if (materializedStringStore != null && materializedStringStore.TryGetValue(encoding, out string[] materializedStrings))
-            {
-                return materializedStrings[index];
-            }
-
-            ReadOnlySpan<byte> bytes = GetBytes(index, out bool isNull);
-
-            if (isNull)
-            {
-                return null;
-            }
-
-            if (bytes.Length == 0)
-            {
-                return string.Empty;
-            }
-
-            unsafe
-            {
-                fixed (byte* data = &MemoryMarshal.GetReference(bytes))
-                    return encoding.GetString(data, bytes.Length);
-            }
-        }
-
-        /// <summary>
-        /// Materialize the array for the given encoding to accelerate the string access
-        /// </summary>
-        /// <param name="encoding">Optional: the string encoding, default is UTF8</param>
-        /// <remarks>This method is not thread safe when it is called in parallel with <see cref="GetString(int, Encoding)"/> or <see cref="Materialize(Encoding)"/>.</remarks>
-        public void Materialize(Encoding encoding = default)
-        {
-            encoding ??= DefaultEncoding;
-
-            if (IsMaterialized(encoding))
-            {
-                return;
-            }
-
-            if (materializedStringStore == null)
-            {
-                materializedStringStore = new Dictionary<Encoding, string[]>();
-            }
-
-            var stringStore = new string[Length];
-            for (int i = 0; i < Length; i++)
-            {
-                stringStore[i] = GetString(i, encoding);
-            }
-
-            materializedStringStore[encoding] = stringStore;
-        }
-
-        /// <summary>
-        /// Check if the array has been materialized for the given encoding
-        /// </summary>
-        /// <param name="encoding">Optional: the string encoding, default is UTF8</param>
-        /// <returns>True of false whether the array has been materialized</returns>
-        public bool IsMaterialized(Encoding encoding = default)
-        {
-            if (materializedStringStore == null)
-            {
-                return false;
-            }
-
-            encoding ??= DefaultEncoding;
-            return materializedStringStore.ContainsKey(encoding);
-        }
-
-        int IReadOnlyCollection<string>.Count => Length;
-
-        string IReadOnlyList<string>.this[int index] => GetString(index);
-
-        IEnumerator<string> IEnumerable<string>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetString(index);
-            };
-        }
-
-        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<string>)this).GetEnumerator();
-
-        int ICollection<string>.Count => Length;
-        bool ICollection<string>.IsReadOnly => true;
-        void ICollection<string>.Add(string item) => throw new NotSupportedException("Collection is read-only.");
-        bool ICollection<string>.Remove(string item) => throw new NotSupportedException("Collection is read-only.");
-        void ICollection<string>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-        bool ICollection<string>.Contains(string item)
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                if (GetString(index) == item)
-                    return true;
-            }
-
-            return false;
-        }
-
-        void ICollection<string>.CopyTo(string[] array, int arrayIndex)
-        {
-            for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-            {
-                array[destIndex] = GetString(srcIndex);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/StringViewArray.cs b/csharp/src/Apache.Arrow/Arrays/StringViewArray.cs
deleted file mode 100644
index 8864476..0000000
--- a/csharp/src/Apache.Arrow/Arrays/StringViewArray.cs
+++ /dev/null
@@ -1,110 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace Apache.Arrow
-{
-    public class StringViewArray: BinaryViewArray, IReadOnlyList<string>
-    {
-        public static readonly Encoding DefaultEncoding = Encoding.UTF8;
-
-        public new class Builder : BuilderBase<StringViewArray, Builder>
-        {
-            public Builder() : base(StringViewType.Default) { }
-
-            protected override StringViewArray Build(ArrayData data)
-            {
-                return new StringViewArray(data);
-            }
-
-            public Builder Append(string value, Encoding encoding = null)
-            {
-                if (value == null)
-                {
-                    return AppendNull();
-                }
-                encoding = encoding ?? DefaultEncoding;
-                byte[] span = encoding.GetBytes(value);
-                return Append(span.AsSpan());
-            }
-
-            public Builder AppendRange(IEnumerable<string> values, Encoding encoding = null)
-            {
-                foreach (string value in values)
-                {
-                    Append(value, encoding);
-                }
-
-                return this;
-            }
-        }
-
-        public StringViewArray(ArrayData data)
-            : base(ArrowTypeId.StringView, data) { }
-
-        public StringViewArray(int length,
-            ArrowBuffer valueOffsetsBuffer,
-            ArrowBuffer dataBuffer,
-            ArrowBuffer nullBitmapBuffer,
-            int nullCount = 0, int offset = 0)
-            : this(new ArrayData(StringViewType.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueOffsetsBuffer, dataBuffer }))
-        { }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public string GetString(int index, Encoding encoding = default)
-        {
-            encoding ??= DefaultEncoding;
-
-            ReadOnlySpan<byte> bytes = GetBytes(index, out bool isNull);
-
-            if (isNull)
-            {
-                return null;
-            }
-            if (bytes.Length == 0)
-            {
-                return string.Empty;
-            }
-
-            unsafe
-            {
-                fixed (byte* data = &MemoryMarshal.GetReference(bytes))
-                    return encoding.GetString(data, bytes.Length);
-            }
-        }
-
-        int IReadOnlyCollection<string>.Count => Length;
-
-        string IReadOnlyList<string>.this[int index] => GetString(index);
-
-        IEnumerator<string> IEnumerable<string>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetString(index);
-            };
-        }
-
-        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<string>)this).GetEnumerator();
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/StructArray.cs b/csharp/src/Apache.Arrow/Arrays/StructArray.cs
deleted file mode 100644
index fc1335a..0000000
--- a/csharp/src/Apache.Arrow/Arrays/StructArray.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-
-namespace Apache.Arrow
-{
-    public class StructArray : Array, IArrowRecord
-    {
-        private IReadOnlyList<IArrowArray> _fields;
-
-        public IReadOnlyList<IArrowArray> Fields =>
-            LazyInitializer.EnsureInitialized(ref _fields, InitializeFields);
-
-        public StructArray(
-            IArrowType dataType, int length,
-            IEnumerable<IArrowArray> children,
-            ArrowBuffer nullBitmapBuffer, int nullCount = 0, int offset = 0)
-            : this(new ArrayData(
-                dataType, length, nullCount, offset, new[] { nullBitmapBuffer },
-                children.Select(child => child.Data)))
-        {
-        }
-
-        public StructArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Struct);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor)
-        {
-            switch (visitor)
-            {
-                case IArrowArrayVisitor<StructArray> structArrayVisitor:
-                    structArrayVisitor.Visit(this);
-                    break;
-                case IArrowArrayVisitor<IArrowRecord> arrowStructVisitor:
-                    arrowStructVisitor.Visit(this);
-                    break;
-                default:
-                    visitor.Visit(this);
-                    break;
-            }
-        }
-
-        private IReadOnlyList<IArrowArray> InitializeFields()
-        {
-            IArrowArray[] result = new IArrowArray[Data.Children.Length];
-            for (int i = 0; i < Data.Children.Length; i++)
-            {
-                var childData = Data.Children[i];
-                if (Data.Offset != 0 || childData.Length != Data.Length)
-                {
-                    childData = childData.Slice(Data.Offset, Data.Length);
-                }
-                result[i] = ArrowArrayFactory.BuildArray(childData);
-            }
-            return result;
-        }
-
-        IRecordType IArrowRecord.Schema => (StructType)Data.DataType;
-
-        int IArrowRecord.ColumnCount => Fields.Count;
-
-        IArrowArray IArrowRecord.Column(string columnName, IEqualityComparer<string> comparer) =>
-            Fields[((StructType)Data.DataType).GetFieldIndex(columnName, comparer)];
-
-        IArrowArray IArrowRecord.Column(int columnIndex) => Fields[columnIndex];
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Time32Array.cs b/csharp/src/Apache.Arrow/Arrays/Time32Array.cs
deleted file mode 100644
index 63c0898..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Time32Array.cs
+++ /dev/null
@@ -1,201 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or moreDate32Array
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Apache.Arrow
-{
-    /// <summary>
-    /// The <see cref="Time32Array"/> class holds an array of <see cref="Int32" />, where each value is
-    /// stored as the number of seconds/ milliseconds (depending on the Time32Type) since midnight.
-    /// </summary>
-    public class Time32Array : PrimitiveArray<int>
-#if NET6_0_OR_GREATER
-        , IReadOnlyList<TimeOnly?>, ICollection<TimeOnly?>
-#endif
-    {
-        /// <summary>
-        /// The <see cref="Builder"/> class can be used to fluently build <see cref="Time32Array"/> objects.
-        /// </summary>
-        public class Builder : TimeArrayBuilder<int, Time32Array, Builder>
-        {
-            private class TimeBuilder : PrimitiveArrayBuilder<int, Time32Array, TimeBuilder>
-            {
-                public Time32Type DataType { get; }
-
-                public TimeBuilder(Time32Type dataType) => DataType = dataType;
-
-                protected override Time32Array Build(
-                    ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                    int length, int nullCount, int offset) =>
-                    new Time32Array(DataType, valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-            }
-
-            public Builder()
-                : this(Time32Type.Default) { }
-
-            public Builder(TimeUnit unit)
-                : this((Time32Type)TimeType.FromTimeUnit(unit)) { }
-
-            /// <summary>
-            /// Construct a new instance of the <see cref="Builder"/> class.
-            /// </summary>
-            public Builder(Time32Type type)
-                : base(new TimeBuilder(type))
-            {
-            }
-
-#if NET6_0_OR_GREATER
-            protected override int Convert(TimeOnly time)
-            {
-                var unit = ((TimeBuilder)InnerBuilder).DataType.Unit;
-                return unit switch
-                {
-                    TimeUnit.Second => (int)(time.Ticks / TimeSpan.TicksPerSecond),
-                    TimeUnit.Millisecond => (int)(time.Ticks / TimeSpan.TicksPerMillisecond),
-                    _ => throw new InvalidDataException($"Unsupported time unit for Time32Type: {unit}")
-                };
-            }
-#endif
-        }
-
-        public Time32Array(
-            Time32Type type,
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(type, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public Time32Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Time32);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        /// <summary>
-        /// Get the time at the specified index as seconds
-        /// </summary>
-        /// <param name="index">Index at which to get the time.</param>
-        /// <returns>Returns an <see cref="Int32" />, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public int? GetSeconds(int index)
-        {
-            int? value = GetValue(index);
-            if (value == null)
-            {
-                return null;
-            }
-
-            var unit = ((Time32Type) Data.DataType).Unit;
-            return unit switch
-            {
-                TimeUnit.Second => value,
-                TimeUnit.Millisecond => value / 1_000,
-                _ => throw new InvalidDataException($"Unsupported time unit for Time32Type: {unit}")
-            };
-        }
-
-        /// <summary>
-        /// Get the time at the specified index as milliseconds
-        /// </summary>
-        /// <param name="index">Index at which to get the time.</param>
-        /// <returns>Returns an <see cref="Int32" />, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public int? GetMilliSeconds(int index)
-        {
-            int? value = GetValue(index);
-            if (value == null)
-            {
-                return null;
-            }
-
-            var unit = ((Time32Type)Data.DataType).Unit;
-            return unit switch
-            {
-                TimeUnit.Second => value * 1_000,
-                TimeUnit.Millisecond => value,
-                _ => throw new InvalidDataException($"Unsupported time unit for Time32Type: {unit}")
-            };
-        }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Get the time at the specified index as <see cref="TimeOnly"/>
-        /// </summary>
-        /// <param name="index">Index at which to get the time.</param>
-        /// <returns>Returns a <see cref="TimeOnly" />, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public TimeOnly? GetTime(int index)
-        {
-            int? value = GetValue(index);
-            if (value == null)
-            {
-                return null;
-            }
-
-            var unit = ((Time32Type)Data.DataType).Unit;
-            return unit switch
-            {
-                TimeUnit.Second => new TimeOnly(value.Value * TimeSpan.TicksPerSecond),
-                TimeUnit.Millisecond => new TimeOnly(value.Value * TimeSpan.TicksPerMillisecond),
-                _ => throw new InvalidDataException($"Unsupported time unit for Time32Type: {unit}")
-            };
-        }
-
-        int IReadOnlyCollection<TimeOnly?>.Count => Length;
-
-        TimeOnly? IReadOnlyList<TimeOnly?>.this[int index] => GetTime(index);
-
-        IEnumerator<TimeOnly?> IEnumerable<TimeOnly?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetTime(index);
-            };
-        }
-
-        int ICollection<TimeOnly?>.Count => Length;
-        bool ICollection<TimeOnly?>.IsReadOnly => true;
-        void ICollection<TimeOnly?>.Add(TimeOnly? item) => throw new NotSupportedException("Collection is read-only.");
-        bool ICollection<TimeOnly?>.Remove(TimeOnly? item) => throw new NotSupportedException("Collection is read-only.");
-        void ICollection<TimeOnly?>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-        bool ICollection<TimeOnly?>.Contains(TimeOnly? item)
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                if (GetTime(index).Equals(item))
-                    return true;
-            }
-
-            return false;
-        }
-
-        void ICollection<TimeOnly?>.CopyTo(TimeOnly?[] array, int arrayIndex)
-        {
-            for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-            {
-                array[destIndex] = GetTime(srcIndex);
-            }
-        }
-#endif
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/Time64Array.cs b/csharp/src/Apache.Arrow/Arrays/Time64Array.cs
deleted file mode 100644
index 5518462..0000000
--- a/csharp/src/Apache.Arrow/Arrays/Time64Array.cs
+++ /dev/null
@@ -1,192 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or moreDate32Array
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Apache.Arrow
-{
-    /// <summary>
-    /// The <see cref="Time64Array"/> class holds an array of <see cref="Int64" />, where each value is
-    /// stored as the number of microseconds/nanoseconds (depending on the Time64Type) since midnight.
-    /// </summary>
-    public class Time64Array : PrimitiveArray<long>
-#if NET6_0_OR_GREATER
-        , IReadOnlyList<TimeOnly?>, ICollection<TimeOnly?>
-#endif
-    {
-        /// <summary>
-        /// The <see cref="Builder"/> class can be used to fluently build <see cref="Time64Array"/> objects.
-        /// </summary>
-        public class Builder : TimeArrayBuilder<long, Time64Array, Builder>
-        {
-            private class TimeBuilder : PrimitiveArrayBuilder<long, Time64Array, TimeBuilder>
-            {
-                public Time64Type DataType { get; }
-
-                public TimeBuilder(Time64Type dataType) => DataType = dataType;
-
-                protected override Time64Array Build(
-                    ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                    int length, int nullCount, int offset) =>
-                    new Time64Array(DataType, valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-            }
-
-            public Builder()
-                : this(Time64Type.Default) { }
-
-            public Builder(TimeUnit unit)
-                : this((Time64Type)TimeType.FromTimeUnit(unit)) { }
-
-            /// <summary>
-            /// Construct a new instance of the <see cref="Builder"/> class.
-            /// </summary>
-            public Builder(Time64Type type)
-                : base(new TimeBuilder(type))
-            {
-            }
-
-#if NET6_0_OR_GREATER
-            protected override long Convert(TimeOnly time)
-            {
-                return ((TimeBuilder)InnerBuilder).DataType.Unit.ConvertFromTicks(time.Ticks);
-            }
-#endif
-        }
-
-        public Time64Array(
-            Time64Type type,
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(type, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public Time64Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Time64);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        /// <summary>
-        /// Get the time at the specified index as microseconds
-        /// </summary>
-        /// <param name="index">Index at which to get the time.</param>
-        /// <returns>Returns a <see cref="Int64" />, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public long? GetMicroSeconds(int index)
-        {
-            long? value = GetValue(index);
-            if (value == null)
-            {
-                return null;
-            }
-
-            var unit = ((Time64Type)Data.DataType).Unit;
-            return unit switch
-            {
-                TimeUnit.Microsecond => value,
-                TimeUnit.Nanosecond => value / 1_000,
-                _ => throw new InvalidDataException($"Unsupported time unit for Time64Type: {unit}")
-            };
-        }
-
-        /// <summary>
-        /// Get the time at the specified index as nanoseconds
-        /// </summary>
-        /// <param name="index">Index at which to get the time.</param>
-        /// <returns>Returns a <see cref="Int64" />, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public long? GetNanoSeconds(int index)
-        {
-            long? value = GetValue(index);
-            if (value == null)
-            {
-                return null;
-            }
-
-            var unit = ((Time64Type)Data.DataType).Unit;
-            return unit switch
-            {
-                TimeUnit.Microsecond => value * 1_000,
-                TimeUnit.Nanosecond => value,
-                _ => throw new InvalidDataException($"Unsupported time unit for Time64Type: {unit}")
-            };
-        }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Get the time at the specified index as <see cref="TimeOnly"/>
-        /// </summary>
-        /// <remarks>
-        /// This may cause truncation of nanosecond values, as the resolution of TimeOnly is in 100-ns increments.
-        /// </remarks>
-        /// <param name="index">Index at which to get the time.</param>
-        /// <returns>Returns a <see cref="TimeOnly" />, or <c>null</c> if there is no object at that index.
-        /// </returns>
-        public TimeOnly? GetTime(int index)
-        {
-            long? value = GetValue(index);
-            if (value == null)
-            {
-                return null;
-            }
-
-            return new TimeOnly(((Time64Type)Data.DataType).Unit.ConvertToTicks(value.Value));
-        }
-
-        int IReadOnlyCollection<TimeOnly?>.Count => Length;
-
-        TimeOnly? IReadOnlyList<TimeOnly?>.this[int index] => GetTime(index);
-
-        IEnumerator<TimeOnly?> IEnumerable<TimeOnly?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetTime(index);
-            };
-        }
-
-        int ICollection<TimeOnly?>.Count => Length;
-        bool ICollection<TimeOnly?>.IsReadOnly => true;
-        void ICollection<TimeOnly?>.Add(TimeOnly? item) => throw new NotSupportedException("Collection is read-only.");
-        bool ICollection<TimeOnly?>.Remove(TimeOnly? item) => throw new NotSupportedException("Collection is read-only.");
-        void ICollection<TimeOnly?>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-        bool ICollection<TimeOnly?>.Contains(TimeOnly? item)
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                if (GetTime(index).Equals(item))
-                    return true;
-            }
-
-            return false;
-        }
-
-        void ICollection<TimeOnly?>.CopyTo(TimeOnly?[] array, int arrayIndex)
-        {
-            for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-            {
-                array[destIndex] = GetTime(srcIndex);
-            }
-        }
-#endif
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/TimeArrayBuilder.cs b/csharp/src/Apache.Arrow/Arrays/TimeArrayBuilder.cs
deleted file mode 100644
index 88f8aa8..0000000
--- a/csharp/src/Apache.Arrow/Arrays/TimeArrayBuilder.cs
+++ /dev/null
@@ -1,152 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Apache.Arrow
-{
-    public abstract class TimeArrayBuilder<TUnderlying, TArray, TBuilder> :
-        DelegatingArrayBuilder<TUnderlying, TArray, TBuilder>
-#if NET6_0_OR_GREATER
-        , IArrowArrayBuilder<TimeOnly, TArray, TBuilder>
-#endif
-        where TArray : IArrowArray
-        where TBuilder : class, IArrowArrayBuilder<TArray>
-    {
-        /// <summary>
-        /// Construct a new instance of the <see cref="TimeArrayBuilder{TUnderlying,TArray,TBuilder}"/> class.
-        /// </summary>
-        /// <param name="innerBuilder">Inner builder that will produce arrays of type <typeparamref name="TArray"/>.
-        /// </param>
-        protected TimeArrayBuilder(IArrowArrayBuilder<TUnderlying, TArray, IArrowArrayBuilder<TArray>> innerBuilder)
-            : base(innerBuilder)
-        { }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Append a time in the form of a <see cref="TimeOnly"/> object to the array.
-        /// </summary>
-        /// <param name="value">Time to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Append(TimeOnly value)
-        {
-            InnerBuilder.Append(Convert(value));
-            return this as TBuilder;
-        }
-#endif
-
-        /// <summary>
-        /// Append a time
-        /// </summary>
-        /// <param name="value"></param>
-        /// <returns></returns>
-        public TBuilder Append(TUnderlying value)
-        {
-            InnerBuilder.Append(value);
-            return this as TBuilder;
-        }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Append a span of times in the form of <see cref="TimeOnly"/> objects to the array.
-        /// </summary>
-        /// <param name="span">Span of times to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Append(ReadOnlySpan<TimeOnly> span)
-        {
-            InnerBuilder.Reserve(span.Length);
-            foreach (var item in span)
-            {
-                InnerBuilder.Append(Convert(item));
-            }
-
-            return this as TBuilder;
-        }
-#endif
-
-        public TBuilder Append(ReadOnlySpan<TUnderlying> values)
-        {
-            InnerBuilder.Append(values);
-            return this as TBuilder;
-        }
-
-        /// <summary>
-        /// Append a null time to the array.
-        /// </summary>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public override TBuilder AppendNull()
-        {
-            InnerBuilder.AppendNull();
-            return this as TBuilder;
-        }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Append a collection of times in the form of <see cref="TimeOnly"/> objects to the array.
-        /// </summary>
-        /// <param name="values">Collection of times to add.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder AppendRange(IEnumerable<TimeOnly> values)
-        {
-            InnerBuilder.AppendRange(values.Select(Convert));
-            return this as TBuilder;
-        }
-#endif
-
-        public TBuilder AppendRange(IEnumerable<TUnderlying> values)
-        {
-            InnerBuilder.AppendRange(values);
-            return this as TBuilder;
-        }
-
-#if NET6_0_OR_GREATER
-        /// <summary>
-        /// Set the value of a time in the form of a <see cref="TimeOnly"/> object at the specified index.
-        /// </summary>
-        /// <param name="index">Index at which to set value.</param>
-        /// <param name="value">Time to set.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Set(int index, TimeOnly value)
-        {
-            InnerBuilder.Set(index, Convert(value));
-            return this as TBuilder;
-        }
-#endif
-
-        public TBuilder Set(int index, TUnderlying value)
-        {
-            InnerBuilder.Set(index, value);
-            return this as TBuilder;
-        }
-
-        /// <summary>
-        /// Swap the values of the times at the specified indices.
-        /// </summary>
-        /// <param name="i">First index.</param>
-        /// <param name="j">Second index.</param>
-        /// <returns>Returns the builder (for fluent-style composition).</returns>
-        public TBuilder Swap(int i, int j)
-        {
-            InnerBuilder.Swap(i, j);
-            return this as TBuilder;
-        }
-
-#if NET6_0_OR_GREATER
-        protected abstract TUnderlying Convert(TimeOnly time);
-#endif
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/TimestampArray.cs b/csharp/src/Apache.Arrow/Arrays/TimestampArray.cs
deleted file mode 100644
index b838605..0000000
--- a/csharp/src/Apache.Arrow/Arrays/TimestampArray.cs
+++ /dev/null
@@ -1,186 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-
-namespace Apache.Arrow
-{
-    public class TimestampArray : PrimitiveArray<long>, IReadOnlyList<DateTimeOffset?>, ICollection<DateTimeOffset?>
-    {
-        private static readonly DateTimeOffset s_epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, 0, TimeSpan.Zero);
-
-        public class Builder: PrimitiveArrayBuilder<DateTimeOffset, long, TimestampArray, Builder>
-        {
-            internal class TimestampBuilder : PrimitiveArrayBuilder<long, TimestampArray, TimestampBuilder>
-            {
-                internal TimestampBuilder(TimestampType type)
-                {
-                    DataType = type ?? throw new ArgumentNullException(nameof(type));
-                }
-
-                protected TimestampType DataType { get; }
-
-                protected override TimestampArray Build(
-                    ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                    int length, int nullCount, int offset) =>
-                    new TimestampArray(DataType, valueBuffer, nullBitmapBuffer,
-                        length, nullCount, offset);
-            }
-
-            protected TimestampType DataType { get; }
-
-            public Builder()
-                : this(TimestampType.Default) { }
-
-            public Builder(TimeUnit unit, TimeZoneInfo timezone)
-                : this(new TimestampType(unit, timezone)) { }
-
-            public Builder(TimeUnit unit = TimeUnit.Millisecond, string timezone = "+00:00")
-                : this(new TimestampType(unit, timezone)) { }
-
-            public Builder(TimeUnit unit)
-                : this(new TimestampType(unit, (string) null)) { }
-
-            public Builder(TimestampType type)
-                : base(new TimestampBuilder(type))
-            {
-                DataType = type;
-            }
-
-            protected override long ConvertTo(DateTimeOffset value)
-            {
-                // We must return the absolute time since the UNIX epoch while
-                // respecting the timezone offset; the calculation is as follows:
-                //
-                // - Compute time span between epoch and specified time
-                // - Compute time divisions per tick
-
-                TimeSpan timeSpan = value - s_epoch;
-                long ticks = timeSpan.Ticks;
-
-                switch (DataType.Unit)
-                {
-                    case TimeUnit.Nanosecond:
-                        return checked(ticks * 100);
-                    case TimeUnit.Microsecond:
-                        return ticks / 10;
-                    case TimeUnit.Millisecond:
-                        return ticks / TimeSpan.TicksPerMillisecond;
-                    case TimeUnit.Second:
-                        return ticks / TimeSpan.TicksPerSecond;
-                    default:
-                        throw new InvalidOperationException($"unsupported time unit <{DataType.Unit}>");
-                }
-            }
-        }
-
-        public TimestampArray(
-            TimestampType type,
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(type, length, nullCount, offset,
-                new[] {nullBitmapBuffer, valueBuffer})) { }
-
-        public TimestampArray(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.Timestamp);
-
-            Debug.Assert(Data.DataType is TimestampType);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-        public DateTimeOffset GetTimestampUnchecked(int index)
-        {
-            var type = (TimestampType) Data.DataType;
-            long value = Values[index];
-
-            long ticks;
-
-            switch (type.Unit)
-            {
-                case TimeUnit.Nanosecond:
-                    ticks = value / 100;
-                    break;
-                case TimeUnit.Microsecond:
-                    ticks = value * 10;
-                    break;
-                case TimeUnit.Millisecond:
-                    ticks = value * TimeSpan.TicksPerMillisecond;
-                    break;
-                case TimeUnit.Second:
-                    ticks = value * TimeSpan.TicksPerSecond;
-                    break;
-                default:
-                    throw new InvalidDataException(
-                        $"Unsupported timestamp unit <{type.Unit}>");
-            }
-
-            return new DateTimeOffset(s_epoch.Ticks + ticks, TimeSpan.Zero);
-        }
-
-        public DateTimeOffset? GetTimestamp(int index)
-        {
-            if (IsNull(index))
-            {
-                return null;
-            }
-
-            return GetTimestampUnchecked(index);
-        }
-
-        int IReadOnlyCollection<DateTimeOffset?>.Count => Length;
-
-        DateTimeOffset? IReadOnlyList<DateTimeOffset?>.this[int index] => GetTimestamp(index);
-
-        IEnumerator<DateTimeOffset?> IEnumerable<DateTimeOffset?>.GetEnumerator()
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                yield return GetTimestamp(index);
-            };
-        }
-
-        int ICollection<DateTimeOffset?>.Count => Length;
-        bool ICollection<DateTimeOffset?>.IsReadOnly => true;
-        void ICollection<DateTimeOffset?>.Add(DateTimeOffset? item) => throw new NotSupportedException("Collection is read-only.");
-        bool ICollection<DateTimeOffset?>.Remove(DateTimeOffset? item) => throw new NotSupportedException("Collection is read-only.");
-        void ICollection<DateTimeOffset?>.Clear() => throw new NotSupportedException("Collection is read-only.");
-
-        bool ICollection<DateTimeOffset?>.Contains(DateTimeOffset? item)
-        {
-            for (int index = 0; index < Length; index++)
-            {
-                if (GetTimestamp(index).Equals(item))
-                    return true;
-            }
-
-            return false;
-        }
-
-        void ICollection<DateTimeOffset?>.CopyTo(DateTimeOffset?[] array, int arrayIndex)
-        {
-            for (int srcIndex = 0, destIndex = arrayIndex; srcIndex < Length; srcIndex++, destIndex++)
-            {
-                array[destIndex] = GetTimestamp(srcIndex);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/UInt16Array.cs b/csharp/src/Apache.Arrow/Arrays/UInt16Array.cs
deleted file mode 100644
index bba244f..0000000
--- a/csharp/src/Apache.Arrow/Arrays/UInt16Array.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class UInt16Array : PrimitiveArray<ushort>
-    {
-        public class Builder : PrimitiveArrayBuilder<ushort, UInt16Array, Builder>
-        {
-            protected override UInt16Array Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new UInt16Array(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public UInt16Array(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(UInt16Type.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public UInt16Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.UInt16);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-    }
-
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/UInt32Array.cs b/csharp/src/Apache.Arrow/Arrays/UInt32Array.cs
deleted file mode 100644
index 65320be..0000000
--- a/csharp/src/Apache.Arrow/Arrays/UInt32Array.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class UInt32Array : PrimitiveArray<uint>
-    {
-        public class Builder : PrimitiveArrayBuilder<uint, UInt32Array, Builder>
-        {
-            protected override UInt32Array Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new UInt32Array(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public UInt32Array(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(UInt32Type.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public UInt32Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.UInt32);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/UInt64Array.cs b/csharp/src/Apache.Arrow/Arrays/UInt64Array.cs
deleted file mode 100644
index 617949f..0000000
--- a/csharp/src/Apache.Arrow/Arrays/UInt64Array.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class UInt64Array : PrimitiveArray<ulong>
-    {
-        public class Builder : PrimitiveArrayBuilder<ulong, UInt64Array, Builder>
-        {
-            protected override UInt64Array Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new UInt64Array(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public UInt64Array(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(UInt64Type.Default, length, nullCount, offset,
-                new[] { nullBitmapBuffer, valueBuffer }))
-        { }
-
-        public UInt64Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.UInt64);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/UInt8Array.cs b/csharp/src/Apache.Arrow/Arrays/UInt8Array.cs
deleted file mode 100644
index 5cde791..0000000
--- a/csharp/src/Apache.Arrow/Arrays/UInt8Array.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public class UInt8Array : PrimitiveArray<byte>
-    {
-        public class Builder : PrimitiveArrayBuilder<byte, UInt8Array, Builder>
-        {
-            protected override UInt8Array Build(
-                ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-                int length, int nullCount, int offset) =>
-                new UInt8Array(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-        }
-
-        public UInt8Array(
-            ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
-            int length, int nullCount, int offset)
-            : this(new ArrayData(UInt8Type.Default, length, nullCount, offset, 
-                new[] { nullBitmapBuffer, valueBuffer })) { }
-
-        public UInt8Array(ArrayData data)
-            : base(data)
-        {
-            data.EnsureDataType(ArrowTypeId.UInt8);
-        }
-
-        public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
-
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Arrays/UnionArray.cs b/csharp/src/Apache.Arrow/Arrays/UnionArray.cs
deleted file mode 100644
index c1deb9b..0000000
--- a/csharp/src/Apache.Arrow/Arrays/UnionArray.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.Threading;
-
-namespace Apache.Arrow
-{
-    public abstract class UnionArray : IArrowArray
-    {
-        protected IReadOnlyList<IArrowArray> _fields;
-
-        public IReadOnlyList<IArrowArray> Fields =>
-            LazyInitializer.EnsureInitialized(ref _fields, InitializeFields);
-
-        public ArrayData Data { get; }
-
-        public UnionType Type => (UnionType)Data.DataType;
-
-        public UnionMode Mode => Type.Mode;
-
-        public ArrowBuffer TypeBuffer => Data.Buffers[0];
-
-        public ReadOnlySpan<byte> TypeIds => TypeBuffer.Span.Slice(Offset, Length);
-
-        public int Length => Data.Length;
-
-        public int Offset => Data.Offset;
-
-        public int NullCount => Data.GetNullCount();
-
-        public bool IsValid(int index) => NullCount == 0 || FieldIsValid(Fields[TypeIds[index]], index);
-
-        public bool IsNull(int index) => !IsValid(index);
-
-        protected UnionArray(ArrayData data) 
-        {
-            Data = data;
-            data.EnsureDataType(ArrowTypeId.Union);
-        }
-
-        public static UnionArray Create(ArrayData data)
-        {
-            return ((UnionType)data.DataType).Mode switch
-            {
-                UnionMode.Dense => new DenseUnionArray(data),
-                UnionMode.Sparse => new SparseUnionArray(data),
-                _ => throw new InvalidOperationException("unknown union mode in array creation")
-            };
-        }
-
-        public void Accept(IArrowArrayVisitor visitor) => Array.Accept(this, visitor);
-
-        protected abstract bool FieldIsValid(IArrowArray field, int index);
-
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                Data.Dispose();
-            }
-        }
-
-        protected static void ValidateMode(UnionMode expected, UnionMode actual)
-        {
-            if (expected != actual)
-            {
-                throw new ArgumentException(
-                    $"Specified union mode <{actual}> does not match expected mode <{expected}>",
-                    "Mode");
-            }
-        }
-
-        internal static int ComputeNullCount(ArrayData data)
-        {
-            return ((UnionType)data.DataType).Mode switch
-            {
-                UnionMode.Sparse => SparseUnionArray.ComputeNullCount(data),
-                UnionMode.Dense => DenseUnionArray.ComputeNullCount(data),
-                _ => throw new InvalidOperationException("unknown union mode in null count computation")
-            };
-        }
-
-        private IReadOnlyList<IArrowArray> InitializeFields()
-        {
-            IArrowArray[] result = new IArrowArray[Data.Children.Length];
-            for (int i = 0; i < Data.Children.Length; i++)
-            {
-                var childData = Data.Children[i];
-                if (Mode == UnionMode.Sparse && (Data.Offset != 0 || childData.Length != Data.Length))
-                {
-                    // We only slice the child data for sparse mode,
-                    // so that the sliced value offsets remain valid in dense mode
-                    childData = childData.Slice(Data.Offset, Data.Length);
-                }
-                result[i] = ArrowArrayFactory.BuildArray(childData);
-            }
-            return result;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/ArrowBuffer.BitmapBuilder.cs b/csharp/src/Apache.Arrow/ArrowBuffer.BitmapBuilder.cs
deleted file mode 100644
index 6bdd131..0000000
--- a/csharp/src/Apache.Arrow/ArrowBuffer.BitmapBuilder.cs
+++ /dev/null
@@ -1,332 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using Apache.Arrow.Memory;
-
-namespace Apache.Arrow
-{
-    public partial struct ArrowBuffer
-    {
-        /// <summary>
-        /// The <see cref="BitmapBuilder"/> class is a complement to <see cref="ArrowBuffer.Builder{T}"/>
-        /// and is designed for boolean fields, which are efficiently bit-packed into byte-aligned memory.
-        /// </summary>
-        public class BitmapBuilder
-        {
-            private const int DefaultBitCapacity = 64;
-
-            /// <summary>
-            /// Gets the number of bits that can be contained in the memory allocated by the current instance.
-            /// </summary>
-            public int Capacity { get; private set; }
-
-            /// <summary>
-            /// Gets the number of bits currently appended.
-            /// </summary>
-            public int Length { get; private set; }
-
-            /// <summary>
-            /// Gets the raw byte memory underpinning the builder.
-            /// </summary>
-            public Memory<byte> Memory { get; private set; }
-
-            /// <summary>
-            /// Gets the span of (bit-packed byte) memory underpinning the builder.
-            /// </summary>
-            public Span<byte> Span => Memory.Span;
-
-            /// <summary>
-            /// Gets the number of set bits (i.e. set to 1).
-            /// </summary>
-            public int SetBitCount { get; private set; }
-
-            /// <summary>
-            /// Gets the number of unset bits (i.e. set to 0).
-            /// </summary>
-            public int UnsetBitCount => Length - SetBitCount;
-
-            /// <summary>
-            /// Creates an instance of the <see cref="BitmapBuilder"/> class.
-            /// </summary>
-            /// <param name="capacity">Number of bits of initial capacity to reserve.</param>
-            public BitmapBuilder(int capacity = DefaultBitCapacity)
-            {
-                Memory = new byte[BitUtility.ByteCount(capacity)];
-                Capacity = capacity;
-            }
-
-            /// <summary>
-            /// Append a single bit.
-            /// </summary>
-            /// <param name="value">Bit to append.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public BitmapBuilder Append(bool value)
-            {
-                if (Length % 8 == 0)
-                {
-                    // Append a new byte to the buffer when needed.
-                    EnsureAdditionalCapacity(1);
-                }
-
-                BitUtility.SetBit(Span, Length, value);
-                Length++;
-                SetBitCount += value ? 1 : 0;
-                return this;
-            }
-
-            /// <summary>
-            /// Append a span of bits.
-            /// </summary>
-            /// <param name="source">Source of bits to append.</param>
-            /// <param name="validBits">Number of valid bits in the source span.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public BitmapBuilder Append(ReadOnlySpan<byte> source, int validBits)
-            {                
-                if (!source.IsEmpty && validBits > source.Length * 8)
-                    throw new ArgumentException($"Number of valid bits ({validBits}) cannot be greater than the source span length ({source.Length * 8} bits).", nameof(validBits));
-                
-                // Check if memory copy can be used from the source array (performance optimization for byte-aligned coping)
-                if (!source.IsEmpty && Length % 8 == 0)
-                {
-                    EnsureAdditionalCapacity(validBits);
-                    source.Slice(0, BitUtility.ByteCount(validBits)).CopyTo(Span.Slice(Length / 8));
-                    
-                    Length += validBits;
-                    SetBitCount += BitUtility.CountBits(source, 0, validBits);
-                }
-                else
-                {
-                    for (int i = 0; i < validBits; i++)
-                    {
-                        Append(source.IsEmpty || BitUtility.GetBit(source, i));
-                    }
-                }
-
-                return this;
-            }
-
-            /// <summary>
-            /// Append multiple bits.
-            /// </summary>
-            /// <param name="values">Bits to append.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public BitmapBuilder AppendRange(IEnumerable<bool> values)
-            {
-                if (values != null)
-                {
-                    foreach (var v in values)
-                    {
-                        Append(v);
-                    }
-                }
-
-                return this;
-            }
-
-            /// <summary>
-            /// Append multiple bits.
-            /// </summary>
-            /// <param name="value">Value of bits to append.</param>
-            /// <param name="length">Number of times the value should be added.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public BitmapBuilder AppendRange(bool value, int length)
-            {
-                if (length < 0)
-                    throw new ArgumentOutOfRangeException(nameof(length));
-
-                EnsureAdditionalCapacity(length);
-                Span<byte> span = Span;
-                BitUtility.SetBits(span, Length, length, value);
-
-                Length += length;
-                SetBitCount += value ? length : 0;
-
-                return this;
-            }
-
-            /// <summary>
-            /// Toggle the bit at a particular index.
-            /// </summary>
-            /// <param name="index">Index of bit to toggle.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public BitmapBuilder Toggle(int index)
-            {
-                CheckIndex(index);
-                bool priorValue = BitUtility.GetBit(Span, index);
-                SetBitCount += priorValue ? -1 : 1;
-                BitUtility.ToggleBit(Span, index);
-                return this;
-            }
-
-            /// <summary>
-            /// Set the bit at a particular index to 1.
-            /// </summary>
-            /// <param name="index">Index of bit to set.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public BitmapBuilder Set(int index)
-            {
-                CheckIndex(index);
-                bool priorValue = BitUtility.GetBit(Span, index);
-                SetBitCount += priorValue ? 0 : 1;
-                BitUtility.SetBit(Span, index);
-                return this;
-            }
-
-            /// <summary>
-            /// Set the bit at a particular index to a given value.
-            /// </summary>
-            /// <param name="index">Index of bit to set/unset.</param>
-            /// <param name="value">Value of bit.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public BitmapBuilder Set(int index, bool value)
-            {
-                CheckIndex(index);
-                bool priorValue = BitUtility.GetBit(Span, index);
-                SetBitCount -= priorValue ? 1 : 0;
-                SetBitCount += value ? 1 : 0;
-                BitUtility.SetBit(Span, index, value);
-                return this;
-            }
-
-            /// <summary>
-            /// Swap the bits at two given indices.
-            /// </summary>
-            /// <param name="i">First index.</param>
-            /// <param name="j">Second index.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public BitmapBuilder Swap(int i, int j)
-            {
-                CheckIndex(i);
-                CheckIndex(j);
-                bool bi = BitUtility.GetBit(Span, i);
-                bool bj = BitUtility.GetBit(Span, j);
-                BitUtility.SetBit(Span, i, bj);
-                BitUtility.SetBit(Span, j, bi);
-                return this;
-            }
-
-            /// <summary>
-            /// Reserve a given number of bits' additional capacity.
-            /// </summary>
-            /// <param name="additionalCapacity">Number of bits of required additional capacity.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public BitmapBuilder Reserve(int additionalCapacity)
-            {
-                if (additionalCapacity < 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(additionalCapacity));
-                }
-
-                EnsureAdditionalCapacity(additionalCapacity);
-                return this;
-            }
-
-            /// <summary>
-            /// Resize the buffer to a given size.
-            /// </summary>
-            /// <remarks>
-            /// Note that if the required capacity is larger than the current length of the populated buffer so far,
-            /// the buffer's contents in the new, expanded region are undefined.
-            /// </remarks>
-            /// <remarks>
-            /// Note that if the required capacity is smaller than the current length of the populated buffer so far,
-            /// the buffer will be truncated and items at the end of the buffer will be lost.
-            /// </remarks>
-            /// <param name="capacity">Number of bits of required capacity.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public BitmapBuilder Resize(int capacity)
-            {
-                if (capacity < 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(capacity), "Capacity must be non-negative");
-                }
-
-                EnsureCapacity(capacity);
-                Length = capacity;
-
-                SetBitCount = BitUtility.CountBits(Span, 0, Length);
-
-                return this;
-            }
-
-            /// <summary>
-            /// Clear all contents appended so far.
-            /// </summary>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public BitmapBuilder Clear()
-            {
-                Span.Fill(default);
-                Length = 0;
-                SetBitCount = 0;
-                return this;
-            }
-
-            /// <summary>
-            /// Build an Arrow buffer from the appended contents so far.
-            /// </summary>
-            /// <param name="allocator">Optional memory allocator.</param>
-            /// <returns>Returns an <see cref="ArrowBuffer"/> object.</returns>
-            public ArrowBuffer Build(MemoryAllocator allocator = default)
-            {
-                int bufferLength = checked((int)BitUtility.RoundUpToMultipleOf64(Memory.Length));
-                var memoryAllocator = allocator ?? MemoryAllocator.Default.Value;
-                var memoryOwner = memoryAllocator.Allocate(bufferLength);
-                Memory.Slice(0, Memory.Length).CopyTo(memoryOwner.Memory);
-                return new ArrowBuffer(memoryOwner);
-            }
-
-            private void CheckIndex(int index)
-            {
-                if (index < 0 || index >= Length)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(index));
-                }
-            }
-
-            private void EnsureAdditionalCapacity(int additionalCapacity)
-            {
-                EnsureCapacity(checked(Length + additionalCapacity));
-            }
-
-            private void EnsureCapacity(int requiredCapacity)
-            {
-                if (requiredCapacity > Capacity)
-                {
-                    // TODO: specifiable growth strategy
-                    // Double the length of the in-memory array, or use the byte count of the capacity, whichever is
-                    // greater.
-                    int byteCount = Math.Max(BitUtility.ByteCount(requiredCapacity), Memory.Length * 2);
-                    Reallocate(byteCount);
-                    Capacity = byteCount * 8;
-                }
-            }
-
-            private void Reallocate(int numBytes)
-            {
-                if (numBytes != 0)
-                {
-                    Debug.Assert(numBytes > Memory.Length);
-                    var memory = new Memory<byte>(new byte[numBytes]);
-                    Memory.CopyTo(memory);
-
-                    Memory = memory;
-                }
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/ArrowBuffer.Builder.cs b/csharp/src/Apache.Arrow/ArrowBuffer.Builder.cs
deleted file mode 100644
index 7c03027..0000000
--- a/csharp/src/Apache.Arrow/ArrowBuffer.Builder.cs
+++ /dev/null
@@ -1,255 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using System;
-using System.Buffers;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-
-namespace Apache.Arrow
-{
-    public partial struct ArrowBuffer
-    {
-        /// <summary>
-        /// The <see cref="Builder{T}"/> class is able to append value-type items, with fluent-style methods, to build
-        /// up an <see cref="ArrowBuffer"/> of contiguous items.
-        /// </summary>
-        /// <remarks>
-        /// Note that <see cref="bool"/> is not supported as a generic type argument for this class.  Please use
-        /// <see cref="BitmapBuilder"/> instead.
-        /// </remarks>
-        /// <typeparam name="T">Value-type of item to build into a buffer.</typeparam>
-        public class Builder<T>
-            where T : struct
-        {
-            private const int DefaultCapacity = 8;
-
-            private readonly int _size;
-
-            /// <summary>
-            /// Gets the number of items that can be contained in the memory allocated by the current instance.
-            /// </summary>
-            public int Capacity => Memory.Length / _size;
-
-            /// <summary>
-            /// Gets the number of items currently appended.
-            /// </summary>
-            public int Length { get; private set; }
-
-            /// <summary>
-            /// Gets the raw byte memory underpinning the builder.
-            /// </summary>
-            public Memory<byte> Memory { get; private set; }
-
-            /// <summary>
-            /// Gets the span of memory underpinning the builder.
-            /// </summary>
-            public Span<T> Span
-            {
-                [MethodImpl(MethodImplOptions.AggressiveInlining)]
-                get => Memory.Span.CastTo<T>();
-            }
-
-            /// <summary>
-            /// Creates an instance of the <see cref="Builder{T}"/> class.
-            /// </summary>
-            /// <param name="capacity">Number of items of initial capacity to reserve.</param>
-            public Builder(int capacity = DefaultCapacity)
-            {
-                // Using `bool` as the template argument, if used in an unrestricted fashion, would result in a buffer
-                // with inappropriate contents being produced.  Because C# does not support template specialisation,
-                // and because generic type constraints do not support negation, we will throw a runtime error to
-                // indicate that such a template type is not supported.
-                if (typeof(T) == typeof(bool))
-                {
-                    throw new NotSupportedException(
-                        $"An instance of {nameof(Builder<T>)} cannot be instantiated, as `bool` is not an " +
-                        $"appropriate generic type to use with this class - please use {nameof(BitmapBuilder)} " +
-                        $"instead");
-                }
-
-                _size = Unsafe.SizeOf<T>();
-
-                Memory = new byte[capacity * _size];
-                Length = 0;
-            }
-
-            /// <summary>
-            /// Append a buffer, assumed to contain items of the same type.
-            /// </summary>
-            /// <param name="buffer">Buffer to append.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public Builder<T> Append(ArrowBuffer buffer)
-            {
-                Append(buffer.Span.CastTo<T>());
-                return this;
-            }
-
-            /// <summary>
-            /// Append a single item.
-            /// </summary>
-            /// <param name="value">Item to append.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public Builder<T> Append(T value)
-            {
-                EnsureAdditionalCapacity(1);
-                Span[Length++] = value;
-                return this;
-            }
-
-            /// <summary>
-            /// Append a span of items.
-            /// </summary>
-            /// <param name="source">Source of item span.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public Builder<T> Append(ReadOnlySpan<T> source)
-            {
-                EnsureAdditionalCapacity(source.Length);
-                source.CopyTo(Span.Slice(Length, source.Length));
-                Length += source.Length;
-                return this;
-            }
-
-            /// <summary>
-            /// Append a number of items.
-            /// </summary>
-            /// <param name="values">Items to append.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public Builder<T> AppendRange(IEnumerable<T> values)
-            {
-                if (values != null)
-                {
-                    foreach (T v in values)
-                    {
-                        Append(v);
-                    }
-                }
-
-                return this;
-            }
-
-            /// <summary>
-            /// Reserve a given number of items' additional capacity.
-            /// </summary>
-            /// <param name="additionalCapacity">Number of items of required additional capacity.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public Builder<T> Reserve(int additionalCapacity)
-            {
-                if (additionalCapacity < 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(additionalCapacity));
-                }
-
-                EnsureAdditionalCapacity(additionalCapacity);
-                return this;
-            }
-
-            /// <summary>
-            /// Resize the buffer to a given size.
-            /// </summary>
-            /// <remarks>
-            /// Note that if the required capacity is larger than the current length of the populated buffer so far,
-            /// the buffer's contents in the new, expanded region are undefined.
-            /// </remarks>
-            /// <remarks>
-            /// Note that if the required capacity is smaller than the current length of the populated buffer so far,
-            /// the buffer will be truncated and items at the end of the buffer will be lost.
-            /// </remarks>
-            /// <param name="capacity">Number of items of required capacity.</param>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public Builder<T> Resize(int capacity)
-            {
-                if (capacity < 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(capacity), "Capacity must be non-negative");
-                }
-
-                EnsureCapacity(capacity);
-                Length = capacity;
-
-                return this;
-            }
-
-            /// <summary>
-            /// Clear all contents appended so far.
-            /// </summary>
-            /// <returns>Returns the builder (for fluent-style composition).</returns>
-            public Builder<T> Clear()
-            {
-                Span.Fill(default);
-                Length = 0;
-                return this;
-            }
-
-            /// <summary>
-            /// Build an Arrow buffer from the appended contents so far.
-            /// </summary>
-            /// <param name="allocator">Optional memory allocator.</param>
-            /// <returns>Returns an <see cref="ArrowBuffer"/> object.</returns>
-            public ArrowBuffer Build(MemoryAllocator allocator = default)
-            {
-                return Build(64, allocator);
-            }
-
-            /// <summary>
-            /// Build an Arrow buffer from the appended contents so far of the specified byte size.
-            /// </summary>
-            /// <param name="allocator">Optional memory allocator.</param>
-            /// <returns>Returns an <see cref="ArrowBuffer"/> object.</returns>
-            internal ArrowBuffer Build(int byteSize, MemoryAllocator allocator = default)
-            {
-                int currentBytesLength = Length * _size;
-                int bufferLength = checked((int)BitUtility.RoundUpToMultiplePowerOfTwo(currentBytesLength, byteSize));
-
-                MemoryAllocator memoryAllocator = allocator ?? MemoryAllocator.Default.Value;
-                IMemoryOwner<byte> memoryOwner = memoryAllocator.Allocate(bufferLength);
-                Memory.Slice(0, currentBytesLength).CopyTo(memoryOwner.Memory);
-
-                return new ArrowBuffer(memoryOwner);
-            }
-
-            private void EnsureAdditionalCapacity(int additionalCapacity)
-            {
-                EnsureCapacity(checked(Length + additionalCapacity));
-            }
-
-            private void EnsureCapacity(int requiredCapacity)
-            {
-                if (requiredCapacity > Capacity)
-                {
-                    // TODO: specifiable growth strategy
-                    // Double the length of the in-memory array, or use the byte count of the capacity, whichever is
-                    // greater.
-                    int capacity = Math.Max(requiredCapacity * _size, Memory.Length * 2);
-                    Reallocate(capacity);
-                }
-            }
-
-            private void Reallocate(int numBytes)
-            {
-                if (numBytes != 0)
-                {
-                    var memory = new Memory<byte>(new byte[numBytes]);
-                    Memory.CopyTo(memory);
-
-                    Memory = memory;
-                }
-            }
-
-        }
-
-    }
-}
diff --git a/csharp/src/Apache.Arrow/ArrowBuffer.cs b/csharp/src/Apache.Arrow/ArrowBuffer.cs
deleted file mode 100644
index ef98bdc..0000000
--- a/csharp/src/Apache.Arrow/ArrowBuffer.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.Runtime.CompilerServices;
-using Apache.Arrow.Memory;
-
-namespace Apache.Arrow
-{
-    public readonly partial struct ArrowBuffer : IEquatable<ArrowBuffer>, IDisposable
-    {
-        private readonly IMemoryOwner<byte> _memoryOwner;
-        private readonly ReadOnlyMemory<byte> _memory;
-
-        public static ArrowBuffer Empty => new ArrowBuffer(Memory<byte>.Empty);
-
-        public ArrowBuffer(ReadOnlyMemory<byte> data)
-        {
-            _memoryOwner = null;
-            _memory = data;
-        }
-
-        internal ArrowBuffer(IMemoryOwner<byte> memoryOwner)
-        {
-            // When wrapping an IMemoryOwner, don't cache the Memory<byte>
-            // since the owner may be disposed, and the cached Memory would
-            // be invalid.
-
-            _memoryOwner = memoryOwner;
-            _memory = Memory<byte>.Empty;
-        }
-
-        public ReadOnlyMemory<byte> Memory =>
-            _memoryOwner != null ? _memoryOwner.Memory : _memory;
-
-        public bool IsEmpty => Memory.IsEmpty;
-
-        public int Length => Memory.Length;
-
-        public ReadOnlySpan<byte> Span
-        {
-            [MethodImpl(MethodImplOptions.AggressiveInlining)]
-            get => Memory.Span;
-        }
-
-        public ArrowBuffer Clone(MemoryAllocator allocator = default)
-        {
-            return Span.Length == 0 ? Empty : new Builder<byte>(Span.Length)
-                .Append(Span)
-                .Build(allocator);
-        }
-
-        public bool Equals(ArrowBuffer other)
-        {
-            return Span.SequenceEqual(other.Span);
-        }
-
-        public void Dispose()
-        {
-            _memoryOwner?.Dispose();
-        }
-
-        internal bool TryExport(ExportedAllocationOwner newOwner, out IntPtr ptr)
-        {
-            if (IsEmpty)
-            {
-                // _memoryOwner could be anything (for example null or a NullMemoryOwner), but it doesn't matter here
-                ptr = IntPtr.Zero;
-                return true;
-            }
-
-            if (_memoryOwner is IOwnableAllocation ownable && ownable.TryAcquire(out ptr, out int offset, out int length))
-            {
-                newOwner.Acquire(ptr, offset, length);
-                ptr += offset;
-                return true;
-            }
-
-            ptr = IntPtr.Zero;
-            return false;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/BitUtility.cs b/csharp/src/Apache.Arrow/BitUtility.cs
deleted file mode 100644
index d9ad2e6..0000000
--- a/csharp/src/Apache.Arrow/BitUtility.cs
+++ /dev/null
@@ -1,269 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace Apache.Arrow
-{
-    public static class BitUtility
-    {
-        private static ReadOnlySpan<byte> PopcountTable => new byte[] {
-            0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-            1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-            1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-            2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-            1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-            2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-            2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-            3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
-        };
-
-        private static ReadOnlySpan<byte> BitMask => new byte[] {
-            1, 2, 4, 8, 16, 32, 64, 128
-        };
-
-        public static bool GetBit(byte data, int index) =>
-            ((data >> index) & 1) != 0;
-
-        public static bool GetBit(ReadOnlySpan<byte> data, int index) =>
-            (data[index / 8] & BitMask[index % 8]) != 0;
-
-        public static void ClearBit(Span<byte> data, int index)
-        {
-            data[index / 8] &= (byte) ~BitMask[index % 8];
-        }
-
-        public static void SetBit(Span<byte> data, int index)
-        {
-            data[index / 8] |= BitMask[index % 8];
-        }
-
-        public static void SetBit(Span<byte> data, int index, bool value)
-        {
-            int idx = index / 8;
-            int mod = index % 8;
-            data[idx] = value
-                ? (byte)(data[idx] | BitMask[mod])
-                : (byte)(data[idx] & ~BitMask[mod]);
-        }
-
-        /// <summary>
-        /// Set the number of bits in a span of bytes starting
-        /// at a specific index, and limiting to length.
-        /// </summary>
-        /// <param name="data">Span to set bits value.</param>
-        /// <param name="index">Bit index to start counting from.</param>
-        /// <param name="length">Maximum of bits in the span to consider.</param>
-        internal static void SetBits(Span<byte> data, int index, int length, bool value)
-        {
-            if (length == 0)
-                return;
-
-            int endBitIndex = checked(index + length - 1);
-                        
-            // Use simpler method if there aren't many values
-            if (length < 20)
-            {
-                for (int i = index; i <= endBitIndex; i++)
-                {
-                    SetBit(data, i, value);
-                }
-                return;
-            }
-            
-            // Otherwise do the work to figure out how to copy whole bytes
-            int startByteIndex = index / 8;
-            int startBitOffset = index % 8;
-            int endByteIndex = endBitIndex / 8;
-            int endBitOffset = endBitIndex % 8;
-                        
-            // If the starting index and ending index are not byte-aligned,
-            // we'll need to set bits the slow way. If they are
-            // byte-aligned, and for all other bytes in the 'middle', we
-            // can use a faster byte-aligned set.
-            int fullByteStartIndex = startBitOffset == 0 ? startByteIndex : startByteIndex + 1;
-            int fullByteEndIndex = endBitOffset == 7 ? endByteIndex : endByteIndex - 1;
-
-            // Bits we will be using to finish up the first byte
-            if (startBitOffset != 0)
-            {
-                Span<byte> slice = data.Slice(startByteIndex, 1);
-                for (int i = startBitOffset; i <= 7; i++)
-                    SetBit(slice, i, value);
-            }
-
-            if (fullByteEndIndex >= fullByteStartIndex)
-            {
-                Span<byte> slice = data.Slice(fullByteStartIndex, fullByteEndIndex - fullByteStartIndex + 1);
-                byte fill = (byte)(value ? 0xFF : 0x00);
-
-                slice.Fill(fill);
-            }
-
-            if (endBitOffset != 7)
-            {
-                Span<byte> slice = data.Slice(endByteIndex, 1);
-                for (int i = 0; i <= endBitOffset; i++)
-                    SetBit(slice, i, value);
-            }
-        }
-
-        public static void ToggleBit(Span<byte> data, int index)
-        {
-            data[index / 8] ^= BitMask[index % 8];
-        }
-
-        /// <summary>
-        /// Counts the number of set bits in a span of bytes starting
-        /// at a specific bit index.
-        /// </summary>
-        /// <param name="data">Span to count bits.</param>
-        /// <param name="index">Bit index to start counting from.</param>
-        /// <returns>Count of set (one) bits.</returns>
-        public static int CountBits(ReadOnlySpan<byte> data, int index) =>
-            CountBits(data, index, data.Length * 8 - index);
-
-        /// <summary>
-        /// Counts the number of set bits in a span of bytes starting
-        /// at a specific bit index, and limiting to a certain number of bits
-        /// in the span.
-        /// </summary>
-        /// <param name="data">Span to count bits.</param>
-        /// <param name="index">Bit index to start counting from.</param>
-        /// <param name="length">Maximum of bits in the span to consider.</param>
-        /// <returns>Count of set (one) bits.</returns>
-        public static int CountBits(ReadOnlySpan<byte> data, int index, int length)
-        {
-            int startByteIndex = index / 8;
-            int startBitOffset = index % 8;
-
-            int endBitIndex = index + length - 1;
-
-            int endByteIndex = endBitIndex / 8;
-            int endBitOffset = endBitIndex % 8;
-
-            if (startBitOffset < 0)
-                return 0;
-
-            int count = 0;
-            if (startByteIndex == endByteIndex)
-            {
-                // Range starts and ends within the same byte.
-                ReadOnlySpan<byte> slice = data.Slice(startByteIndex, 1);
-                for (int i = startBitOffset; i <= endBitOffset; i++)
-                    count += GetBit(slice, i) ? 1 : 0;
-
-                return count;
-            }
-
-            // If the starting index and ending index are not byte-aligned,
-            // we'll need to count bits the slow way. If they are
-            // byte-aligned, and for all other bytes in the 'middle', we
-            // can use a faster byte-aligned count.
-            int fullByteStartIndex = startBitOffset == 0 ? startByteIndex : startByteIndex + 1;
-            int fullByteEndIndex = endBitOffset == 7 ? endByteIndex : endByteIndex - 1;
-
-            if (startBitOffset != 0)
-            {
-                ReadOnlySpan<byte> slice = data.Slice(startByteIndex, 1);
-                for (int i = startBitOffset; i <= 7; i++)
-                    count += GetBit(slice, i) ? 1 : 0;
-            }
-
-            if (fullByteEndIndex >= fullByteStartIndex)
-            {
-                ReadOnlySpan<byte> slice = data.Slice(fullByteStartIndex, fullByteEndIndex - fullByteStartIndex + 1);
-                count += CountBits(slice);
-            }
-
-            if (endBitOffset != 7)
-            {
-                ReadOnlySpan<byte> slice = data.Slice(endByteIndex, 1);
-                for (int i = 0; i <= endBitOffset; i++)
-                    count += GetBit(slice, i) ? 1 : 0;
-            }
-
-            return count;
-        }
-
-        /// <summary>
-        /// Counts the number of set bits in a span of bytes.
-        /// </summary>
-        /// <param name="data">Span to count bits.</param>
-        /// <returns>Count of set (one) bits.</returns>
-        public static int CountBits(ReadOnlySpan<byte> data)
-        {
-            int count = 0;
-            foreach (byte t in data)
-                count += PopcountTable[t];
-            return count;
-        }
-
-        /// <summary>
-        /// Rounds an integer to the nearest multiple of 64.
-        /// </summary>
-        /// <param name="n">Integer to round.</param>
-        /// <returns>Integer rounded to the nearest multiple of 64.</returns>
-        public static long RoundUpToMultipleOf64(long n) =>
-            RoundUpToMultiplePowerOfTwo(n, 64);
-
-        /// <summary>
-        /// Rounds an integer to the nearest multiple of 8.
-        /// </summary>
-        /// <param name="n">Integer to round.</param>
-        /// <returns>Integer rounded to the nearest multiple of 8.</returns>
-        public static long RoundUpToMultipleOf8(long n) =>
-            RoundUpToMultiplePowerOfTwo(n, 8);
-
-        /// <summary>
-        /// Rounds an integer up to the nearest multiple of factor, where
-        /// factor must be a power of two.
-        ///
-        /// This function does not throw when the factor is not a power of two.
-        /// </summary>
-        /// <param name="n">Integer to round up.</param>
-        /// <param name="factor">Power of two factor to round up to.</param>
-        /// <returns>Integer rounded up to the nearest power of two.</returns>
-        public static long RoundUpToMultiplePowerOfTwo(long n, int factor)
-        {
-            // Assert that factor is a power of two.
-            Debug.Assert(factor > 0 && (factor & (factor - 1)) == 0);
-            return (n + (factor - 1)) & ~(factor - 1);
-        }
-
-        internal static bool IsMultipleOf8(long n) => n % 8 == 0;
-
-        /// <summary>
-        /// Calculates the number of bytes required to store n bits.
-        /// </summary>
-        /// <param name="n">Number of bits</param>
-        /// <returns>Number of bytes</returns>
-        public static int ByteCount(int n)
-        {
-            Debug.Assert(n >= 0);
-            return n / 8 + (n % 8 != 0 ? 1 : 0); // ceil(n / 8)
-        }
-
-        internal static int ReadInt32(ReadOnlyMemory<byte> value)
-        {
-            Debug.Assert(value.Length >= sizeof(int));
-
-            return Unsafe.ReadUnaligned<int>(ref MemoryMarshal.GetReference(value.Span));
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/C/CArrowArray.cs b/csharp/src/Apache.Arrow/C/CArrowArray.cs
deleted file mode 100644
index 882ca8c..0000000
--- a/csharp/src/Apache.Arrow/C/CArrowArray.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-using System;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace Apache.Arrow.C
-{
-    /// <summary>
-    /// An Arrow C Data Interface Schema, which represents the data in an exported array or record batch.
-    /// </summary>
-    /// <remarks>
-    /// This is used to export <see cref="RecordBatch"/> or <see cref="IArrowArray"/> to other languages. It matches
-    /// the layout of the ArrowArray struct described in https://github.com/apache/arrow/blob/main/cpp/src/arrow/c/abi.h.
-    /// </remarks>
-    [StructLayout(LayoutKind.Sequential)]
-    public unsafe struct CArrowArray
-    {
-        public long length;
-        public long null_count;
-        public long offset;
-        public long n_buffers;
-        public long n_children;
-        public byte** buffers;
-        public CArrowArray** children;
-        public CArrowArray* dictionary;
-#if NET5_0_OR_GREATER
-        internal delegate* unmanaged<CArrowArray*, void> release;
-#else
-        internal IntPtr release;
-#endif
-        public void* private_data;
-
-        /// <summary>
-        /// Allocate and zero-initialize an unmanaged pointer of this type.
-        /// </summary>
-        /// <remarks>
-        /// This pointer must later be freed by <see cref="Free"/>.
-        /// </remarks>
-        public static CArrowArray* Create()
-        {
-            var ptr = (CArrowArray*)Marshal.AllocHGlobal(sizeof(CArrowArray));
-
-            *ptr = default;
-
-            return ptr;
-        }
-
-        /// <summary>
-        /// Free a pointer that was allocated in <see cref="Create"/>.
-        /// </summary>
-        /// <remarks>
-        /// Do not call this on a pointer that was allocated elsewhere.
-        /// </remarks>
-        public static void Free(CArrowArray* array)
-        {
-            CallReleaseFunc(array);
-            Marshal.FreeHGlobal((IntPtr)array);
-        }
-
-        /// <summary>
-        /// Call the array's release func, if set.
-        /// </summary>
-        public static void CallReleaseFunc(CArrowArray* array)
-        {
-            if (array->release != default)
-            {
-                // Call release if not already called.
-#if NET5_0_OR_GREATER
-                array->release(array);
-#else
-                Marshal.GetDelegateForFunctionPointer<CArrowArrayExporter.ReleaseArrowArray>(array->release)(array);
-#endif
-                Debug.Assert(array->release == default,
-                             "Calling the CArrowArray release func should have set it to NULL");
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/C/CArrowArrayExporter.cs b/csharp/src/Apache.Arrow/C/CArrowArrayExporter.cs
deleted file mode 100644
index b241fdf..0000000
--- a/csharp/src/Apache.Arrow/C/CArrowArrayExporter.cs
+++ /dev/null
@@ -1,254 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-using System;
-using System.Buffers;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow.C
-{
-    public static class CArrowArrayExporter
-    {
-#if NET5_0_OR_GREATER
-        private static unsafe delegate* unmanaged<CArrowArray*, void> ReleaseArrayPtr => &ReleaseArray;
-#else
-        internal unsafe delegate void ReleaseArrowArray(CArrowArray* cArray);
-        private static unsafe readonly NativeDelegate<ReleaseArrowArray> s_releaseArray = new NativeDelegate<ReleaseArrowArray>(ReleaseArray);
-        private static IntPtr ReleaseArrayPtr => s_releaseArray.Pointer;
-#endif
-        /// <summary>
-        /// Export an <see cref="IArrowArray"/> to a <see cref="CArrowArray"/>. Whether or not the
-        /// export succeeds, the original array becomes invalid. Clone an array to continue using it
-        /// after a copy has been exported.
-        /// </summary>
-        /// <param name="array">The array to export</param>
-        /// <param name="cArray">An allocated but uninitialized CArrowArray pointer.</param>
-        /// <example>
-        /// <code>
-        /// CArrowArray* exportPtr = CArrowArray.Create();
-        /// CArrowArrayExporter.ExportArray(array, exportPtr);
-        /// foreign_import_function(exportPtr);
-        /// </code>
-        /// </example>
-        public static unsafe void ExportArray(IArrowArray array, CArrowArray* cArray)
-        {
-            if (array == null)
-            {
-                throw new ArgumentNullException(nameof(array));
-            }
-            if (cArray == null)
-            {
-                throw new ArgumentNullException(nameof(cArray));
-            }
-
-            ExportedAllocationOwner allocationOwner = new ExportedAllocationOwner();
-            try
-            {
-                ConvertArray(allocationOwner, array.Data, cArray);
-                allocationOwner = null;
-            }
-            finally
-            {
-                allocationOwner?.Dispose();
-            }
-        }
-
-        /// <summary>
-        /// Export a <see cref="RecordBatch"/> to a <see cref="CArrowArray"/>. Whether or not the
-        /// export succeeds, the original record batch becomes invalid. Clone the batch to continue using it
-        /// after a copy has been exported.
-        /// </summary>
-        /// <param name="batch">The record batch to export</param>
-        /// <param name="cArray">An allocated but uninitialized CArrowArray pointer.</param>
-        /// <example>
-        /// <code>
-        /// CArrowArray* exportPtr = CArrowArray.Create();
-        /// CArrowArrayExporter.ExportRecordBatch(batch, exportPtr);
-        /// foreign_import_function(exportPtr);
-        /// </code>
-        /// </example>
-        public static unsafe void ExportRecordBatch(RecordBatch batch, CArrowArray* cArray)
-        {
-            if (batch == null)
-            {
-                throw new ArgumentNullException(nameof(batch));
-            }
-            if (cArray == null)
-            {
-                throw new ArgumentNullException(nameof(cArray));
-            }
-            if (cArray->release != default)
-            {
-                throw new ArgumentException("Cannot export array to a struct that is already initialized.", nameof(cArray));
-            }
-
-            ExportedAllocationOwner allocationOwner = new ExportedAllocationOwner();
-            try
-            {
-                ConvertRecordBatch(allocationOwner, batch, cArray);
-                allocationOwner = null;
-            }
-            finally
-            {
-                allocationOwner?.Dispose();
-            }
-        }
-
-        private unsafe static void ConvertArray(ExportedAllocationOwner sharedOwner, ArrayData array, CArrowArray* cArray)
-        {
-            cArray->length = array.Length;
-            cArray->offset = array.Offset;
-            cArray->null_count = array.NullCount; // The C Data interface allows the null count to be -1
-            cArray->release = ReleaseArrayPtr;
-            cArray->private_data = MakePrivateData(sharedOwner);
-
-            cArray->n_buffers = array.Buffers?.Length ?? 0;
-            cArray->buffers = null;
-            if (cArray->n_buffers > 0)
-            {
-                long* lengths = null;
-                int bufferCount = array.Buffers.Length;
-                if (array.DataType.TypeId == ArrowTypeId.BinaryView || array.DataType.TypeId == ArrowTypeId.StringView)
-                {
-                    lengths = (long*)sharedOwner.Allocate(8 * bufferCount); // overallocation to avoid edge case
-                    bufferCount++;
-                    cArray->n_buffers++;
-                }
-
-                cArray->buffers = (byte**)sharedOwner.Allocate(bufferCount * IntPtr.Size);
-                for (int i = 0; i < array.Buffers.Length; i++)
-                {
-                    ArrowBuffer buffer = array.Buffers[i];
-                    IntPtr ptr;
-                    if (!buffer.TryExport(sharedOwner, out ptr))
-                    {
-                        throw new NotSupportedException($"An ArrowArray of type {array.DataType.TypeId} could not be exported: failed on buffer #{i}");
-                    }
-                    cArray->buffers[i] = (byte*)ptr;
-                    if (lengths != null && i >= 2)
-                    {
-                        lengths[i - 2] = array.Buffers[i].Length;
-                    }
-                }
-
-                if (lengths != null)
-                {
-                    cArray->buffers[array.Buffers.Length] = (byte*)lengths;
-                }
-            }
-
-            cArray->n_children = array.Children?.Length ?? 0;
-            cArray->children = null;
-            if (cArray->n_children > 0)
-            {
-                cArray->children = (CArrowArray**)sharedOwner.Allocate(IntPtr.Size * array.Children.Length);
-                for (int i = 0; i < array.Children.Length; i++)
-                {
-                    cArray->children[i] = MakeArray(sharedOwner);
-                    ConvertArray(sharedOwner, array.Children[i], cArray->children[i]);
-                }
-            }
-
-            cArray->dictionary = null;
-            if (array.Dictionary != null)
-            {
-                cArray->dictionary = MakeArray(sharedOwner);
-                ConvertArray(sharedOwner, array.Dictionary, cArray->dictionary);
-            }
-        }
-
-        private unsafe static void ConvertRecordBatch(ExportedAllocationOwner sharedOwner, RecordBatch batch, CArrowArray* cArray)
-        {
-            cArray->length = batch.Length;
-            cArray->offset = 0;
-            cArray->null_count = 0;
-            cArray->release = ReleaseArrayPtr;
-            cArray->private_data = MakePrivateData(sharedOwner);
-
-            cArray->n_buffers = 1;
-            cArray->buffers = (byte**)sharedOwner.Allocate(IntPtr.Size);
-
-            cArray->n_children = batch.ColumnCount;
-            cArray->children = null;
-            // XXX sharing the same ExportedAllocationOwner for all columns
-            // and child arrays makes memory tracking inflexible.
-            // If the consumer keeps only a single record batch column,
-            // the entire record batch memory is nevertheless kept alive.
-            if (cArray->n_children > 0)
-            {
-                cArray->children = (CArrowArray**)sharedOwner.Allocate(IntPtr.Size * batch.ColumnCount);
-                int i = 0;
-                foreach (IArrowArray child in batch.Arrays)
-                {
-                    cArray->children[i] = MakeArray(sharedOwner);
-                    ConvertArray(sharedOwner, child.Data, cArray->children[i]);
-                    i++;
-                }
-            }
-
-            cArray->dictionary = null;
-        }
-
-#if NET5_0_OR_GREATER
-        [UnmanagedCallersOnly]
-#endif
-        private unsafe static void ReleaseArray(CArrowArray* cArray)
-        {
-            for (long i = 0; i < cArray->n_children; i++)
-            {
-                CArrowArray.CallReleaseFunc(cArray->children[i]);
-            }
-            if (cArray->dictionary != null)
-            {
-                CArrowArray.CallReleaseFunc(cArray->dictionary);
-            }
-            DisposePrivateData(&cArray->private_data);
-            cArray->release = default;
-        }
-
-        private unsafe static CArrowArray* MakeArray(ExportedAllocationOwner sharedOwner)
-        {
-            var array = (CArrowArray*)sharedOwner.Allocate(sizeof(CArrowArray));
-            *array = default;
-            return array;
-        }
-
-        private unsafe static void* MakePrivateData(ExportedAllocationOwner sharedOwner)
-        {
-            GCHandle gch = GCHandle.Alloc(sharedOwner);
-            sharedOwner.IncRef();
-            return (void*)GCHandle.ToIntPtr(gch);
-        }
-
-        private unsafe static void DisposePrivateData(void** ptr)
-        {
-            GCHandle gch = GCHandle.FromIntPtr((IntPtr) (*ptr));
-            if (!gch.IsAllocated)
-            {
-                return;
-            }
-            // We can't call IDisposable.Dispose() here as we create multiple
-            // GCHandles to the same object. Instead, refcounting ensures
-            // timely memory deallocation when all GCHandles are freed.
-            ((ExportedAllocationOwner) gch.Target).DecRef();
-            gch.Free();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/C/CArrowArrayImporter.cs b/csharp/src/Apache.Arrow/C/CArrowArrayImporter.cs
deleted file mode 100644
index c454380..0000000
--- a/csharp/src/Apache.Arrow/C/CArrowArrayImporter.cs
+++ /dev/null
@@ -1,485 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow.C
-{
-    public static class CArrowArrayImporter
-    {
-        /// <summary>
-        /// Import C pointer as an <see cref="IArrowArray"/>.
-        /// </summary>
-        /// <remarks>
-        /// This will call the release callback once all of the buffers in the returned
-        /// IArrowArray are disposed.
-        /// </remarks>
-        /// <examples>
-        /// Typically, you will allocate an uninitialized CArrowArray pointer,
-        /// pass that to external function, and then use this method to import
-        /// the result.
-        ///
-        /// <code>
-        /// CArrowArray* importedPtr = CArrowArray.Create();
-        /// foreign_export_function(importedPtr);
-        /// IArrowArray importedArray = CArrowArrayImporter.ImportArray(importedPtr);
-        /// </code>
-        /// </examples>
-        /// <param name="ptr">The pointer to the array being imported</param>
-        /// <param name="type">The type of the array being imported</param>
-        /// <returns>The imported C# array</returns>
-        public static unsafe IArrowArray ImportArray(CArrowArray* ptr, IArrowType type)
-        {
-            ImportedArrowArray importedArray = null;
-            try
-            {
-                importedArray = new ImportedArrowArray(ptr);
-                return importedArray.GetAsArray(type);
-            }
-            finally
-            {
-                importedArray?.Release();
-            }
-        }
-
-        /// <summary>
-        /// Import C pointer as a <see cref="RecordBatch"/>.
-        /// </summary>
-        /// <remarks>
-        /// This will call the release callback once all of the buffers in the returned
-        /// RecordBatch are disposed.
-        /// </remarks>
-        /// <examples>
-        /// Typically, you will allocate an uninitialized CArrowArray pointer,
-        /// pass that to external function, and then use this method to import
-        /// the result.
-        ///
-        /// <code>
-        /// CArrowArray* importedPtr = CArrowArray.Create();
-        /// foreign_export_function(importedPtr);
-        /// RecordBatch batch = CArrowArrayImporter.ImportRecordBatch(importedPtr, schema);
-        /// </code>
-        /// </examples>
-        /// <param name="ptr">The pointer to the record batch being imported</param>
-        /// <param name="schema">The schema type of the record batch being imported</param>
-        /// <returns>The imported C# record batch</returns>
-        public static unsafe RecordBatch ImportRecordBatch(CArrowArray* ptr, Schema schema)
-        {
-            ImportedArrowArray importedArray = null;
-            try
-            {
-                importedArray = new ImportedArrowArray(ptr);
-                return importedArray.GetAsRecordBatch(schema);
-            }
-            finally
-            {
-                importedArray?.Release();
-            }
-        }
-
-        private sealed unsafe class ImportedArrowArray : ImportedAllocationOwner
-        {
-            private readonly CArrowArray _cArray;
-
-            public ImportedArrowArray(CArrowArray* cArray)
-            {
-                if (cArray == null)
-                {
-                    throw new ArgumentNullException(nameof(cArray));
-                }
-                if (cArray->release == default)
-                {
-                    throw new ArgumentException("Tried to import an array that has already been released.", nameof(cArray));
-                }
-                _cArray = *cArray;
-                cArray->release = default;
-            }
-
-            protected override void FinalRelease()
-            {
-                if (_cArray.release != default)
-                {
-                    fixed (CArrowArray* cArray = &_cArray)
-                    {
-#if NET5_0_OR_GREATER
-                        cArray->release(cArray);
-#else
-                        Marshal.GetDelegateForFunctionPointer<CArrowArrayExporter.ReleaseArrowArray>(cArray->release)(cArray);
-#endif
-                    }
-                }
-            }
-
-            public IArrowArray GetAsArray(IArrowType type)
-            {
-                fixed (CArrowArray* cArray = &_cArray)
-                {
-                    return ArrowArrayFactory.BuildArray(GetAsArrayData(cArray, type));
-                }
-            }
-
-            public RecordBatch GetAsRecordBatch(Schema schema)
-            {
-                IArrowArray[] arrays = new IArrowArray[schema.FieldsList.Count];
-                for (int i = 0; i < _cArray.n_children; i++)
-                {
-                    arrays[i] = ArrowArrayFactory.BuildArray(GetAsArrayData(_cArray.children[i], schema.FieldsList[i].DataType));
-                }
-                return new RecordBatch(schema, arrays, checked((int)_cArray.length));
-            }
-
-            private ArrayData GetAsArrayData(CArrowArray* cArray, IArrowType type)
-            {
-                ArrayData[] children = null;
-                ArrowBuffer[] buffers = null;
-                ArrayData dictionary = null;
-                switch (type.TypeId)
-                {
-                    case ArrowTypeId.String:
-                    case ArrowTypeId.Binary:
-                        buffers = ImportByteArrayBuffers(cArray);
-                        break;
-                    case ArrowTypeId.StringView:
-                    case ArrowTypeId.BinaryView:
-                        buffers = ImportByteArrayViewBuffers(cArray);
-                        break;
-                    case ArrowTypeId.LargeString:
-                    case ArrowTypeId.LargeBinary:
-                        buffers = ImportLargeByteArrayBuffers(cArray);
-                        break;
-                    case ArrowTypeId.List:
-                        children = ProcessListChildren(cArray, ((ListType)type).ValueDataType);
-                        buffers = ImportListBuffers(cArray);
-                        break;
-                    case ArrowTypeId.ListView:
-                        children = ProcessListChildren(cArray, ((ListViewType)type).ValueDataType);
-                        buffers = ImportListViewBuffers(cArray);
-                        break;
-                    case ArrowTypeId.LargeList:
-                        children = ProcessListChildren(cArray, ((LargeListType)type).ValueDataType);
-                        buffers = ImportLargeListBuffers(cArray);
-                        break;
-                    case ArrowTypeId.FixedSizeList:
-                        children = ProcessListChildren(cArray, ((FixedSizeListType)type).ValueDataType);
-                        buffers = ImportFixedSizeListBuffers(cArray);
-                        break;
-                    case ArrowTypeId.Struct:
-                        children = ProcessStructChildren(cArray, ((StructType)type).Fields);
-                        buffers = new ArrowBuffer[] { ImportValidityBuffer(cArray) };
-                        break;
-                    case ArrowTypeId.Union:
-                        UnionType unionType = (UnionType)type;
-                        children = ProcessStructChildren(cArray, unionType.Fields);
-                        buffers = unionType.Mode switch
-                        {
-                            UnionMode.Dense => ImportDenseUnionBuffers(cArray),
-                            UnionMode.Sparse => ImportSparseUnionBuffers(cArray),
-                            _ => throw new InvalidOperationException("unknown union mode in import")
-                        }; ;
-                        break;
-                    case ArrowTypeId.Map:
-                        MapType mapType = (MapType)type;
-                        children = ProcessListChildren(cArray, mapType.Fields[0].DataType);
-                        buffers = ImportListBuffers(cArray);
-                        break;
-                    case ArrowTypeId.Null:
-                        buffers = System.Array.Empty<ArrowBuffer>();
-                        break;
-                    case ArrowTypeId.Dictionary:
-                        DictionaryType dictionaryType = (DictionaryType)type;
-                        dictionary = GetAsArrayData(cArray->dictionary, dictionaryType.ValueType);
-                        goto default; // Fall through to get the validity and index data
-                    default:
-                        if (type is FixedWidthType fixedWidthType)
-                        {
-                            buffers = ImportFixedWidthBuffers(cArray, fixedWidthType.BitWidth);
-                        }
-                        break;
-                }
-
-                if (buffers == null)
-                {
-                    throw new NotSupportedException("Data type is not yet supported in import.");
-                }
-
-                return new ArrayData(
-                    type,
-                    checked((int)cArray->length),
-                    checked((int)cArray->null_count),
-                    checked((int)cArray->offset),
-                    buffers,
-                    children,
-                    dictionary);
-            }
-
-            private ArrayData[] ProcessListChildren(CArrowArray* cArray, IArrowType type)
-            {
-                if (cArray->n_children != 1)
-                {
-                    throw new InvalidOperationException("Lists are expected to have exactly one child array");
-                }
-
-                ArrayData[] children = new ArrayData[1];
-                children[0] = GetAsArrayData(cArray->children[0], type);
-                return children;
-            }
-
-            private ArrayData[] ProcessStructChildren(CArrowArray* cArray, IReadOnlyList<Field> fields)
-            {
-                if (cArray->n_children != fields.Count)
-                {
-                    throw new InvalidOperationException("Struct child count does not match schema");
-                }
-
-                ArrayData[] children = new ArrayData[fields.Count];
-                for (int i = 0; i < fields.Count; i++)
-                {
-                    children[i] = GetAsArrayData(cArray->children[i], fields[i].DataType);
-                }
-                return children;
-            }
-
-            private ArrowBuffer ImportValidityBuffer(CArrowArray* cArray)
-            {
-                int length = checked((int)cArray->offset + (int)cArray->length);
-                int validityLength = checked((int)BitUtility.RoundUpToMultipleOf8(length) / 8);
-                return (cArray->buffers[0] == null) ? ArrowBuffer.Empty : new ArrowBuffer(AddMemory((IntPtr)cArray->buffers[0], 0, validityLength));
-            }
-
-            private ArrowBuffer ImportCArrayBuffer(CArrowArray* cArray, int i, int lengthBytes)
-            {
-                if (lengthBytes > 0)
-                {
-                    Debug.Assert(cArray->buffers[i] != null);
-                    return new ArrowBuffer(AddMemory((IntPtr)cArray->buffers[i], 0, lengthBytes));
-                }
-                else
-                {
-                    return ArrowBuffer.Empty;
-                }
-            }
-
-            private ArrowBuffer[] ImportByteArrayBuffers(CArrowArray* cArray)
-            {
-                if (cArray->n_buffers != 3)
-                {
-                    throw new InvalidOperationException("Byte arrays are expected to have exactly three buffers");
-                }
-
-                int length = checked((int)cArray->offset + (int)cArray->length);
-                int offsetsLength = (length + 1) * 4;
-                int* offsets = (int*)cArray->buffers[1];
-                Debug.Assert(offsets != null);
-                int valuesLength = offsets[length];
-
-                ArrowBuffer[] buffers = new ArrowBuffer[3];
-                buffers[0] = ImportValidityBuffer(cArray);
-                buffers[1] = ImportCArrayBuffer(cArray, 1, offsetsLength);
-                buffers[2] = ImportCArrayBuffer(cArray, 2, valuesLength);
-
-                return buffers;
-            }
-
-            private ArrowBuffer[] ImportByteArrayViewBuffers(CArrowArray* cArray)
-            {
-                if (cArray->n_buffers < 3)
-                {
-                    throw new InvalidOperationException("Byte array views are expected to have at least three buffers");
-                }
-
-                int length = checked((int)cArray->offset + (int)cArray->length);
-                int viewsLength = length * 16;
-
-                long* bufferLengths = (long*)cArray->buffers[cArray->n_buffers - 1];
-                ArrowBuffer[] buffers = new ArrowBuffer[cArray->n_buffers - 1];
-                buffers[0] = ImportValidityBuffer(cArray);
-                buffers[1] = ImportCArrayBuffer(cArray, 1, viewsLength);
-                for (int i = 2; i < buffers.Length; i++)
-                {
-                    buffers[i] = ImportCArrayBuffer(cArray, i, checked((int)bufferLengths[i - 2]));
-                }
-
-                return buffers;
-            }
-
-            private ArrowBuffer[] ImportLargeByteArrayBuffers(CArrowArray* cArray)
-            {
-                if (cArray->n_buffers != 3)
-                {
-                    throw new InvalidOperationException("Large byte arrays are expected to have exactly three buffers");
-                }
-
-                const int maxLength = int.MaxValue / 8 - 1;
-                if (cArray->length > maxLength)
-                {
-                    throw new OverflowException(
-                        $"Cannot import large byte array. Array length {cArray->length} " +
-                        $"is greater than the maximum supported large byte array length ({maxLength})");
-                }
-
-                int length = checked((int)cArray->offset + (int)cArray->length);
-                int offsetsLength = (length + 1) * 8;
-                long* offsets = (long*)cArray->buffers[1];
-                Debug.Assert(offsets != null);
-                long valuesLength = offsets[length];
-
-                if (valuesLength > int.MaxValue)
-                {
-                    throw new OverflowException(
-                        $"Cannot import large byte array. Data length {valuesLength} " +
-                        $"is greater than the maximum supported large byte array data length ({int.MaxValue})");
-                }
-
-                ArrowBuffer[] buffers = new ArrowBuffer[3];
-                buffers[0] = ImportValidityBuffer(cArray);
-                buffers[1] = ImportCArrayBuffer(cArray, 1, offsetsLength);
-                buffers[2] = ImportCArrayBuffer(cArray, 2, (int)valuesLength);
-
-                return buffers;
-            }
-
-            private ArrowBuffer[] ImportListBuffers(CArrowArray* cArray)
-            {
-                if (cArray->n_buffers != 2)
-                {
-                    throw new InvalidOperationException("List arrays are expected to have exactly two buffers");
-                }
-
-                int length = checked((int)cArray->offset + (int)cArray->length);
-                int offsetsLength = (length + 1) * 4;
-
-                ArrowBuffer[] buffers = new ArrowBuffer[2];
-                buffers[0] = ImportValidityBuffer(cArray);
-                buffers[1] = ImportCArrayBuffer(cArray, 1, offsetsLength);
-
-                return buffers;
-            }
-
-            private ArrowBuffer[] ImportListViewBuffers(CArrowArray* cArray)
-            {
-                if (cArray->n_buffers != 3)
-                {
-                    throw new InvalidOperationException("List view arrays are expected to have exactly three buffers");
-                }
-
-                int length = checked((int)cArray->offset + (int)cArray->length);
-                int offsetsLength = length * 4;
-
-                ArrowBuffer[] buffers = new ArrowBuffer[3];
-                buffers[0] = ImportValidityBuffer(cArray);
-                buffers[1] = ImportCArrayBuffer(cArray, 1, offsetsLength);
-                buffers[2] = ImportCArrayBuffer(cArray, 2, offsetsLength);
-
-                return buffers;
-            }
-
-            private ArrowBuffer[] ImportLargeListBuffers(CArrowArray* cArray)
-            {
-                if (cArray->n_buffers != 2)
-                {
-                    throw new InvalidOperationException("Large list arrays are expected to have exactly two buffers");
-                }
-
-                const int maxLength = int.MaxValue / 8 - 1;
-                if (cArray->length > maxLength)
-                {
-                    throw new OverflowException(
-                        $"Cannot import large list array. Array length {cArray->length} " +
-                        $"is greater than the maximum supported large list array length ({maxLength})");
-                }
-
-                int length = checked((int)cArray->offset + (int)cArray->length);
-                int offsetsLength = (length + 1) * 8;
-
-                ArrowBuffer[] buffers = new ArrowBuffer[2];
-                buffers[0] = ImportValidityBuffer(cArray);
-                buffers[1] = ImportCArrayBuffer(cArray, 1, offsetsLength);
-
-                return buffers;
-            }
-
-            private ArrowBuffer[] ImportFixedSizeListBuffers(CArrowArray* cArray)
-            {
-                if (cArray->n_buffers != 1)
-                {
-                    throw new InvalidOperationException("Fixed-size list arrays are expected to have exactly one buffer");
-                }
-
-                ArrowBuffer[] buffers = new ArrowBuffer[1];
-                buffers[0] = ImportValidityBuffer(cArray);
-
-                return buffers;
-            }
-
-            private ArrowBuffer[] ImportDenseUnionBuffers(CArrowArray* cArray)
-            {
-                if (cArray->n_buffers != 2)
-                {
-                    throw new InvalidOperationException("Dense union arrays are expected to have exactly two children");
-                }
-                int length = checked((int)cArray->offset + (int)cArray->length);
-                int offsetsLength = length * 4;
-
-                ArrowBuffer[] buffers = new ArrowBuffer[2];
-                buffers[0] = ImportCArrayBuffer(cArray, 0, length);
-                buffers[1] = ImportCArrayBuffer(cArray, 1, offsetsLength);
-
-                return buffers;
-            }
-
-            private ArrowBuffer[] ImportSparseUnionBuffers(CArrowArray* cArray)
-            {
-                if (cArray->n_buffers != 1)
-                {
-                    throw new InvalidOperationException("Sparse union arrays are expected to have exactly one child");
-                }
-
-                ArrowBuffer[] buffers = new ArrowBuffer[1];
-                buffers[0] = ImportCArrayBuffer(cArray, 0, checked((int)cArray->offset + (int)cArray->length));
-
-                return buffers;
-            }
-
-            private ArrowBuffer[] ImportFixedWidthBuffers(CArrowArray* cArray, int bitWidth)
-            {
-                if (cArray->n_buffers != 2)
-                {
-                    throw new InvalidOperationException("Arrays of fixed-width type are expected to have exactly two buffers");
-                }
-
-                // validity, data
-                int length = checked((int)cArray->offset + (int)cArray->length);
-                int valuesLength;
-                if (bitWidth >= 8)
-                    valuesLength = checked(length * bitWidth / 8);
-                else
-                    valuesLength = checked((int)BitUtility.RoundUpToMultipleOf8(length) / 8);
-
-                ArrowBuffer[] buffers = new ArrowBuffer[2];
-                buffers[0] = ImportValidityBuffer(cArray);
-                buffers[1] = ImportCArrayBuffer(cArray, 1, valuesLength);
-
-                return buffers;
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/C/CArrowArrayStream.cs b/csharp/src/Apache.Arrow/C/CArrowArrayStream.cs
deleted file mode 100644
index 9cc9984..0000000
--- a/csharp/src/Apache.Arrow/C/CArrowArrayStream.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Runtime.InteropServices;
-using Apache.Arrow.Ipc;
-
-namespace Apache.Arrow.C
-{
-    /// <summary>
-    /// An Arrow C Data Interface ArrowArrayStream, which represents a stream of record batches.
-    /// </summary>
-    /// <remarks>
-    /// This is used to export <see cref="IArrowArrayStream"/> to other languages. It matches the layout of the
-    /// ArrowArrayStream struct described in https://github.com/apache/arrow/blob/main/cpp/src/arrow/c/abi.h.
-    /// </remarks>
-    [StructLayout(LayoutKind.Sequential)]
-    public unsafe struct CArrowArrayStream
-    {
-        /// <summary>
-        /// Callback to get the stream type. Will be the same for all arrays in the stream.
-        /// If successful, the ArrowSchema must be released independently from the stream.
-        ///
-        /// Return value: 0 if successful, an `errno`-compatible error code otherwise.
-        ///</summary>
-#if NET5_0_OR_GREATER
-        internal delegate* unmanaged <CArrowArrayStream*, CArrowSchema*, int> get_schema;
-#else
-        internal IntPtr get_schema;
-#endif
-
-        /// <summary>
-        /// Callback to get the next array. If no error and the array is released, the stream has ended.
-        /// If successful, the ArrowArray must be released independently from the stream.
-        /// 
-        /// Return value: 0 if successful, an `errno`-compatible error code otherwise.
-        /// </summary>
-#if NET5_0_OR_GREATER
-        internal delegate* unmanaged<CArrowArrayStream*, CArrowArray*, int> get_next;
-#else
-        internal IntPtr get_next;
-#endif
-
-        /// <summary>
-        /// Callback to get optional detailed error information. This must only
-        /// be called if the last stream operation failed with a non-0 return code.
-        /// The returned pointer is only valid until the next operation on this stream
-        /// (including release).
-        ///
-        /// Return value: pointer to a null-terminated character array describing the last
-        /// error, or NULL if no description is available.
-        ///</summary>
-#if NET5_0_OR_GREATER
-        internal delegate* unmanaged<CArrowArrayStream*, byte*> get_last_error;
-#else
-        internal IntPtr get_last_error;
-#endif
-
-        /// <summary>
-        /// Release callback: release the stream's own resources. Note that arrays returned by
-        /// get_next must be individually released.
-        /// </summary>
-#if NET5_0_OR_GREATER
-        internal delegate* unmanaged <CArrowArrayStream*, void> release;
-#else
-        internal IntPtr release;
-#endif
-
-        public void* private_data;
-
-        /// <summary>
-        /// Allocate and zero-initialize an unmanaged pointer of this type.
-        /// </summary>
-        /// <remarks>
-        /// This pointer must later be freed by <see cref="Free"/>.
-        /// </remarks>
-        public static CArrowArrayStream* Create()
-        {
-            var ptr = (CArrowArrayStream*)Marshal.AllocHGlobal(sizeof(CArrowArrayStream));
-
-            *ptr = default;
-
-            return ptr;
-        }
-
-        /// <summary>
-        /// Free a pointer that was allocated in <see cref="Create"/>.
-        /// </summary>
-        /// <remarks>
-        /// Do not call this on a pointer that was allocated elsewhere.
-        /// </remarks>
-        public static void Free(CArrowArrayStream* arrayStream)
-        {
-            if (arrayStream->release != default)
-            {
-                // Call release if not already called.
-#if NET5_0_OR_GREATER
-
-                arrayStream->release(arrayStream);
-#else
-                Marshal.GetDelegateForFunctionPointer<CArrowArrayStreamExporter.ReleaseArrayStream>(arrayStream->release)(arrayStream);
-#endif
-            }
-            Marshal.FreeHGlobal((IntPtr)arrayStream);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/C/CArrowArrayStreamExporter.cs b/csharp/src/Apache.Arrow/C/CArrowArrayStreamExporter.cs
deleted file mode 100644
index 17b320f..0000000
--- a/csharp/src/Apache.Arrow/C/CArrowArrayStreamExporter.cs
+++ /dev/null
@@ -1,210 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Apache.Arrow.Ipc;
-
-namespace Apache.Arrow.C
-{
-    public static class CArrowArrayStreamExporter
-    {
-#if NET5_0_OR_GREATER
-        private static unsafe delegate* unmanaged<CArrowArrayStream*, CArrowSchema*, int> GetSchemaPtr => &GetSchema;
-        private static unsafe delegate* unmanaged<CArrowArrayStream*, CArrowArray*, int> GetNextPtr => &GetNext;
-        private static unsafe delegate* unmanaged<CArrowArrayStream*, byte*> GetLastErrorPtr => &GetLastError;
-        private static unsafe delegate* unmanaged<CArrowArrayStream*, void> ReleasePtr => &Release;
-#else
-        internal unsafe delegate int GetSchemaArrayStream(CArrowArrayStream* cArrayStream, CArrowSchema* cSchema);
-        private static unsafe NativeDelegate<GetSchemaArrayStream> s_getSchemaArrayStream = new NativeDelegate<GetSchemaArrayStream>(GetSchema);
-        private static unsafe IntPtr GetSchemaPtr => s_getSchemaArrayStream.Pointer;
-        internal unsafe delegate int GetNextArrayStream(CArrowArrayStream* cArrayStream, CArrowArray* cArray);
-        private static unsafe NativeDelegate<GetNextArrayStream> s_getNextArrayStream = new NativeDelegate<GetNextArrayStream>(GetNext);
-        private static unsafe IntPtr GetNextPtr => s_getNextArrayStream.Pointer;
-        internal unsafe delegate byte* GetLastErrorArrayStream(CArrowArrayStream* cArrayStream);
-        private static unsafe NativeDelegate<GetLastErrorArrayStream> s_getLastErrorArrayStream = new NativeDelegate<GetLastErrorArrayStream>(GetLastError);
-        private static unsafe IntPtr GetLastErrorPtr => s_getLastErrorArrayStream.Pointer;
-        internal unsafe delegate void ReleaseArrayStream(CArrowArrayStream* cArrayStream);
-        private static unsafe NativeDelegate<ReleaseArrayStream> s_releaseArrayStream = new NativeDelegate<ReleaseArrayStream>(Release);
-        private static unsafe IntPtr ReleasePtr => s_releaseArrayStream.Pointer;
-#endif
-
-        /// <summary>
-        /// Export an <see cref="IArrowArrayStream"/> to a <see cref="CArrowArrayStream"/>.
-        /// </summary>
-        /// <param name="arrayStream">The array stream to export</param>
-        /// <param name="cArrayStream">An allocated but uninitialized CArrowArrayStream pointer.</param>
-        /// <example>
-        /// <code>
-        /// CArrowArrayStream* exportPtr = CArrowArrayStream.Create();
-        /// CArrowArrayStreamExporter.ExportArray(arrayStream, exportPtr);
-        /// foreign_import_function(exportPtr);
-        /// </code>
-        /// </example>
-        public static unsafe void ExportArrayStream(IArrowArrayStream arrayStream, CArrowArrayStream* cArrayStream)
-        {
-            if (arrayStream == null)
-            {
-                throw new ArgumentNullException(nameof(arrayStream));
-            }
-            if (cArrayStream == null)
-            {
-                throw new ArgumentNullException(nameof(cArrayStream));
-            }
-
-            cArrayStream->private_data = ExportedArrayStream.Export(arrayStream);
-            cArrayStream->get_schema = GetSchemaPtr;
-            cArrayStream->get_next = GetNextPtr;
-            cArrayStream->get_last_error = GetLastErrorPtr;
-            cArrayStream->release = ReleasePtr;
-        }
-
-#if NET5_0_OR_GREATER
-        [UnmanagedCallersOnly]
-#endif
-        private unsafe static int GetSchema(CArrowArrayStream* cArrayStream, CArrowSchema* cSchema)
-        {
-            ExportedArrayStream arrayStream = null;
-            try
-            {
-                arrayStream = ExportedArrayStream.FromPointer(cArrayStream->private_data);
-                CArrowSchemaExporter.ExportSchema(arrayStream.ArrowArrayStream.Schema, cSchema);
-                return arrayStream.ClearError();
-            }
-            catch (Exception ex)
-            {
-                return arrayStream?.SetError(ex) ?? ExportedArrayStream.EOTHER;
-            }
-        }
-
-#if NET5_0_OR_GREATER
-        [UnmanagedCallersOnly]
-#endif
-        private unsafe static int GetNext(CArrowArrayStream* cArrayStream, CArrowArray* cArray)
-        {
-            ExportedArrayStream arrayStream = null;
-            try
-            {
-                cArray->release = default;
-                arrayStream = ExportedArrayStream.FromPointer(cArrayStream->private_data);
-                RecordBatch recordBatch = arrayStream.ArrowArrayStream.ReadNextRecordBatchAsync().Result;
-                if (recordBatch != null)
-                {
-                    CArrowArrayExporter.ExportRecordBatch(recordBatch, cArray);
-                }
-                return arrayStream.ClearError();
-            }
-            catch (Exception ex)
-            {
-                return arrayStream?.SetError(ex) ?? ExportedArrayStream.EOTHER;
-            }
-        }
-
-#if NET5_0_OR_GREATER
-        [UnmanagedCallersOnly]
-#endif
-        private unsafe static byte* GetLastError(CArrowArrayStream* cArrayStream)
-        {
-            try
-            {
-                ExportedArrayStream arrayStream = ExportedArrayStream.FromPointer(cArrayStream->private_data);
-                return arrayStream.LastError;
-            }
-            catch (Exception)
-            {
-                return null;
-            }
-        }
-
-#if NET5_0_OR_GREATER
-        [UnmanagedCallersOnly]
-#endif
-        private unsafe static void Release(CArrowArrayStream* cArrayStream)
-        {
-            ExportedArrayStream.Free(&cArrayStream->private_data);
-            cArrayStream->release = default;
-        }
-
-        sealed unsafe class ExportedArrayStream : IDisposable
-        {
-            public const int EOTHER = 131;
-
-            ExportedArrayStream(IArrowArrayStream arrayStream)
-            {
-                ArrowArrayStream = arrayStream;
-                LastError = null;
-            }
-
-            public IArrowArrayStream ArrowArrayStream { get; private set; }
-            public byte* LastError { get; private set; }
-
-            public static void* Export(IArrowArrayStream arrayStream)
-            {
-                ExportedArrayStream result = new ExportedArrayStream(arrayStream);
-                GCHandle gch = GCHandle.Alloc(result);
-                return (void*)GCHandle.ToIntPtr(gch);
-            }
-
-            public static void Free(void** ptr)
-            {
-                GCHandle gch = GCHandle.FromIntPtr((IntPtr)(*ptr));
-                if (!gch.IsAllocated)
-                {
-                    return;
-                }
-                ((ExportedArrayStream)gch.Target).Dispose();
-                gch.Free();
-                *ptr = null;
-            }
-
-            public static ExportedArrayStream FromPointer(void* ptr)
-            {
-                GCHandle gch = GCHandle.FromIntPtr((IntPtr)ptr);
-                return (ExportedArrayStream)gch.Target;
-            }
-
-            public int SetError(Exception ex)
-            {
-                ReleaseLastError();
-                LastError = StringUtil.ToCStringUtf8(ex.Message);
-                return EOTHER;
-            }
-
-            public int ClearError()
-            {
-                ReleaseLastError();
-                return 0;
-            }
-
-            public void Dispose()
-            {
-                ReleaseLastError();
-                ArrowArrayStream?.Dispose();
-                ArrowArrayStream = null;
-            }
-
-            void ReleaseLastError()
-            {
-                if (LastError != null)
-                {
-                    Marshal.FreeHGlobal((IntPtr)LastError);
-                    LastError = null;
-                }
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/C/CArrowArrayStreamImporter.cs b/csharp/src/Apache.Arrow/C/CArrowArrayStreamImporter.cs
deleted file mode 100644
index fe0a307..0000000
--- a/csharp/src/Apache.Arrow/C/CArrowArrayStreamImporter.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-using System;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Ipc;
-
-namespace Apache.Arrow.C
-{
-    public static class CArrowArrayStreamImporter
-    {
-        /// <summary>
-        /// Import C pointer as an <see cref="IArrowArrayStream"/>.
-        /// </summary>
-        /// <remarks>
-        /// This will call the release callback on the passed struct if the function fails.
-        /// Otherwise, the release callback is called when the IArrowArrayStream is disposed.
-        /// </remarks>
-        /// <examples>
-        /// Typically, you will allocate an uninitialized CArrowArrayStream pointer,
-        /// pass that to external function, and then use this method to import
-        /// the result.
-        /// 
-        /// <code>
-        /// CArrowArrayStream* importedPtr = CArrowArrayStream.Create();
-        /// foreign_export_function(importedPtr);
-        /// IArrowArrayStream importedStream = CArrowArrayStreamImporter.ImportStream(importedPtr);
-        /// </code>
-        /// </examples>
-        /// <param name="ptr">The pointer to the stream being imported</param>
-        /// <returns>The imported C# array stream</returns>
-        public static unsafe IArrowArrayStream ImportArrayStream(CArrowArrayStream* ptr)
-        {
-            return new ImportedArrowArrayStream(ptr);
-        }
-
-        private sealed unsafe class ImportedArrowArrayStream : IArrowArrayStream
-        {
-            private readonly CArrowArrayStream _cArrayStream;
-            private readonly Schema _schema;
-            private bool _disposed;
-
-            internal static string GetLastError(CArrowArrayStream* arrayStream, int errno)
-            {
-#if NET5_0_OR_GREATER
-                byte* error = arrayStream->get_last_error(arrayStream);
-#else
-                byte* error = Marshal.GetDelegateForFunctionPointer<CArrowArrayStreamExporter.GetLastErrorArrayStream>(arrayStream->get_last_error)(arrayStream);
-#endif
-                if (error == null)
-                {
-                    return $"Array stream operation failed with no message. Error code: {errno}";
-                }
-                return StringUtil.PtrToStringUtf8(error);
-            }
-
-            public ImportedArrowArrayStream(CArrowArrayStream* cArrayStream)
-            {
-                if (cArrayStream == null)
-                {
-                    throw new ArgumentNullException(nameof(cArrayStream));
-                }
-                if (cArrayStream->release == default)
-                {
-                    throw new ArgumentException("Tried to import an array stream that has already been released.", nameof(cArrayStream));
-                }
-
-                CArrowSchema cSchema = new CArrowSchema();
-#if NET5_0_OR_GREATER
-                int errno = cArrayStream->get_schema(cArrayStream, &cSchema);
-#else
-                int errno = Marshal.GetDelegateForFunctionPointer<CArrowArrayStreamExporter.GetSchemaArrayStream>(cArrayStream->get_schema)(cArrayStream, &cSchema);
-#endif
-                if (errno != 0)
-                {
-                    throw new Exception(GetLastError(cArrayStream, errno));
-                }
-                _schema = CArrowSchemaImporter.ImportSchema(&cSchema);
-
-                _cArrayStream = *cArrayStream;
-                cArrayStream->release = default;
-            }
-
-            ~ImportedArrowArrayStream()
-            {
-                Dispose();
-            }
-
-            public Schema Schema => _schema;
-
-            public ValueTask<RecordBatch> ReadNextRecordBatchAsync(CancellationToken cancellationToken = default)
-            {
-                if (_disposed)
-                {
-                    throw new ObjectDisposedException(typeof(ImportedArrowArrayStream).Name);
-                }
-
-                if (cancellationToken.IsCancellationRequested)
-                {
-                    return new(Task.FromCanceled<RecordBatch>(cancellationToken));
-                }
-
-                RecordBatch result = null;
-                CArrowArray cArray = new CArrowArray();
-                fixed (CArrowArrayStream* cArrayStream = &_cArrayStream)
-                {
-#if NET5_0_OR_GREATER
-                    int errno = cArrayStream->get_next(cArrayStream, &cArray);
-#else
-                    int errno = Marshal.GetDelegateForFunctionPointer<CArrowArrayStreamExporter.GetNextArrayStream>(cArrayStream->get_next)(cArrayStream, &cArray);
-#endif
-                    if (errno != 0)
-                    {
-                        return new(Task.FromException<RecordBatch>(new Exception(GetLastError(cArrayStream, errno))));
-                    }
-                    if (cArray.release != default)
-                    {
-                        result = CArrowArrayImporter.ImportRecordBatch(&cArray, _schema);
-                    }
-                }
-
-                return new ValueTask<RecordBatch>(result);
-            }
-
-            public void Dispose()
-            {
-                if (!_disposed && _cArrayStream.release != default)
-                {
-                    _disposed = true;
-                    fixed (CArrowArrayStream* cArrayStream = &_cArrayStream)
-                    {
-#if NET5_0_OR_GREATER
-                        cArrayStream->release(cArrayStream);
-#else
-                        Marshal.GetDelegateForFunctionPointer<CArrowArrayStreamExporter.ReleaseArrayStream>(cArrayStream->release)(cArrayStream);
-#endif
-                    }
-                }
-                GC.SuppressFinalize(this);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/C/CArrowSchema.cs b/csharp/src/Apache.Arrow/C/CArrowSchema.cs
deleted file mode 100644
index 50c363b..0000000
--- a/csharp/src/Apache.Arrow/C/CArrowSchema.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-using System;
-using System.Runtime.InteropServices;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow.C
-{
-    /// <summary>
-    /// An Arrow C Data Interface Schema, which represents a type, field, or schema.
-    /// </summary>
-    /// <remarks>
-    /// This is used to export <see cref="ArrowType"/>, <see cref="Field"/>, or
-    /// <see cref="Schema"/> to other languages. It matches the layout of the
-    /// ArrowSchema struct described in https://github.com/apache/arrow/blob/main/cpp/src/arrow/c/abi.h.
-    /// </remarks>
-    [StructLayout(LayoutKind.Sequential)]
-    public unsafe struct CArrowSchema
-    {
-        public byte* format;
-        public byte* name;
-        public byte* metadata;
-        public long flags;
-        public long n_children;
-        public CArrowSchema** children;
-        public CArrowSchema* dictionary;
-#if NET5_0_OR_GREATER
-        internal delegate* unmanaged<CArrowSchema*, void> release;
-#else
-        internal IntPtr release;
-#endif
-        public void* private_data;
-
-        /// <summary>
-        /// Allocate and zero-initialize an unmanaged pointer of this type.
-        /// </summary>
-        /// <remarks>
-        /// This pointer must later be freed by <see cref="Free"/>.
-        /// </remarks>
-        public static CArrowSchema* Create()
-        {
-            var ptr = (CArrowSchema*)Marshal.AllocHGlobal(sizeof(CArrowSchema));
-
-            *ptr = default;
-
-            return ptr;
-        }
-
-        /// <summary>
-        /// Free a pointer that was allocated in <see cref="Create"/>.
-        /// </summary>
-        /// <remarks>
-        /// Do not call this on a pointer that was allocated elsewhere.
-        /// </remarks>
-        public static void Free(CArrowSchema* schema)
-        {
-            if (schema->release != default)
-            {
-                // Call release if not already called.
-#if NET5_0_OR_GREATER
-                schema->release(schema);
-#else
-                Marshal.GetDelegateForFunctionPointer<CArrowSchemaExporter.ReleaseArrowSchema>(schema->release)(schema);
-#endif
-            }
-            Marshal.FreeHGlobal((IntPtr)schema);
-        }
-
-
-        /// <summary>
-        /// For dictionary-encoded types, whether the ordering of dictionary indices is semantically meaningful.
-        /// </summary>
-        public const long ArrowFlagDictionaryOrdered = 1;
-        /// <summary>
-        /// Whether this field is semantically nullable (regardless of whether it actually has null values)
-        /// </summary>
-        public const long ArrowFlagNullable = 2;
-        /// <summary>
-        /// For map types, whether the keys within each map value are sorted.
-        /// </summary>
-        public const long ArrowFlagMapKeysSorted = 4;
-
-        /// <summary>
-        /// Get the value of a particular flag.
-        /// </summary>
-        /// <remarks>
-        /// Known valid flags are <see cref="ArrowFlagDictionaryOrdered" />,
-        /// <see cref="ArrowFlagNullable" />, and <see cref="ArrowFlagMapKeysSorted" />.
-        /// </remarks>
-        public readonly bool GetFlag(long flag)
-        {
-            return (flags & flag) == flag;
-        }
-
-        internal readonly CArrowSchema* GetChild(long i)
-        {
-            if ((ulong)i >= (ulong)n_children)
-            {
-                throw new ArgumentOutOfRangeException("Child index out of bounds.");
-            }
-            if (children == null)
-            {
-                throw new ArgumentOutOfRangeException($"Child index '{i}' out of bounds.");
-            }
-
-            return children[i];
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/C/CArrowSchemaExporter.cs b/csharp/src/Apache.Arrow/C/CArrowSchemaExporter.cs
deleted file mode 100644
index 1cf6dc7..0000000
--- a/csharp/src/Apache.Arrow/C/CArrowSchemaExporter.cs
+++ /dev/null
@@ -1,372 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow.C
-{
-    public static class CArrowSchemaExporter
-    {
-#if NET5_0_OR_GREATER
-        private static unsafe delegate* unmanaged<CArrowSchema*, void> ReleaseSchemaPtr => &ReleaseCArrowSchema;
-#else
-        internal unsafe delegate void ReleaseArrowSchema(CArrowSchema* cArray);
-        private static unsafe readonly NativeDelegate<ReleaseArrowSchema> s_releaseSchema = new NativeDelegate<ReleaseArrowSchema>(ReleaseCArrowSchema);
-        private static IntPtr ReleaseSchemaPtr => s_releaseSchema.Pointer;
-#endif
-
-        /// <summary>
-        /// Export a type to a <see cref="CArrowSchema"/>.
-        /// </summary>
-        /// <param name="datatype">The datatype to export</param>
-        /// <param name="schema">An allocated but uninitialized CArrowSchema pointer.</param>
-        /// <example>
-        /// <code>
-        /// CArrowSchema* exportPtr = CArrowSchema.Create();
-        /// CArrowSchemaExporter.ExportType(dataType, exportPtr);
-        /// foreign_import_function(exportPtr);
-        /// CArrowSchema.Free(exportPtr);
-        /// </code>
-        /// </example>
-        public static unsafe void ExportType(IArrowType datatype, CArrowSchema* schema)
-        {
-            if (datatype == null)
-            {
-                throw new ArgumentNullException(nameof(datatype));
-            }
-            if (schema == null)
-            {
-                throw new ArgumentNullException(nameof(schema));
-            }
-
-            schema->format = StringUtil.ToCStringUtf8(GetFormat(datatype));
-            schema->name = null;
-            schema->metadata = null;
-            schema->flags = GetFlags(datatype);
-
-            schema->children = ConstructChildren(datatype, out var numChildren);
-            schema->n_children = numChildren;
-
-            schema->dictionary = ConstructDictionary(datatype);
-
-            schema->release = ReleaseSchemaPtr;
-
-            schema->private_data = null;
-        }
-
-        /// <summary>
-        /// Export a field to a <see cref="CArrowSchema"/>.
-        /// </summary>
-        /// <param name="field">The field to export</param>
-        /// <param name="schema">An allocated but uninitialized CArrowSchema pointer.</param>
-        /// <example>
-        /// <code>
-        /// CArrowSchema* exportPtr = CArrowSchema.Create();
-        /// CArrowSchemaExporter.ExportType(field, exportPtr);
-        /// foreign_import_function(exportPtr);
-        /// CArrowSchema.Free(exportPtr);
-        /// </code>
-        /// </example>
-        public static unsafe void ExportField(Field field, CArrowSchema* schema)
-        {
-            ExportType(field.DataType, schema);
-            schema->name = StringUtil.ToCStringUtf8(field.Name);
-            schema->metadata = ConstructMetadata(field.Metadata);
-            schema->flags = GetFlags(field.DataType, field.IsNullable);
-        }
-
-        /// <summary>
-        /// Export a schema to a <see cref="CArrowSchema"/>.
-        /// </summary>
-        /// <param name="schema">The schema to export</param>
-        /// <param name="out_schema">An allocated but uninitialized CArrowSchema pointer.</param>
-        /// <example>
-        /// <code>
-        /// CArrowSchema* exportPtr = CArrowSchema.Create();
-        /// CArrowSchemaExporter.ExportType(schema, exportPtr);
-        /// foreign_import_function(exportPtr);
-        /// CArrowSchema.Free(exportPtr);
-        /// </code>
-        /// </example>
-        public static unsafe void ExportSchema(Schema schema, CArrowSchema* out_schema)
-        {
-            var structType = new StructType(schema.FieldsList);
-            ExportType(structType, out_schema);
-            out_schema->metadata = ConstructMetadata(schema.Metadata);
-        }
-
-        private static char FormatTimeUnit(TimeUnit unit) => unit switch
-        {
-            TimeUnit.Second => 's',
-            TimeUnit.Millisecond => 'm',
-            TimeUnit.Microsecond => 'u',
-            TimeUnit.Nanosecond => 'n',
-            _ => throw new InvalidDataException($"Unsupported time unit for export: {unit}"),
-        };
-
-        private static string FormatUnion(UnionType unionType)
-        {
-            StringBuilder builder = new StringBuilder();
-            builder.Append(unionType.Mode switch
-            {
-                UnionMode.Sparse => "+us:",
-                UnionMode.Dense => "+ud:",
-                _ => throw new InvalidDataException($"Unsupported union mode for export: {unionType.Mode}"),
-            });
-            for (int i = 0; i < unionType.TypeIds.Length; i++)
-            {
-                if (i > 0) { builder.Append(','); }
-                builder.Append(unionType.TypeIds[i]);
-            }
-            return builder.ToString();
-        }
-
-        private static string GetFormat(IArrowType datatype)
-        {
-            switch (datatype)
-            {
-                case NullType _: return "n";
-                case BooleanType _: return "b";
-                // Integers
-                case Int8Type _: return "c";
-                case UInt8Type _: return "C";
-                case Int16Type _: return "s";
-                case UInt16Type _: return "S";
-                case Int32Type _: return "i";
-                case UInt32Type _: return "I";
-                case Int64Type _: return "l";
-                case UInt64Type _: return "L";
-                // Floats
-                case HalfFloatType _: return "e";
-                case FloatType _: return "f";
-                case DoubleType _: return "g";
-                // Decimal
-                case Decimal32Type decimalType:
-                    return $"d:{decimalType.Precision},{decimalType.Scale},32";
-                case Decimal64Type decimalType:
-                    return $"d:{decimalType.Precision},{decimalType.Scale},64";
-                case Decimal128Type decimalType:
-                    return $"d:{decimalType.Precision},{decimalType.Scale}";
-                case Decimal256Type decimalType:
-                    return $"d:{decimalType.Precision},{decimalType.Scale},256";
-                // Binary
-                case BinaryType _: return "z";
-                case BinaryViewType _: return "vz";
-                case LargeBinaryType _: return "Z";
-                case StringType _: return "u";
-                case StringViewType _: return "vu";
-                case LargeStringType _: return "U";
-                case FixedSizeBinaryType binaryType:
-                    return $"w:{binaryType.ByteWidth}";
-                // Date
-                case Date32Type _: return "tdD";
-                case Date64Type _: return "tdm";
-                // Time
-                case Time32Type timeType:
-                    return String.Format("tt{0}", FormatTimeUnit(timeType.Unit));
-                case Time64Type timeType:
-                    // Same prefix as Time32, but allowed time units are different.
-                    return String.Format("tt{0}", FormatTimeUnit(timeType.Unit));
-                // Duration
-                case DurationType durationType:
-                    return String.Format("tD{0}", FormatTimeUnit(durationType.Unit));
-                // Timestamp
-                case TimestampType timestampType:
-                    return String.Format("ts{0}:{1}", FormatTimeUnit(timestampType.Unit), timestampType.Timezone);
-                // Interval
-                case IntervalType intervalType:
-                    return intervalType.Unit switch
-                    {
-                        IntervalUnit.YearMonth => "tiM",
-                        IntervalUnit.DayTime => "tiD",
-                        IntervalUnit.MonthDayNanosecond => "tin",
-                        _ => throw new InvalidDataException($"Unsupported interval unit for export: {intervalType.Unit}"),
-                    };
-                // Nested
-                case ListType _: return "+l";
-                case ListViewType _: return "+vl";
-                case LargeListType _: return "+L";
-                case FixedSizeListType fixedListType:
-                    return $"+w:{fixedListType.ListSize}";
-                case StructType _: return "+s";
-                case UnionType u: return FormatUnion(u);
-                case MapType _: return "+m";
-                // Dictionary
-                case DictionaryType dictionaryType:
-                    return GetFormat(dictionaryType.IndexType);
-                default: throw new NotImplementedException($"Exporting {datatype.Name} not implemented");
-            }
-        }
-
-        private static long GetFlags(IArrowType datatype, bool nullable = true)
-        {
-            long flags = 0;
-
-            if (nullable)
-            {
-                flags |= CArrowSchema.ArrowFlagNullable;
-            }
-
-            if (datatype is DictionaryType dictionaryType)
-            {
-                if (dictionaryType.Ordered)
-                {
-                    flags |= CArrowSchema.ArrowFlagDictionaryOrdered;
-                }
-            }
-
-            if (datatype is MapType mapType && mapType.KeySorted)
-            {
-                flags |= CArrowSchema.ArrowFlagMapKeysSorted;
-            }
-
-            return flags;
-        }
-
-        private static unsafe CArrowSchema** ConstructChildren(IArrowType datatype, out long numChildren)
-        {
-            if (datatype is NestedType nestedType)
-            {
-                IReadOnlyList<Field> fields = nestedType.Fields;
-                int numFields = fields.Count;
-                numChildren = numFields;
-                if (numFields == 0)
-                {
-                    throw new NotSupportedException("Exporting nested data types with zero children.");
-                };
-
-                var pointerList = (CArrowSchema**)Marshal.AllocHGlobal(numFields * IntPtr.Size);
-
-                for (var i = 0; i < numChildren; i++)
-                {
-                    CArrowSchema* cSchema = CArrowSchema.Create();
-                    ExportField(fields[i], cSchema);
-                    pointerList[i] = cSchema;
-                }
-
-                return pointerList;
-
-            }
-            else
-            {
-                numChildren = 0;
-                return null;
-            }
-        }
-
-        private static unsafe CArrowSchema* ConstructDictionary(IArrowType datatype)
-        {
-            if (datatype is DictionaryType dictType)
-            {
-                CArrowSchema* cSchema = CArrowSchema.Create();
-                ExportType(dictType.ValueType, cSchema);
-                return cSchema;
-            }
-            else
-            {
-                return null;
-            }
-        }
-
-        private unsafe static byte* ConstructMetadata(IReadOnlyDictionary<string, string> metadata)
-        {
-            if (metadata == null || metadata.Count == 0)
-            {
-                return null;
-            }
-
-            int size = 4;
-            int[] lengths = new int[metadata.Count * 2];
-            int i = 0;
-            foreach (KeyValuePair<string, string> pair in metadata)
-            {
-                size += 8;
-                lengths[i] = Encoding.UTF8.GetByteCount(pair.Key);
-                size += lengths[i++];
-                lengths[i] = Encoding.UTF8.GetByteCount(pair.Value);
-                size += lengths[i++];
-            }
-
-            IntPtr result = Marshal.AllocHGlobal(size);
-            Marshal.WriteInt32(result, metadata.Count);
-            byte* ptr = (byte*)result + 4;
-            i = 0;
-            foreach (KeyValuePair<string, string> pair in metadata)
-            {
-                WriteMetadataString(ref ptr, lengths[i++], pair.Key);
-                WriteMetadataString(ref ptr, lengths[i++], pair.Value);
-            }
-
-            Debug.Assert((long)(IntPtr)ptr - (long)result == size);
-
-            return (byte*)result;
-        }
-
-        private unsafe static void WriteMetadataString(ref byte* ptr, int length, string str)
-        {
-            Marshal.WriteInt32((IntPtr)ptr, length);
-            ptr += 4;
-            fixed (char* s = str)
-            {
-                Encoding.UTF8.GetBytes(s, str.Length, ptr, length);
-            }
-            ptr += length;
-        }
-
-#if NET5_0_OR_GREATER
-        [UnmanagedCallersOnly]
-#endif
-        private static unsafe void ReleaseCArrowSchema(CArrowSchema* schema)
-        {
-            if (schema == null) return;
-            if (schema->release == default) return;
-
-            Marshal.FreeHGlobal((IntPtr)schema->format);
-            Marshal.FreeHGlobal((IntPtr)schema->name);
-            Marshal.FreeHGlobal((IntPtr)schema->metadata);
-            schema->format = null;
-            schema->name = null;
-            schema->metadata = null;
-
-            if (schema->n_children > 0)
-            {
-                for (int i = 0; i < schema->n_children; i++)
-                {
-                    CArrowSchema.Free(schema->GetChild(i));
-                }
-                Marshal.FreeHGlobal((IntPtr)schema->children);
-            }
-
-            if (schema->dictionary != null)
-            {
-                CArrowSchema.Free(schema->dictionary);
-            }
-
-            schema->flags = 0;
-            schema->n_children = 0;
-            schema->dictionary = null;
-            schema->children = null;
-            schema->release = default;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/C/CArrowSchemaImporter.cs b/csharp/src/Apache.Arrow/C/CArrowSchemaImporter.cs
deleted file mode 100644
index a772b8f..0000000
--- a/csharp/src/Apache.Arrow/C/CArrowSchemaImporter.cs
+++ /dev/null
@@ -1,410 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow.C
-{
-    public static class CArrowSchemaImporter
-    {
-        /// <summary>
-        /// Import C pointer as an <see cref="ArrowType"/>.
-        /// </summary>
-        /// <remarks>
-        /// This will call the release callback on the passed struct, even if
-        /// this function fails.
-        /// </remarks>
-        /// <examples>
-        /// Typically, you will allocate an uninitialized CArrowSchema pointer,
-        /// pass that to external function, and then use this method to import
-        /// the result.
-        ///
-        /// <code>
-        /// CArrowSchema* importedPtr = CArrowSchema.Create();
-        /// foreign_export_function(importedPtr);
-        /// ArrowType importedType = CArrowSchemaImporter.ImportType(importedPtr);
-        /// CArrowSchema.Free(importedPtr);
-        /// </code>
-        /// </examples>
-        public static unsafe ArrowType ImportType(CArrowSchema* ptr)
-        {
-            using var importedType = new ImportedArrowSchema(ptr);
-            return importedType.GetAsType();
-        }
-
-        /// <summary>
-        /// Import C pointer as a <see cref="Field"/>.
-        /// </summary>
-        /// <remarks>
-        /// This will call the release callback on the passed struct, even if
-        /// this function fails.
-        /// </remarks>
-        /// <examples>
-        /// Typically, you will allocate an uninitialized CArrowSchema pointer,
-        /// pass that to external function, and then use this method to import
-        /// the result.
-        ///
-        /// <code>
-        /// CArrowSchema* importedPtr = CArrowSchema.Create();
-        /// foreign_export_function(importedPtr);
-        /// Field importedField = CArrowSchemaImporter.ImportField(importedPtr);
-        /// CArrowSchema.Free(importedPtr);
-        /// </code>
-        /// </examples>
-        public static unsafe Field ImportField(CArrowSchema* ptr)
-        {
-            using var importedField = new ImportedArrowSchema(ptr);
-            return importedField.GetAsField();
-        }
-
-        /// <summary>
-        /// Import C pointer as a <see cref="Schema"/>.
-        /// </summary>
-        /// <remarks>
-        /// This will call the release callback on the passed struct, even if
-        /// this function fails.
-        /// </remarks>
-        /// <examples>
-        /// Typically, you will allocate an uninitialized CArrowSchema pointer,
-        /// pass that to external function, and then use this method to import
-        /// the result.
-        ///
-        /// <code>
-        /// CArrowSchema* importedPtr = CArrowSchema.Create();
-        /// foreign_export_function(importedPtr);
-        /// Field importedSchema = CArrowSchemaImporter.ImportSchema(importedPtr);
-        /// CArrowSchema.Free(importedPtr);
-        /// </code>
-        /// </examples>
-        public static unsafe Schema ImportSchema(CArrowSchema* ptr)
-        {
-            using var importedSchema = new ImportedArrowSchema(ptr);
-            return importedSchema.GetAsSchema();
-        }
-
-        private sealed unsafe class ImportedArrowSchema : IDisposable
-        {
-            private readonly CArrowSchema* _cSchema;
-            private readonly bool _isRoot;
-
-            public ImportedArrowSchema(CArrowSchema* cSchema)
-            {
-                if (cSchema == null)
-                {
-                    throw new ArgumentException("Passed null pointer for cSchema.");
-                }
-                _cSchema = cSchema;
-                if (_cSchema->release == default)
-                {
-                    throw new ArgumentException("Tried to import a schema that has already been released.");
-                }
-                _isRoot = true;
-            }
-
-            public ImportedArrowSchema(CArrowSchema* handle, bool isRoot) : this(handle)
-            {
-                _isRoot = isRoot;
-            }
-
-            public void Dispose()
-            {
-                // We only call release on a root-level schema, not child ones.
-                if (_isRoot && _cSchema->release != default)
-                {
-#if NET5_0_OR_GREATER
-                    _cSchema->release(_cSchema);
-#else
-                    Marshal.GetDelegateForFunctionPointer<CArrowSchemaExporter.ReleaseArrowSchema>(_cSchema->release)(_cSchema);
-#endif
-                }
-            }
-
-            public ArrowType GetAsType()
-            {
-                var format = StringUtil.PtrToStringUtf8(_cSchema->format);
-                if (_cSchema->dictionary != null)
-                {
-                    ArrowType indicesType = format switch
-                    {
-                        "c" => Int8Type.Default,
-                        "C" => UInt8Type.Default,
-                        "s" => Int16Type.Default,
-                        "S" => UInt16Type.Default,
-                        "i" => Int32Type.Default,
-                        "I" => UInt32Type.Default,
-                        "l" => Int64Type.Default,
-                        "L" => UInt64Type.Default,
-                        _ => throw new InvalidDataException($"Indices must be an integer, but got format string {format}"),
-                    };
-
-                    var dictionarySchema = new ImportedArrowSchema(_cSchema->dictionary, isRoot: false);
-                    ArrowType dictionaryType = dictionarySchema.GetAsType();
-
-                    bool ordered = _cSchema->GetFlag(CArrowSchema.ArrowFlagDictionaryOrdered);
-
-                    return new DictionaryType(indicesType, dictionaryType, ordered);
-                }
-
-                // Special handling for nested types
-                if (format == "+l" || format == "+vl" || format == "+L")
-                {
-                    if (_cSchema->n_children != 1)
-                    {
-                        throw new InvalidDataException("Expected list type to have exactly one child.");
-                    }
-                    ImportedArrowSchema childSchema;
-                    if (_cSchema->GetChild(0) == null)
-                    {
-                        throw new InvalidDataException("Expected list type child to be non-null.");
-                    }
-                    childSchema = new ImportedArrowSchema(_cSchema->GetChild(0), isRoot: false);
-
-                    Field childField = childSchema.GetAsField();
-
-                    return format[1] switch
-                    {
-                        'l' => new ListType(childField),
-                        'v' => new ListViewType(childField),
-                        'L' => new LargeListType(childField),
-                        _ => throw new InvalidDataException($"Invalid format for list: '{format}'"),
-                    };
-                }
-                else if (format == "+s")
-                {
-                    return new StructType(ParseChildren("struct"));
-                }
-                else if (format.StartsWith("+w:"))
-                {
-                    // Fixed-width list
-                    int width = Int32.Parse(format.Substring(3));
-
-                    if (_cSchema->n_children != 1)
-                    {
-                        throw new InvalidDataException("Expected fixed-length list type to have exactly one child.");
-                    }
-                    ImportedArrowSchema childSchema;
-                    if (_cSchema->GetChild(0) == null)
-                    {
-                        throw new InvalidDataException("Expected fixed-length list type child to be non-null.");
-                    }
-                    childSchema = new ImportedArrowSchema(_cSchema->GetChild(0), isRoot: false);
-
-                    Field childField = childSchema.GetAsField();
-
-                    return new FixedSizeListType(childField, width);
-                }
-                else if (format == "+m")
-                {
-                    return new MapType(
-                        ParseChildren("map").Single(),
-                        (_cSchema->flags & CArrowSchema.ArrowFlagMapKeysSorted) != 0);
-                }
-
-                // TODO: Large list type
-
-                // Decimals
-                if (format.StartsWith("d:"))
-                {
-                    string[] parameters = format.Substring(2).Split(',');
-                    int precision = Int32.Parse(parameters[0]);
-                    int scale = Int32.Parse(parameters[1]);
-                    int bitWidth = parameters.Length == 2 ? 128 : Int32.Parse(parameters[2]);
-                    switch (bitWidth)
-                    {
-                        case 32: return new Decimal32Type(precision, scale);
-                        case 64: return new Decimal64Type(precision, scale);
-                        case 128: return new Decimal128Type(precision, scale);
-                        case 256: return new Decimal256Type(precision, scale);
-                        default: throw new InvalidDataException($"Unexpected bit width {bitWidth}");
-                    }
-                }
-
-                // Timestamps
-                if (format.StartsWith("ts"))
-                {
-                    TimeUnit timeUnit = format[2] switch
-                    {
-                        's' => TimeUnit.Second,
-                        'm' => TimeUnit.Millisecond,
-                        'u' => TimeUnit.Microsecond,
-                        'n' => TimeUnit.Nanosecond,
-                        _ => throw new InvalidDataException($"Unsupported time unit for import: {format[2]}"),
-                    };
-
-                    string timezone = format.Substring(format.IndexOf(':') + 1);
-                    if (timezone.Length == 0)
-                    {
-                        timezone = null;
-                    }
-                    return new TimestampType(timeUnit, timezone);
-                }
-
-                // Fixed-width binary
-                if (format.StartsWith("w:"))
-                {
-                    int width = Int32.Parse(format.Substring(2));
-                    return new FixedSizeBinaryType(width);
-                }
-
-                // Unions
-                if (format.StartsWith("+ud:") || format.StartsWith("+us:"))
-                {
-                    UnionMode unionMode = format[2] == 'd' ? UnionMode.Dense : UnionMode.Sparse;
-                    List<int> typeIds = new List<int>();
-                    int pos = 4;
-                    do
-                    {
-                        int next = format.IndexOf(',', pos);
-                        if (next < 0) { next = format.Length; }
-
-                        int code;
-                        if (!int.TryParse(format.Substring(pos, next - pos), out code))
-                        {
-                            throw new InvalidDataException($"Invalid type code for union import: {format.Substring(pos, next - pos)}");
-                        }
-                        typeIds.Add(code);
-
-                        pos = next + 1;
-                    } while (pos < format.Length);
-
-                    return new UnionType(ParseChildren("union"), typeIds, unionMode);
-                }
-
-                return format switch
-                {
-                    // Primitives
-                    "n" => NullType.Default,
-                    "b" => BooleanType.Default,
-                    "c" => Int8Type.Default,
-                    "C" => UInt8Type.Default,
-                    "s" => Int16Type.Default,
-                    "S" => UInt16Type.Default,
-                    "i" => Int32Type.Default,
-                    "I" => UInt32Type.Default,
-                    "l" => Int64Type.Default,
-                    "L" => UInt64Type.Default,
-                    "e" => HalfFloatType.Default,
-                    "f" => FloatType.Default,
-                    "g" => DoubleType.Default,
-                    // Binary data
-                    "z" => BinaryType.Default,
-                    "vz" => BinaryViewType.Default,
-                    "Z" => LargeBinaryType.Default,
-                    "u" => StringType.Default,
-                    "vu" => StringViewType.Default,
-                    "U" => LargeStringType.Default,
-                    // Date and time
-                    "tdD" => Date32Type.Default,
-                    "tdm" => Date64Type.Default,
-                    "tts" => TimeType.Second,
-                    "ttm" => TimeType.Millisecond,
-                    "ttu" => TimeType.Microsecond,
-                    "ttn" => TimeType.Nanosecond,
-                    "tDs" => DurationType.Second,
-                    "tDm" => DurationType.Millisecond,
-                    "tDu" => DurationType.Microsecond,
-                    "tDn" => DurationType.Nanosecond,
-                    "tiM" => IntervalType.YearMonth,
-                    "tiD" => IntervalType.DayTime,
-                    "tin" => IntervalType.MonthDayNanosecond,
-                    _ => throw new NotSupportedException("Data type is not yet supported in import.")
-                };
-            }
-
-            public Field GetAsField()
-            {
-                string name = StringUtil.PtrToStringUtf8(_cSchema->name);
-                string fieldName = string.IsNullOrEmpty(name) ? "" : name;
-
-                bool nullable = _cSchema->GetFlag(CArrowSchema.ArrowFlagNullable);
-
-                return new Field(fieldName, GetAsType(), nullable, GetMetadata(_cSchema->metadata));
-            }
-
-            public Schema GetAsSchema()
-            {
-                ArrowType fullType = GetAsType();
-                if (fullType is StructType structType)
-                {
-                    return new Schema(structType.Fields, GetMetadata(_cSchema->metadata));
-                }
-                else
-                {
-                    throw new ArgumentException("Imported type is not a struct type, so it cannot be converted to a schema.");
-                }
-            }
-
-            private List<Field> ParseChildren(string typeName)
-            {
-                var child_schemas = new ImportedArrowSchema[_cSchema->n_children];
-
-                for (int i = 0; i < _cSchema->n_children; i++)
-                {
-                    if (_cSchema->GetChild(i) == null)
-                    {
-                        throw new InvalidDataException($"Expected {typeName} type child to be non-null.");
-                    }
-                    child_schemas[i] = new ImportedArrowSchema(_cSchema->GetChild(i), isRoot: false);
-                }
-
-                return child_schemas.Select(schema => schema.GetAsField()).ToList();
-            }
-
-            private unsafe static IReadOnlyDictionary<string, string> GetMetadata(byte* metadata)
-            {
-                if (metadata == null)
-                {
-                    return null;
-                }
-
-                IntPtr ptr = (IntPtr)metadata;
-                int count = Marshal.ReadInt32(ptr);
-                if (count <= 0)
-                {
-                    return null;
-                }
-                ptr += 4;
-
-                Dictionary<string, string> result = new Dictionary<string, string>(count);
-                for (int i = 0; i < count; i++)
-                {
-                    result[ReadMetadataString(ref ptr)] = ReadMetadataString(ref ptr);
-                }
-                return result;
-            }
-
-            private unsafe static string ReadMetadataString(ref IntPtr ptr)
-            {
-                int length = Marshal.ReadInt32(ptr);
-                if (length < 0)
-                {
-                    throw new InvalidOperationException("unexpected negative length for metadata string");
-                }
-
-                ptr += 4;
-                string result = Encoding.UTF8.GetString((byte*)ptr, length);
-                ptr += length;
-                return result;
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/C/NativeDelegate.cs b/csharp/src/Apache.Arrow/C/NativeDelegate.cs
deleted file mode 100644
index ebc6330..0000000
--- a/csharp/src/Apache.Arrow/C/NativeDelegate.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace Apache.Arrow.C
-{
-    internal readonly struct NativeDelegate<T> where T : Delegate
-    {
-        private readonly T _managedDelegate; // For lifetime management
-
-        public NativeDelegate(T managedDelegate)
-        {
-            _managedDelegate = managedDelegate;
-            Pointer = Marshal.GetFunctionPointerForDelegate(managedDelegate);
-        }
-
-        public IntPtr Pointer { get; }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/C/StringUtil.cs b/csharp/src/Apache.Arrow/C/StringUtil.cs
deleted file mode 100644
index 9c16493..0000000
--- a/csharp/src/Apache.Arrow/C/StringUtil.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Runtime.InteropServices;
-
-// Adapted from:
-// https://github.com/G-Research/ParquetSharp/blob/467d99298fb5a5b9d5935b9c8dbde95e63954dd3/csharp/StringUtil.cs
-
-namespace Apache.Arrow.C
-{
-
-    internal static class StringUtil
-    {
-        public static unsafe byte* ToCStringUtf8(string str)
-        {
-            var utf8 = System.Text.Encoding.UTF8;
-            int byteCount = utf8.GetByteCount(str);
-            byte* byteArray = (byte*)Marshal.AllocHGlobal(byteCount + 1);
-
-            fixed (char* chars = str)
-            {
-                utf8.GetBytes(chars, str.Length, byteArray, byteCount);
-            }
-
-            // Need to make sure it is null-terminated.
-            byteArray[byteCount] = 0;
-
-            return byteArray;
-        }
-
-        public static unsafe string PtrToStringUtf8(byte* ptr)
-        {
-#if NETSTANDARD2_1_OR_GREATER
-            return Marshal.PtrToStringUTF8(ptr);
-#else
-            if (ptr == null)
-            {
-                return null;
-            }
-
-            int length;
-            for (length = 0; ptr[length] != '\0'; ++length)
-            {
-            }
-
-            return System.Text.Encoding.UTF8.GetString(ptr, length);
-#endif
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/ChunkedArray.cs b/csharp/src/Apache.Arrow/ChunkedArray.cs
deleted file mode 100644
index 85b3560..0000000
--- a/csharp/src/Apache.Arrow/ChunkedArray.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    /// <summary>
-    /// A data structure to manage a list of primitive Array arrays logically as one large array
-    /// </summary>
-    public class ChunkedArray
-    {
-        private IList<IArrowArray> Arrays { get; }
-        public IArrowType DataType { get; }
-        public long Length { get; }
-        public long NullCount { get; }
-
-        public int ArrayCount
-        {
-            get => Arrays.Count;
-        }
-
-        public Array Array(int index) => Arrays[index] as Array;
-
-        public IArrowArray ArrowArray(int index) => Arrays[index];
-
-        public ChunkedArray(IList<Array> arrays)
-            : this(Cast(arrays))
-        {
-        }
-
-        public ChunkedArray(IList<IArrowArray> arrays)
-        {
-            Arrays = arrays ?? throw new ArgumentNullException(nameof(arrays));
-            if (arrays.Count < 1)
-            {
-                throw new ArgumentException($"Count must be at least 1. Got {arrays.Count} instead");
-            }
-            DataType = arrays[0].Data.DataType;
-            foreach (IArrowArray array in arrays)
-            {
-                Length += array.Length;
-                NullCount += array.NullCount;
-            }
-        }
-
-        public ChunkedArray(Array array) : this(new IArrowArray[] { array }) { }
-
-        public ChunkedArray Slice(long offset, long length)
-        {
-            if (offset >= Length)
-            {
-                throw new ArgumentException($"Index {offset} cannot be greater than the Column's Length {Length}");
-            }
-
-            int curArrayIndex = 0;
-            int numArrays = Arrays.Count;
-            while (curArrayIndex < numArrays && offset > Arrays[curArrayIndex].Length)
-            {
-                offset -= Arrays[curArrayIndex].Length;
-                curArrayIndex++;
-            }
-
-            IList<IArrowArray> newArrays = new List<IArrowArray>();
-            while (curArrayIndex < numArrays && length > 0)
-            {
-                newArrays.Add(ArrowArrayFactory.Slice(Arrays[curArrayIndex], (int)offset,
-                              length > Arrays[curArrayIndex].Length ? Arrays[curArrayIndex].Length : (int)length));
-                length -= Arrays[curArrayIndex].Length - offset;
-                offset = 0;
-                curArrayIndex++;
-            }
-            return new ChunkedArray(newArrays);
-        }
-
-        public ChunkedArray Slice(long offset)
-        {
-            return Slice(offset, Length - offset);
-        }
-
-        public override string ToString() => $"{nameof(ChunkedArray)}: Length={Length}, DataType={DataType.Name}";
-      
-        private static IArrowArray[] Cast(IList<Array> arrays)
-        {
-            IArrowArray[] arrowArrays = new IArrowArray[arrays.Count];
-            for (int i = 0; i < arrays.Count; i++)
-            {
-                arrowArrays[i] = arrays[i];
-            }
-            return arrowArrays;
-        }
-
-        // TODO: Flatten for Structs
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Column.cs b/csharp/src/Apache.Arrow/Column.cs
deleted file mode 100644
index 0709b91..0000000
--- a/csharp/src/Apache.Arrow/Column.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    /// <summary>
-    /// A Column data structure that logically represents a column in a dataset
-    /// </summary>
-    public class Column
-    {
-        public Field Field { get;  }
-        public ChunkedArray Data { get; }
-
-        public Column(Field field, IList<Array> arrays)
-            : this(field, new ChunkedArray(arrays), doValidation: true)
-        {
-        }
-
-        public Column(Field field, IList<IArrowArray> arrays)
-            : this(field, new ChunkedArray(arrays), doValidation: true)
-        {
-        }
-
-        private Column(Field field, ChunkedArray data, bool doValidation = false)
-        {
-            Data = data;
-            Field = field;
-            if (doValidation && !ValidateArrayDataTypes())
-            {
-                throw new ArgumentException($"{Field.DataType} must match {Data.DataType}");
-            }
-        }
-
-        public long Length => Data.Length;
-        public long NullCount => Data.NullCount;
-        public string Name => Field.Name;
-        public IArrowType Type => Field.DataType;
-
-        public Column Slice(int offset, int length)
-        {
-            return new Column(Field, Data.Slice(offset, length));
-        }
-
-        public Column Slice(int offset)
-        {
-            return new Column(Field, Data.Slice(offset));
-        }
-
-        private bool ValidateArrayDataTypes()
-        {
-            var dataTypeComparer = new ArrayDataTypeComparer(Field.DataType);
-
-            for (int i = 0; i < Data.ArrayCount; i++)
-            {
-                if (Data.ArrowArray(i).Data.DataType.TypeId != Field.DataType.TypeId)
-                {
-                    return false;
-                }
-
-                Data.ArrowArray(i).Data.DataType.Accept(dataTypeComparer);
-
-                if (!dataTypeComparer.DataTypeMatch)
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/DecimalUtility.cs b/csharp/src/Apache.Arrow/DecimalUtility.cs
deleted file mode 100644
index 363f816..0000000
--- a/csharp/src/Apache.Arrow/DecimalUtility.cs
+++ /dev/null
@@ -1,455 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Data.SqlTypes;
-using System.Numerics;
-
-namespace Apache.Arrow
-{
-    /// <summary>
-    /// This is semi-optimised best attempt at converting to / from decimal and the buffers
-    /// </summary>
-    internal static class DecimalUtility
-    {
-        private static readonly BigInteger _maxDecimal = new BigInteger(decimal.MaxValue);
-        private static readonly BigInteger _minDecimal = new BigInteger(decimal.MinValue);
-        private static readonly ulong[] s_powersOfTen =
-        {
-            1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000,
-            1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000,
-            1000000000000000000, 10000000000000000000
-        };
-
-        private static int PowersOfTenLength => s_powersOfTen.Length - 1;
-
-        internal static decimal GetDecimal(in ArrowBuffer valueBuffer, int index, int scale, int byteWidth)
-        {
-            int startIndex = index * byteWidth;
-            ReadOnlySpan<byte> value = valueBuffer.Span.Slice(startIndex, byteWidth);
-            BigInteger integerValue;
-
-#if NETCOREAPP
-            integerValue = new BigInteger(value);
-#else
-            integerValue = new BigInteger(value.ToArray());
-#endif
-
-            if (integerValue > _maxDecimal || integerValue < _minDecimal)
-            {
-                BigInteger scaleBy = BigInteger.Pow(10, scale);
-                BigInteger integerPart = BigInteger.DivRem(integerValue, scaleBy, out BigInteger fractionalPart);
-
-                // decimal overflow, not much we can do here - C# needs a BigDecimal
-                if (integerPart > _maxDecimal)
-                {
-                    throw new OverflowException($"Value: {integerPart} of {integerValue} is too big be represented as a decimal");
-                }
-                else if (integerPart < _minDecimal) 
-                {
-                    throw new OverflowException($"Value: {integerPart} of {integerValue} is too small be represented as a decimal");
-                }
-                else if (fractionalPart > _maxDecimal || fractionalPart < _minDecimal)
-                {
-                    throw new OverflowException($"Value: {fractionalPart} of {integerValue} is too precise be represented as a decimal");
-                }
-
-                return (decimal)integerPart + DivideByScale(fractionalPart, scale);
-            }
-            else
-            {
-                return DivideByScale(integerValue, scale);
-            }
-        }
-
-#if NETCOREAPP
-        internal unsafe static string GetString(in ArrowBuffer valueBuffer, int index, int precision, int scale, int byteWidth)
-        {
-            int startIndex = index * byteWidth;
-            ReadOnlySpan<byte> value = valueBuffer.Span.Slice(startIndex, byteWidth);
-            BigInteger integerValue = new BigInteger(value);
-            if (scale == 0)
-            {
-                return integerValue.ToString();
-            }
-
-            bool negative = integerValue.Sign < 0;
-            if (negative)
-            {
-                integerValue = -integerValue;
-            }
-
-            int start = scale + 3;
-            Span<char> result = stackalloc char[start + precision];
-            if (!integerValue.TryFormat(result.Slice(start), out int charsWritten) || charsWritten > precision)
-            {
-                throw new OverflowException($"Value: {integerValue} cannot be formatted");
-            }
-
-            if (scale >= charsWritten)
-            {
-                int length = charsWritten;
-                result[++length] = '0';
-                result[++length] = '.';
-                while (scale > length - 2)
-                {
-                    result[++length] = '0';
-                }
-                start = charsWritten + 1;
-                charsWritten = length;
-            }
-            else
-            {
-                result.Slice(start, charsWritten - scale).CopyTo(result.Slice(--start));
-                charsWritten++;
-                result[charsWritten + 1] = '.';
-            }
-
-            if (negative)
-            {
-                result[--start] = '-';
-                charsWritten++;
-            }
-
-            return new string(result.Slice(start, charsWritten));
-        }
-#else
-        internal unsafe static string GetString(in ArrowBuffer valueBuffer, int index, int precision, int scale, int byteWidth)
-        {
-            int startIndex = index * byteWidth;
-            ReadOnlySpan<byte> value = valueBuffer.Span.Slice(startIndex, byteWidth);
-            BigInteger integerValue = new BigInteger(value.ToArray());
-            if (scale == 0)
-            {
-                return integerValue.ToString();
-            }
-
-            bool negative = integerValue.Sign < 0;
-            if (negative)
-            {
-                integerValue = -integerValue;
-            }
-
-            string toString = integerValue.ToString();
-            int charsWritten = toString.Length;
-            if (charsWritten > precision)
-            {
-                throw new OverflowException($"Value: {integerValue} cannot be formatted");
-            }
-
-            char[] result = new char[precision + 2];
-            int pos = 0;
-            if (negative)
-            {
-                result[pos++] = '-';
-            }
-            if (scale >= charsWritten)
-            {
-                result[pos++] = '0';
-                result[pos++] = '.';
-                int length = 0;
-                while (scale > charsWritten + length)
-                {
-                    result[pos++] = '0';
-                    length++;
-                }
-                toString.CopyTo(0, result, pos, charsWritten);
-                pos += charsWritten;
-            }
-            else
-            {
-                int wholePartLength = charsWritten - scale;
-                toString.CopyTo(0, result, pos, wholePartLength);
-                pos += wholePartLength;
-                result[pos++] = '.';
-                toString.CopyTo(wholePartLength, result, pos, scale);
-                pos += scale;
-            }
-            return new string(result, 0, pos);
-        }
-#endif
-
-        internal static SqlDecimal GetSqlDecimal128(in ArrowBuffer valueBuffer, int index, int precision, int scale)
-        {
-            const int byteWidth = 16;
-            const int intWidth = byteWidth / 4;
-            const int longWidth = byteWidth / 8;
-
-            byte mostSignificantByte = valueBuffer.Span[(index + 1) * byteWidth - 1];
-            bool isPositive = (mostSignificantByte & 0x80) == 0;
-
-            if (isPositive)
-            {
-                ReadOnlySpan<int> value = valueBuffer.Span.CastTo<int>().Slice(index * intWidth, intWidth);
-                return new SqlDecimal((byte)precision, (byte)scale, true, value[0], value[1], value[2], value[3]);
-            }
-            else
-            {
-                ReadOnlySpan<long> value = valueBuffer.Span.CastTo<long>().Slice(index * longWidth, longWidth);
-                long data1 = -value[0];
-                long data2 = (data1 == 0) ? -value[1] : ~value[1];
-
-                return new SqlDecimal((byte)precision, (byte)scale, false, (int)(data1 & 0xffffffff), (int)(data1 >> 32), (int)(data2 & 0xffffffff), (int)(data2 >> 32));
-            }
-        }
-
-        private static decimal DivideByScale(BigInteger integerValue, int scale)
-        {
-            decimal result = (decimal)integerValue; // this cast is safe here
-            int drop = scale;
-            while (drop > PowersOfTenLength)
-            {
-                result /= s_powersOfTen[PowersOfTenLength];
-                drop -= PowersOfTenLength;
-            }
-
-            result /= s_powersOfTen[drop];
-            return result;
-        }
-
-        internal static void GetBytes(decimal value, int precision, int scale, int byteWidth, Span<byte> bytes)
-        {
-            // create BigInteger from decimal
-            BigInteger bigInt;
-
-#if NET5_0_OR_GREATER
-            Span<int> decimalBits = stackalloc int[4];
-            decimal.GetBits(value, decimalBits);
-#else
-            int[] decimalBits = decimal.GetBits(value);
-#endif
-
-            int decScale = (decimalBits[3] >> 16) & 0x7F;
-#if NETCOREAPP
-            Span<byte> bigIntBytes = stackalloc byte[13];
-
-            Span<byte> intBytes = stackalloc byte[4];
-            for (int i = 0; i < 3; i++)
-            {
-                int bit = decimalBits[i];
-                if (!BitConverter.TryWriteBytes(intBytes, bit))
-                    throw new OverflowException($"Could not extract bytes from int {bit}");
-
-                for (int j = 0; j < 4; j++)
-                {
-                    bigIntBytes[4 * i + j] = intBytes[j];
-                }
-            }
-            bigInt = new BigInteger(bigIntBytes);
-#else
-            byte[] bigIntBytes = new byte[13];
-            for (int i = 0; i < 3; i++)
-            {
-                int bit = decimalBits[i];
-                byte[] intBytes = BitConverter.GetBytes(bit);
-                for (int j = 0; j < intBytes.Length; j++)
-                {
-                    bigIntBytes[4 * i + j] = intBytes[j];
-                }
-            }
-            bigInt = new BigInteger(bigIntBytes);
-#endif
-
-            if (value < 0)
-            {
-                bigInt = -bigInt;
-            }
-
-            // validate precision and scale
-            if (decScale > scale)
-                throw new OverflowException($"Decimal scale cannot be greater than that in the Arrow vector: {decScale} != {scale}");
-
-            if (bigInt >= BigInteger.Pow(10, precision))
-                throw new OverflowException($"Decimal precision cannot be greater than that in the Arrow vector: {value} has precision > {precision}");
-
-            if (decScale < scale) // pad with trailing zeros
-            {
-                bigInt *= BigInteger.Pow(10, scale - decScale);
-            }
-
-            // extract bytes from BigInteger
-            if (bytes.Length != byteWidth)
-            {
-                throw new OverflowException($"ValueBuffer size not equal to {byteWidth} byte width: {bytes.Length}");
-            }
-
-            int bytesWritten;
-#if NETCOREAPP
-            if (!bigInt.TryWriteBytes(bytes, out bytesWritten, false, !BitConverter.IsLittleEndian))
-                throw new OverflowException("Could not extract bytes from integer value " + bigInt);
-#else
-            byte[] tempBytes = bigInt.ToByteArray();
-            tempBytes.CopyTo(bytes);
-            bytesWritten = tempBytes.Length;
-#endif
-
-            if (bytes.Length > byteWidth)
-            {
-                throw new OverflowException($"Decimal size greater than {byteWidth} bytes: {bytes.Length}");
-            }
-
-            if (bigInt.Sign == -1)
-            {
-                for (int i = bytesWritten; i < byteWidth; i++)
-                {
-                    bytes[i] = 255;
-                }
-            }
-        }
-
-        internal static void GetBytes(string value, int precision, int scale, int byteWidth, Span<byte> bytes)
-        {
-            if (value == null || value.Length == 0)
-            {
-                throw new ArgumentException("numeric value may not be null or blank", nameof(value));
-            }
-
-            int start = 0;
-            if (value[0] == '-' || value[0] == '+')
-            {
-                start++;
-            }
-            while (value[start] == '0' && start < value.Length - 1)
-            {
-                start++;
-            }
-
-            int pos = value.IndexOf('.');
-            int neededPrecision = value.Length - start;
-            int neededScale;
-            if (pos == -1)
-            {
-                neededScale = 0;
-            }
-            else
-            {
-                neededPrecision--;
-                neededScale = value.Length - pos - 1;
-            }
-
-            if (neededScale > scale)
-            {
-                throw new OverflowException($"Decimal scale cannot be greater than that in the Arrow vector: {value} has scale > {scale}");
-            }
-            if (neededPrecision > precision)
-            {
-                throw new OverflowException($"Decimal precision cannot be greater than that in the Arrow vector: {value} has precision > {precision}");
-            }
-
-#if NETCOREAPP
-            ReadOnlySpan<char> src = value.AsSpan();
-            Span<char> buffer = stackalloc char[precision + start + 1];
-
-            int end;
-            if (pos == -1)
-            {
-                src.CopyTo(buffer);
-                end = src.Length;
-            }
-            else
-            {
-                src.Slice(0, pos).CopyTo(buffer);
-                src.Slice(pos + 1).CopyTo(buffer.Slice(pos));
-                end = src.Length - 1;
-            }
-
-            while (neededScale < scale)
-            {
-                buffer[end++] = '0';
-                neededScale++;
-            }
-
-            if (!BigInteger.TryParse(buffer.Slice(0, end), out BigInteger bigInt))
-            {
-                throw new ArgumentException($"Unable to parse {value} as decimal");
-            }
-
-            if (!bigInt.TryWriteBytes(bytes, out int bytesWritten, false, !BitConverter.IsLittleEndian))
-            {
-                throw new OverflowException("Could not extract bytes from integer value " + bigInt);
-            }
-#else
-            char[] buffer = new char[precision + start + 1];
-
-            int end;
-            if (pos == -1)
-            {
-                value.CopyTo(0, buffer, 0, value.Length);
-                end = value.Length;
-            }
-            else
-            {
-                value.CopyTo(0, buffer, 0, pos);
-                value.CopyTo(pos + 1, buffer, pos, neededScale);
-                end = value.Length - 1;
-            }
-
-            while (neededScale < scale)
-            {
-                buffer[end++] = '0';
-                neededScale++;
-            }
-
-            if (!BigInteger.TryParse(new string(buffer, 0, end), out BigInteger bigInt))
-            {
-                throw new ArgumentException($"Unable to parse {value} as decimal");
-            }
-
-            byte[] tempBytes = bigInt.ToByteArray();
-            try
-            {
-                tempBytes.CopyTo(bytes);
-            }
-            catch (ArgumentException)
-            {
-                throw new OverflowException("Could not extract bytes from integer value " + bigInt);
-            }
-            int bytesWritten = tempBytes.Length;
-#endif
-
-            if (bytes.Length > byteWidth)
-            {
-                throw new OverflowException($"Decimal size greater than {byteWidth} bytes: {bytes.Length}");
-            }
-
-            byte fill = bigInt.Sign == -1 ? (byte)255 : (byte)0;
-            for (int i = bytesWritten; i < byteWidth; i++)
-            {
-                bytes[i] = fill;
-            }
-        }
-
-        internal static void GetBytes(SqlDecimal value, int precision, int scale, Span<byte> bytes)
-        {
-            if (value.Precision != precision || value.Scale != scale)
-            {
-                value = SqlDecimal.ConvertToPrecScale(value, precision, scale);
-            }
-
-#if NET7_0_OR_GREATER
-            value.WriteTdsValue(bytes.CastTo<uint>());
-#else
-            value.Data.AsSpan().CopyTo(bytes.CastTo<int>());
-#endif
-
-            if (!value.IsPositive)
-            {
-                Span<long> longSpan = bytes.CastTo<long>();
-                longSpan[0] = -longSpan[0];
-                longSpan[1] = (longSpan[0] == 0) ? -longSpan[1] : ~longSpan[1];
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Extensions/ArrayDataExtensions.cs b/csharp/src/Apache.Arrow/Extensions/ArrayDataExtensions.cs
deleted file mode 100644
index 2b6742a..0000000
--- a/csharp/src/Apache.Arrow/Extensions/ArrayDataExtensions.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-
-namespace Apache.Arrow
-{
-    internal static class ArrayDataExtensions
-    {
-        public static void EnsureBufferCount(this ArrayData data, int count)
-        {
-            if (data.Buffers.Length != count)
-            {
-                // TODO: Use localizable string resource
-                throw new ArgumentException(
-                    $"Buffer count <{data.Buffers.Length}> must be at exactly <{count}>",
-                    nameof(data.Buffers.Length));
-            }
-        }
-
-        public static void EnsureVariadicBufferCount(this ArrayData data, int count)
-        {
-            if (data.Buffers.Length < count)
-            {
-                // TODO: Use localizable string resource
-                throw new ArgumentException(
-                    $"Buffer count <{data.Buffers.Length}> must be at least <{count}>",
-                    nameof(data.Buffers.Length));
-            }
-        }
-
-        public static void EnsureDataType(this ArrayData data, ArrowTypeId id)
-        {
-            if (data.DataType.TypeId != id)
-            {
-                // TODO: Use localizable string resource
-                throw new ArgumentException(
-                    $"Specified array type <{data.DataType.TypeId}> does not match expected type(s) <{id}>",
-                    nameof(data.DataType.TypeId));
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Extensions/ArrayPoolExtensions.cs b/csharp/src/Apache.Arrow/Extensions/ArrayPoolExtensions.cs
deleted file mode 100644
index 5128767..0000000
--- a/csharp/src/Apache.Arrow/Extensions/ArrayPoolExtensions.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.Runtime.CompilerServices;
-
-namespace Apache.Arrow
-{
-    internal static class ArrayPoolExtensions
-    {
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static ArrayLease RentReturn(this ArrayPool<byte> pool, int length, out Memory<byte> buffer)
-        {
-            byte[] array = pool.Rent(length);
-            buffer = array.AsMemory(0, length);
-            return new ArrayLease(pool, array);
-        }
-
-        internal struct ArrayLease : IDisposable
-        {
-            private readonly ArrayPool<byte> _pool;
-            private byte[] _array;
-
-            public ArrayLease(ArrayPool<byte> pool, byte[] array)
-            {
-                _pool = pool;
-                _array = array;
-            }
-
-            public void Dispose()
-            {
-                if (_array != null)
-                {
-                    _pool.Return(_array);
-                    _array = null;
-                }
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Extensions/ArrowTypeExtensions.cs b/csharp/src/Apache.Arrow/Extensions/ArrowTypeExtensions.cs
deleted file mode 100644
index 5b04074..0000000
--- a/csharp/src/Apache.Arrow/Extensions/ArrowTypeExtensions.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Collections.Generic;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public static class ArrowTypeExtensions
-    {
-        private static readonly ISet<ArrowTypeId> s_integralTypes = 
-            new HashSet<ArrowTypeId>(new[]
-            {
-                ArrowTypeId.Int8, ArrowTypeId.Int16, ArrowTypeId.Int32, ArrowTypeId.Int64,
-                ArrowTypeId.UInt8, ArrowTypeId.UInt16, ArrowTypeId.UInt32, ArrowTypeId.UInt64,
-            });
-
-        private static readonly ISet<ArrowTypeId> s_floatingPointTypes =
-            new HashSet<ArrowTypeId>(new[]
-            {
-                ArrowTypeId.HalfFloat, ArrowTypeId.Float, ArrowTypeId.Double
-            });
-
-        public static bool IsIntegral(this IArrowType type) 
-            => s_integralTypes.Contains(type.TypeId);
-
-        public static bool IsFloatingPoint(this IArrowType type)
-            => s_floatingPointTypes.Contains(type.TypeId);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Extensions/FlatbufExtensions.cs b/csharp/src/Apache.Arrow/Extensions/FlatbufExtensions.cs
deleted file mode 100644
index b44c02d..0000000
--- a/csharp/src/Apache.Arrow/Extensions/FlatbufExtensions.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow
-{
-    internal static class FlatbufExtensions
-    {
-        public static Types.IntervalUnit ToArrow(this Flatbuf.IntervalUnit unit)
-        {
-            switch (unit)
-            {
-                case Flatbuf.IntervalUnit.DAY_TIME:
-                    return Types.IntervalUnit.DayTime;
-                case Flatbuf.IntervalUnit.YEAR_MONTH:
-                    return Types.IntervalUnit.YearMonth;
-                case Flatbuf.IntervalUnit.MONTH_DAY_NANO:
-                    return Types.IntervalUnit.MonthDayNanosecond;
-                default:
-                    throw new ArgumentException($"Unexpected Flatbuf IntervalUnit", nameof(unit));
-            }
-        }
-
-        public static Types.DateUnit ToArrow(this Flatbuf.DateUnit unit)
-        {
-            switch (unit)
-            {
-                case Flatbuf.DateUnit.DAY:
-                    return Types.DateUnit.Day;
-                case Flatbuf.DateUnit.MILLISECOND:
-                    return Types.DateUnit.Milliseconds;
-                default:
-                    throw new ArgumentException($"Unexpected Flatbuf IntervalUnit", nameof(unit));
-            }
-        }
-
-        public static Types.TimeUnit ToArrow(this Flatbuf.TimeUnit unit)
-        {
-            switch (unit)
-            {
-                case Flatbuf.TimeUnit.MICROSECOND:
-                    return Types.TimeUnit.Microsecond;
-                case Flatbuf.TimeUnit.MILLISECOND:
-                    return Types.TimeUnit.Millisecond;
-                case Flatbuf.TimeUnit.NANOSECOND:
-                    return Types.TimeUnit.Nanosecond;
-                case Flatbuf.TimeUnit.SECOND:
-                    return Types.TimeUnit.Second;
-                default:
-                    throw new ArgumentException($"Unexpected Flatbuf TimeUnit", nameof(unit));
-            }
-        }
-
-        public static Types.UnionMode ToArrow(this Flatbuf.UnionMode mode)
-        {
-            return mode switch
-            {
-                Flatbuf.UnionMode.Dense => Types.UnionMode.Dense,
-                Flatbuf.UnionMode.Sparse => Types.UnionMode.Sparse,
-                _ => throw new ArgumentException($"Unsupported Flatbuf UnionMode", nameof(mode)),
-            };
-        }
-    }
-}
-
diff --git a/csharp/src/Apache.Arrow/Extensions/SpanExtensions.cs b/csharp/src/Apache.Arrow/Extensions/SpanExtensions.cs
deleted file mode 100644
index b759f38..0000000
--- a/csharp/src/Apache.Arrow/Extensions/SpanExtensions.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace Apache.Arrow
-{
-    public static class SpanExtensions
-    {
-        public static Span<T> CastTo<T>(this Span<byte> span)
-            where T: struct =>
-            MemoryMarshal.Cast<byte, T>(span);
-
-        public static ReadOnlySpan<T> CastTo<T>(this ReadOnlySpan<byte> span)
-            where T: struct =>
-                MemoryMarshal.Cast<byte, T>(span);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Extensions/StreamExtensions.cs b/csharp/src/Apache.Arrow/Extensions/StreamExtensions.cs
deleted file mode 100644
index 1767d23..0000000
--- a/csharp/src/Apache.Arrow/Extensions/StreamExtensions.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow
-{
-    internal static partial class StreamExtensions
-    {
-        public static async ValueTask<int> ReadFullBufferAsync(this Stream stream, Memory<byte> buffer, CancellationToken cancellationToken = default)
-        {
-            int totalBytesRead = 0;
-            do
-            {
-                int bytesRead = 
-                    await stream.ReadAsync(
-                        buffer.Slice(totalBytesRead, buffer.Length - totalBytesRead),
-                        cancellationToken)
-                    .ConfigureAwait(false);
-
-                if (bytesRead == 0)
-                {
-                    // reached the end of the stream
-                    return totalBytesRead;
-                }
-
-                totalBytesRead += bytesRead;
-            }
-            while (totalBytesRead < buffer.Length);
-
-            return totalBytesRead;
-        }
-
-        public static int ReadFullBuffer(this Stream stream, Memory<byte> buffer)
-        {
-            int totalBytesRead = 0;
-            do
-            {
-                int bytesRead = stream.Read(
-                    buffer.Slice(totalBytesRead, buffer.Length - totalBytesRead));
-
-                if (bytesRead == 0)
-                {
-                    // reached the end of the stream
-                    return totalBytesRead;
-                }
-
-                totalBytesRead += bytesRead;
-            }
-            while (totalBytesRead < buffer.Length);
-
-            return totalBytesRead;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Extensions/StreamExtensions.netcoreapp.cs b/csharp/src/Apache.Arrow/Extensions/StreamExtensions.netcoreapp.cs
deleted file mode 100644
index efcacdc..0000000
--- a/csharp/src/Apache.Arrow/Extensions/StreamExtensions.netcoreapp.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-
-namespace Apache.Arrow
-{
-    // Helpers to read from Stream to Memory<byte> on netcoreapp
-    internal static partial class StreamExtensions
-    {
-        public static int Read(this Stream stream, Memory<byte> buffer)
-        {
-            return stream.Read(buffer.Span);
-        }
-
-        public static void Write(this Stream stream, ReadOnlyMemory<byte> buffer)
-        {
-            stream.Write(buffer.Span);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Extensions/StreamExtensions.netstandard.cs b/csharp/src/Apache.Arrow/Extensions/StreamExtensions.netstandard.cs
deleted file mode 100644
index b983be0..0000000
--- a/csharp/src/Apache.Arrow/Extensions/StreamExtensions.netstandard.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow
-{
-    // Helpers to write Memory<byte> to Stream on netstandard
-    internal static partial class StreamExtensions
-    {
-        public static int Read(this Stream stream, Memory<byte> buffer)
-        {
-            if (MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> array))
-            {
-                return stream.Read(array.Array, array.Offset, array.Count);
-            }
-            else
-            {
-                byte[] sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);
-                try
-                {
-                    int result = stream.Read(sharedBuffer, 0, buffer.Length);
-                    new Span<byte>(sharedBuffer, 0, result).CopyTo(buffer.Span);
-                    return result;
-                }
-                finally
-                {
-                    ArrayPool<byte>.Shared.Return(sharedBuffer);
-                }
-            }
-        }
-
-        public static ValueTask<int> ReadAsync(this Stream stream, Memory<byte> buffer, CancellationToken cancellationToken = default)
-        {
-            if (MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> array))
-            {
-                return new ValueTask<int>(stream.ReadAsync(array.Array, array.Offset, array.Count, cancellationToken));
-            }
-            else
-            {
-                byte[] sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);
-                return FinishReadAsync(stream.ReadAsync(sharedBuffer, 0, buffer.Length, cancellationToken), sharedBuffer, buffer);
-
-                async ValueTask<int> FinishReadAsync(Task<int> readTask, byte[] localBuffer, Memory<byte> localDestination)
-                {
-                    try
-                    {
-                        int result = await readTask.ConfigureAwait(false);
-                        new Span<byte>(localBuffer, 0, result).CopyTo(localDestination.Span);
-                        return result;
-                    }
-                    finally
-                    {
-                        ArrayPool<byte>.Shared.Return(localBuffer);
-                    }
-                }
-            }
-        }
-
-        public static void Write(this Stream stream, ReadOnlyMemory<byte> buffer)
-        {
-            if (MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> array))
-            {
-                stream.Write(array.Array, array.Offset, array.Count);
-            }
-            else
-            {
-                byte[] sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);
-                try
-                {
-                    buffer.Span.CopyTo(sharedBuffer);
-                    stream.Write(sharedBuffer, 0, buffer.Length);
-                }
-                finally
-                {
-                    ArrayPool<byte>.Shared.Return(sharedBuffer);
-                }
-            }
-        }
-
-        public static ValueTask WriteAsync(this Stream stream, ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
-        {
-            if (MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> array))
-            {
-                return new ValueTask(stream.WriteAsync(array.Array, array.Offset, array.Count, cancellationToken));
-            }
-            else
-            {
-                byte[] sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);
-                buffer.Span.CopyTo(sharedBuffer);
-                return FinishWriteAsync(stream.WriteAsync(sharedBuffer, 0, buffer.Length, cancellationToken), sharedBuffer);
-            }
-        }
-
-        private static async ValueTask FinishWriteAsync(Task writeTask, byte[] localBuffer)
-        {
-            try
-            {
-                await writeTask.ConfigureAwait(false);
-            }
-            finally
-            {
-                ArrayPool<byte>.Shared.Return(localBuffer);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Extensions/TimeSpanExtensions.cs b/csharp/src/Apache.Arrow/Extensions/TimeSpanExtensions.cs
deleted file mode 100644
index 133156d..0000000
--- a/csharp/src/Apache.Arrow/Extensions/TimeSpanExtensions.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow
-{
-    public static class TimeSpanExtensions
-    {
-        /// <summary>
-        /// Formats a TimeSpan into an ISO 8601 compliant time offset string.
-        /// </summary>
-        /// <param name="timeSpan">timeSpan to format</param>
-        /// <returns>ISO 8601 offset string</returns>
-        public static string ToTimeZoneOffsetString(this TimeSpan timeSpan)
-        {
-            string sign = timeSpan.Hours >= 0 ? "+" : "-";
-            int hours = Math.Abs(timeSpan.Hours);
-            int minutes = Math.Abs(timeSpan.Minutes);
-            return sign + hours.ToString("00") + ":" + minutes.ToString("00");
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Extensions/TupleExtensions.netstandard.cs b/csharp/src/Apache.Arrow/Extensions/TupleExtensions.netstandard.cs
deleted file mode 100644
index e0e0f57..0000000
--- a/csharp/src/Apache.Arrow/Extensions/TupleExtensions.netstandard.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow
-{
-    // Helpers to Deconstruct Tuples on netstandard
-    internal static partial class TupleExtensions
-    {
-        public static void Deconstruct<T1, T2>(this Tuple<T1, T2> value, out T1 item1, out T2 item2)
-        {
-            item1 = value.Item1;
-            item2 = value.Item2;
-        }
-
-        public static void Deconstruct<T1, T2, T3>(this Tuple<T1, T2, T3> value, out T1 item1, out T2 item2, out T3 item3)
-        {
-            item1 = value.Item1;
-            item2 = value.Item2;
-            item3 = value.Item3;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Field.Builder.cs b/csharp/src/Apache.Arrow/Field.Builder.cs
deleted file mode 100644
index f7f3338..0000000
--- a/csharp/src/Apache.Arrow/Field.Builder.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Arrow
-{
-    public partial class Field
-    {
-        public class Builder
-        {
-            private Dictionary<string, string> _metadata;
-            private string _name;
-            private IArrowType _type;
-            private bool _nullable;
-
-            public Builder()
-            {
-                _type = NullType.Default;
-                _nullable = true;
-            }
-
-            public Builder Name(string value)
-            {
-                if (value == null)
-                {
-                    throw new ArgumentNullException(nameof(value));
-                }
-
-                _name = value;
-                return this;
-            }
-
-            public Builder DataType(IArrowType type)
-            {
-                _type = type ?? NullType.Default;
-                return this;
-            }
-
-            public Builder Nullable(bool value)
-            {
-                _nullable = value;
-                return this;
-            }
-
-            public Builder Metadata(string key, string value)
-            {
-                if (string.IsNullOrWhiteSpace(key))
-                {
-                    throw new ArgumentNullException(nameof(key));
-                }
-
-                _metadata ??= new Dictionary<string, string>();
-
-                _metadata[key] = value;
-                return this;
-            }
-
-            public Builder Metadata(IEnumerable<KeyValuePair<string, string>> dictionary)
-            {
-                if (dictionary == null)
-                {
-                    throw new ArgumentNullException(nameof(dictionary));
-                }
-                foreach (KeyValuePair<string, string> entry in dictionary)
-                {
-                    Metadata(entry.Key, entry.Value);
-                }
-                return this;
-            }
-
-            public Field Build()
-            {
-                return new Field(_name, _type, _nullable, _metadata);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Field.cs b/csharp/src/Apache.Arrow/Field.cs
deleted file mode 100644
index ac3cafa..0000000
--- a/csharp/src/Apache.Arrow/Field.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public partial class Field
-    {
-        public IArrowType DataType { get; }
-
-        public string Name { get; }
-
-        public bool IsNullable { get; }
-
-        public bool HasMetadata => Metadata?.Count > 0;
-
-        public IReadOnlyDictionary<string, string> Metadata { get; }
-
-        public Field(string name, IArrowType dataType, bool nullable,
-            IEnumerable<KeyValuePair<string, string>> metadata = default)
-            : this(name, dataType, nullable)
-        {
-            Metadata = metadata?.ToDictionary(kv => kv.Key, kv => kv.Value);
-        }
-
-        internal Field(string name, IArrowType dataType, bool nullable,
-            IReadOnlyDictionary<string, string> metadata, bool copyCollections)
-            : this(name, dataType, nullable)
-        {
-            Debug.Assert(copyCollections == false, "This internal constructor is to not copy the collections.");
-
-            Metadata = metadata;
-        }
-
-        private Field(string name, IArrowType dataType, bool nullable)
-        {
-            if (name == null)
-            {
-                throw new ArgumentNullException(nameof(name));
-            }
-
-            Name = name;
-            DataType = dataType ?? NullType.Default;
-            IsNullable = nullable;
-        }
-
-        public override string ToString() => $"{nameof(Field)}: Name={Name}, DataType={DataType.Name}, IsNullable={IsNullable}, Metadata count={Metadata?.Count ?? 0}";
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/BinaryView.cs b/csharp/src/Apache.Arrow/Flatbuf/BinaryView.cs
deleted file mode 100644
index 2f9cca5..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/BinaryView.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Logically the same as Binary, but the internal representation uses a view
-/// struct that contains the string length and either the string's entire data
-/// inline (for small strings) or an inlined prefix, an index of another buffer,
-/// and an offset pointing to a slice in that buffer (for non-small strings).
-///
-/// Since it uses a variable number of data buffers, each Field with this type
-/// must have a corresponding entry in `variadicBufferCounts`.
-internal struct BinaryView : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static BinaryView GetRootAsBinaryView(ByteBuffer _bb) { return GetRootAsBinaryView(_bb, new BinaryView()); }
-  public static BinaryView GetRootAsBinaryView(ByteBuffer _bb, BinaryView obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public BinaryView __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartBinaryView(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<BinaryView> EndBinaryView(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<BinaryView>(o);
-  }
-}
-
-
-static internal class BinaryViewVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Block.cs b/csharp/src/Apache.Arrow/Flatbuf/Block.cs
deleted file mode 100644
index 8df0159..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Block.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct Block : IFlatbufferObject
-{
-  private Struct __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
-  public Block __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// Index to the start of the RecordBlock (note this is past the Message header)
-  public long Offset { get { return __p.bb.GetLong(__p.bb_pos + 0); } }
-  /// Length of the metadata
-  public int MetaDataLength { get { return __p.bb.GetInt(__p.bb_pos + 8); } }
-  /// Length of the data (this is aligned so there can be a gap between this and
-  /// the metadata).
-  public long BodyLength { get { return __p.bb.GetLong(__p.bb_pos + 16); } }
-
-  public static Offset<Block> CreateBlock(FlatBufferBuilder builder, long Offset, int MetaDataLength, long BodyLength) {
-    builder.Prep(8, 24);
-    builder.PutLong(BodyLength);
-    builder.Pad(4);
-    builder.PutInt(MetaDataLength);
-    builder.PutLong(Offset);
-    return new Offset<Block>(builder.Offset);
-  }
-}
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/BodyCompression.cs b/csharp/src/Apache.Arrow/Flatbuf/BodyCompression.cs
deleted file mode 100644
index bbc0e1e..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/BodyCompression.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Optional compression for the memory buffers constituting IPC message
-/// bodies. Intended for use with RecordBatch but could be used for other
-/// message types
-internal struct BodyCompression : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static BodyCompression GetRootAsBodyCompression(ByteBuffer _bb) { return GetRootAsBodyCompression(_bb, new BodyCompression()); }
-  public static BodyCompression GetRootAsBodyCompression(ByteBuffer _bb, BodyCompression obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public BodyCompression __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// Compressor library.
-  /// For LZ4_FRAME, each compressed buffer must consist of a single frame.
-  public CompressionType Codec { get { int o = __p.__offset(4); return o != 0 ? (CompressionType)__p.bb.GetSbyte(o + __p.bb_pos) : CompressionType.LZ4_FRAME; } }
-  /// Indicates the way the record batch body was compressed
-  public BodyCompressionMethod Method { get { int o = __p.__offset(6); return o != 0 ? (BodyCompressionMethod)__p.bb.GetSbyte(o + __p.bb_pos) : BodyCompressionMethod.BUFFER; } }
-
-  public static Offset<BodyCompression> CreateBodyCompression(FlatBufferBuilder builder,
-      CompressionType codec = CompressionType.LZ4_FRAME,
-      BodyCompressionMethod method = BodyCompressionMethod.BUFFER) {
-    builder.StartTable(2);
-    BodyCompression.AddMethod(builder, method);
-    BodyCompression.AddCodec(builder, codec);
-    return BodyCompression.EndBodyCompression(builder);
-  }
-
-  public static void StartBodyCompression(FlatBufferBuilder builder) { builder.StartTable(2); }
-  public static void AddCodec(FlatBufferBuilder builder, CompressionType codec) { builder.AddSbyte(0, (sbyte)codec, 0); }
-  public static void AddMethod(FlatBufferBuilder builder, BodyCompressionMethod method) { builder.AddSbyte(1, (sbyte)method, 0); }
-  public static Offset<BodyCompression> EndBodyCompression(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<BodyCompression>(o);
-  }
-}
-
-
-static internal class BodyCompressionVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Codec*/, 1 /*CompressionType*/, 1, false)
-      && verifier.VerifyField(tablePos, 6 /*Method*/, 1 /*BodyCompressionMethod*/, 1, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Buffer.cs b/csharp/src/Apache.Arrow/Flatbuf/Buffer.cs
deleted file mode 100644
index 419800d..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Buffer.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// ----------------------------------------------------------------------
-/// A Buffer represents a single contiguous memory segment
-internal struct Buffer : IFlatbufferObject
-{
-  private Struct __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
-  public Buffer __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// The relative offset into the shared memory page where the bytes for this
-  /// buffer starts
-  public long Offset { get { return __p.bb.GetLong(__p.bb_pos + 0); } }
-  /// The absolute length (in bytes) of the memory buffer. The memory is found
-  /// from offset (inclusive) to offset + length (non-inclusive). When building
-  /// messages using the encapsulated IPC message, padding bytes may be written
-  /// after a buffer, but such padding bytes do not need to be accounted for in
-  /// the size here.
-  public long Length { get { return __p.bb.GetLong(__p.bb_pos + 8); } }
-
-  public static Offset<Buffer> CreateBuffer(FlatBufferBuilder builder, long Offset, long Length) {
-    builder.Prep(8, 16);
-    builder.PutLong(Length);
-    builder.PutLong(Offset);
-    return new Offset<Buffer>(builder.Offset);
-  }
-}
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/DictionaryBatch.cs b/csharp/src/Apache.Arrow/Flatbuf/DictionaryBatch.cs
deleted file mode 100644
index 180e941..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/DictionaryBatch.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// For sending dictionary encoding information. Any Field can be
-/// dictionary-encoded, but in this case none of its children may be
-/// dictionary-encoded.
-/// There is one vector / column per dictionary, but that vector / column
-/// may be spread across multiple dictionary batches by using the isDelta
-/// flag
-internal struct DictionaryBatch : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static DictionaryBatch GetRootAsDictionaryBatch(ByteBuffer _bb) { return GetRootAsDictionaryBatch(_bb, new DictionaryBatch()); }
-  public static DictionaryBatch GetRootAsDictionaryBatch(ByteBuffer _bb, DictionaryBatch obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public DictionaryBatch __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public long Id { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
-  public RecordBatch? Data { get { int o = __p.__offset(6); return o != 0 ? (RecordBatch?)(new RecordBatch()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
-  /// If isDelta is true the values in the dictionary are to be appended to a
-  /// dictionary with the indicated id. If isDelta is false this dictionary
-  /// should replace the existing dictionary.
-  public bool IsDelta { get { int o = __p.__offset(8); return o != 0 ? 0!=__p.bb.Get(o + __p.bb_pos) : (bool)false; } }
-
-  public static Offset<DictionaryBatch> CreateDictionaryBatch(FlatBufferBuilder builder,
-      long id = 0,
-      Offset<RecordBatch> dataOffset = default(Offset<RecordBatch>),
-      bool isDelta = false) {
-    builder.StartTable(3);
-    DictionaryBatch.AddId(builder, id);
-    DictionaryBatch.AddData(builder, dataOffset);
-    DictionaryBatch.AddIsDelta(builder, isDelta);
-    return DictionaryBatch.EndDictionaryBatch(builder);
-  }
-
-  public static void StartDictionaryBatch(FlatBufferBuilder builder) { builder.StartTable(3); }
-  public static void AddId(FlatBufferBuilder builder, long id) { builder.AddLong(0, id, 0); }
-  public static void AddData(FlatBufferBuilder builder, Offset<RecordBatch> dataOffset) { builder.AddOffset(1, dataOffset.Value, 0); }
-  public static void AddIsDelta(FlatBufferBuilder builder, bool isDelta) { builder.AddBool(2, isDelta, false); }
-  public static Offset<DictionaryBatch> EndDictionaryBatch(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<DictionaryBatch>(o);
-  }
-}
-
-
-static internal class DictionaryBatchVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Id*/, 8 /*long*/, 8, false)
-      && verifier.VerifyTable(tablePos, 6 /*Data*/, RecordBatchVerify.Verify, false)
-      && verifier.VerifyField(tablePos, 8 /*IsDelta*/, 1 /*bool*/, 1, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/DictionaryEncoding.cs b/csharp/src/Apache.Arrow/Flatbuf/DictionaryEncoding.cs
deleted file mode 100644
index ecf1dd788..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/DictionaryEncoding.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct DictionaryEncoding : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static DictionaryEncoding GetRootAsDictionaryEncoding(ByteBuffer _bb) { return GetRootAsDictionaryEncoding(_bb, new DictionaryEncoding()); }
-  public static DictionaryEncoding GetRootAsDictionaryEncoding(ByteBuffer _bb, DictionaryEncoding obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public DictionaryEncoding __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// The known dictionary id in the application where this data is used. In
-  /// the file or streaming formats, the dictionary ids are found in the
-  /// DictionaryBatch messages
-  public long Id { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
-  /// The dictionary indices are constrained to be non-negative integers. If
-  /// this field is null, the indices must be signed int32. To maximize
-  /// cross-language compatibility and performance, implementations are
-  /// recommended to prefer signed integer types over unsigned integer types
-  /// and to avoid uint64 indices unless they are required by an application.
-  public Int? IndexType { get { int o = __p.__offset(6); return o != 0 ? (Int?)(new Int()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
-  /// By default, dictionaries are not ordered, or the order does not have
-  /// semantic meaning. In some statistical, applications, dictionary-encoding
-  /// is used to represent ordered categorical data, and we provide a way to
-  /// preserve that metadata here
-  public bool IsOrdered { get { int o = __p.__offset(8); return o != 0 ? 0!=__p.bb.Get(o + __p.bb_pos) : (bool)false; } }
-  public DictionaryKind DictionaryKind { get { int o = __p.__offset(10); return o != 0 ? (DictionaryKind)__p.bb.GetShort(o + __p.bb_pos) : DictionaryKind.DenseArray; } }
-
-  public static Offset<DictionaryEncoding> CreateDictionaryEncoding(FlatBufferBuilder builder,
-      long id = 0,
-      Offset<Int> indexTypeOffset = default(Offset<Int>),
-      bool isOrdered = false,
-      DictionaryKind dictionaryKind = DictionaryKind.DenseArray) {
-    builder.StartTable(4);
-    DictionaryEncoding.AddId(builder, id);
-    DictionaryEncoding.AddIndexType(builder, indexTypeOffset);
-    DictionaryEncoding.AddDictionaryKind(builder, dictionaryKind);
-    DictionaryEncoding.AddIsOrdered(builder, isOrdered);
-    return DictionaryEncoding.EndDictionaryEncoding(builder);
-  }
-
-  public static void StartDictionaryEncoding(FlatBufferBuilder builder) { builder.StartTable(4); }
-  public static void AddId(FlatBufferBuilder builder, long id) { builder.AddLong(0, id, 0); }
-  public static void AddIndexType(FlatBufferBuilder builder, Offset<Int> indexTypeOffset) { builder.AddOffset(1, indexTypeOffset.Value, 0); }
-  public static void AddIsOrdered(FlatBufferBuilder builder, bool isOrdered) { builder.AddBool(2, isOrdered, false); }
-  public static void AddDictionaryKind(FlatBufferBuilder builder, DictionaryKind dictionaryKind) { builder.AddShort(3, (short)dictionaryKind, 0); }
-  public static Offset<DictionaryEncoding> EndDictionaryEncoding(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<DictionaryEncoding>(o);
-  }
-}
-
-
-static internal class DictionaryEncodingVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Id*/, 8 /*long*/, 8, false)
-      && verifier.VerifyTable(tablePos, 6 /*IndexType*/, IntVerify.Verify, false)
-      && verifier.VerifyField(tablePos, 8 /*IsOrdered*/, 1 /*bool*/, 1, false)
-      && verifier.VerifyField(tablePos, 10 /*DictionaryKind*/, 2 /*DictionaryKind*/, 2, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/BodyCompressionMethod.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/BodyCompressionMethod.cs
deleted file mode 100644
index e1f0c8f..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/BodyCompressionMethod.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-/// Provided for forward compatibility in case we need to support different
-/// strategies for compressing the IPC message body (like whole-body
-/// compression rather than buffer-level) in the future
-internal enum BodyCompressionMethod : sbyte
-{
-  /// Each constituent buffer is first compressed with the indicated
-  /// compressor, and then written with the uncompressed length in the first 8
-  /// bytes as a 64-bit little-endian signed integer followed by the compressed
-  /// buffer bytes (and then padding as required by the protocol). The
-  /// uncompressed length may be set to -1 to indicate that the data that
-  /// follows is not compressed, which can be useful for cases where
-  /// compression does not yield appreciable savings.
-  BUFFER = 0,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/CompressionType.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/CompressionType.cs
deleted file mode 100644
index 3d886c5..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/CompressionType.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-internal enum CompressionType : sbyte
-{
- LZ4_FRAME = 0,
- ZSTD = 1,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/DateUnit.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/DateUnit.cs
deleted file mode 100644
index 46fd0cc..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/DateUnit.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-internal enum DateUnit : short
-{
- DAY = 0,
- MILLISECOND = 1,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/DictionaryKind.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/DictionaryKind.cs
deleted file mode 100644
index 9a67bc7..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/DictionaryKind.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-/// ----------------------------------------------------------------------
-/// Dictionary encoding metadata
-/// Maintained for forwards compatibility, in the future
-/// Dictionaries might be explicit maps between integers and values
-/// allowing for non-contiguous index values
-internal enum DictionaryKind : short
-{
-  DenseArray = 0,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/Endianness.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/Endianness.cs
deleted file mode 100644
index a0e64f4..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/Endianness.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-/// ----------------------------------------------------------------------
-/// Endianness of the platform producing the data
-internal enum Endianness : short
-{
- Little = 0,
- Big = 1,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/Feature.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/Feature.cs
deleted file mode 100644
index a05b6cf..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/Feature.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-/// Represents Arrow Features that might not have full support
-/// within implementations. This is intended to be used in
-/// two scenarios:
-///  1.  A mechanism for readers of Arrow Streams
-///      and files to understand that the stream or file makes
-///      use of a feature that isn't supported or unknown to
-///      the implementation (and therefore can meet the Arrow
-///      forward compatibility guarantees).
-///  2.  A means of negotiating between a client and server
-///      what features a stream is allowed to use. The enums
-///      values here are intented to represent higher level
-///      features, additional details maybe negotiated
-///      with key-value pairs specific to the protocol.
-///
-/// Enums added to this list should be assigned power-of-two values
-/// to facilitate exchanging and comparing bitmaps for supported
-/// features.
-internal enum Feature : long
-{
-  /// Needed to make flatbuffers happy.
- UNUSED = 0,
-  /// The stream makes use of multiple full dictionaries with the
-  /// same ID and assumes clients implement dictionary replacement
-  /// correctly.
- DICTIONARY_REPLACEMENT = 1,
-  /// The stream makes use of compressed bodies as described
-  /// in Message.fbs.
- COMPRESSED_BODY = 2,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/IntervalUnit.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/IntervalUnit.cs
deleted file mode 100644
index ac82c72..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/IntervalUnit.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-internal enum IntervalUnit : short
-{
-  YEAR_MONTH = 0,
-  DAY_TIME = 1,
-  MONTH_DAY_NANO = 2,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/MessageHeader.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/MessageHeader.cs
deleted file mode 100644
index 1204b1e..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/MessageHeader.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-/// ----------------------------------------------------------------------
-/// The root Message type
-/// This union enables us to easily send different message types without
-/// redundant storage, and in the future we can easily add new message types.
-///
-/// Arrow implementations do not need to implement all of the message types,
-/// which may include experimental metadata types. For maximum compatibility,
-/// it is best to send data using RecordBatch
-internal enum MessageHeader : byte
-{
-  NONE = 0,
-  Schema = 1,
-  DictionaryBatch = 2,
-  RecordBatch = 3,
-  Tensor = 4,
-  SparseTensor = 5,
-};
-
-
-
-static internal class MessageHeaderVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
-  {
-    bool result = true;
-    switch((MessageHeader)typeId)
-    {
-      case MessageHeader.Schema:
-        result = SchemaVerify.Verify(verifier, tablePos);
-        break;
-      case MessageHeader.DictionaryBatch:
-        result = DictionaryBatchVerify.Verify(verifier, tablePos);
-        break;
-      case MessageHeader.RecordBatch:
-        result = RecordBatchVerify.Verify(verifier, tablePos);
-        break;
-      case MessageHeader.Tensor:
-        result = TensorVerify.Verify(verifier, tablePos);
-        break;
-      case MessageHeader.SparseTensor:
-        result = SparseTensorVerify.Verify(verifier, tablePos);
-        break;
-      default: result = true;
-        break;
-    }
-    return result;
-  }
-}
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/MetadataVersion.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/MetadataVersion.cs
deleted file mode 100644
index 13b5315..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/MetadataVersion.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-internal enum MetadataVersion : short
-{
-  /// 0.1.0 (October 2016).
-  V1 = 0,
-  /// 0.2.0 (February 2017). Non-backwards compatible with V1.
-  V2 = 1,
-  /// 0.3.0 -> 0.7.1 (May - December 2017). Non-backwards compatible with V2.
-  V3 = 2,
-  /// >= 0.8.0 (December 2017). Non-backwards compatible with V3.
-  V4 = 3,
-  /// >= 1.0.0 (July 2020). Backwards compatible with V4 (V5 readers can read V4
-  /// metadata and IPC messages). Implementations are recommended to provide a
-  /// V4 compatibility mode with V5 format changes disabled.
-  ///
-  /// Incompatible changes between V4 and V5:
-  /// - Union buffer layout has changed. In V5, Unions don't have a validity
-  ///   bitmap buffer.
-  V5 = 4,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/Precision.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/Precision.cs
deleted file mode 100644
index 3f47a2c..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/Precision.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-internal enum Precision : short
-{
- HALF = 0,
- SINGLE = 1,
- DOUBLE = 2,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/TimeUnit.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/TimeUnit.cs
deleted file mode 100644
index 300b835..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/TimeUnit.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-internal enum TimeUnit : short
-{
- SECOND = 0,
- MILLISECOND = 1,
- MICROSECOND = 2,
- NANOSECOND = 3,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/Type.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/Type.cs
deleted file mode 100644
index 9c04288..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/Type.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-/// ----------------------------------------------------------------------
-/// Top-level Type value, enabling extensible type-specific metadata. We can
-/// add new logical types to Type without breaking backwards compatibility
-internal enum Type : byte
-{
-  NONE = 0,
-  Null = 1,
-  Int = 2,
-  FloatingPoint = 3,
-  Binary = 4,
-  Utf8 = 5,
-  Bool = 6,
-  Decimal = 7,
-  Date = 8,
-  Time = 9,
-  Timestamp = 10,
-  Interval = 11,
-  List = 12,
-  Struct_ = 13,
-  Union = 14,
-  FixedSizeBinary = 15,
-  FixedSizeList = 16,
-  Map = 17,
-  Duration = 18,
-  LargeBinary = 19,
-  LargeUtf8 = 20,
-  LargeList = 21,
-  RunEndEncoded = 22,
-  BinaryView = 23,
-  Utf8View = 24,
-  ListView = 25,
-  LargeListView = 26,
-};
-
-
-
-static internal class TypeVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
-  {
-    bool result = true;
-    switch((Type)typeId)
-    {
-      case Type.Null:
-        result = NullVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Int:
-        result = IntVerify.Verify(verifier, tablePos);
-        break;
-      case Type.FloatingPoint:
-        result = FloatingPointVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Binary:
-        result = BinaryVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Utf8:
-        result = Utf8Verify.Verify(verifier, tablePos);
-        break;
-      case Type.Bool:
-        result = BoolVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Decimal:
-        result = DecimalVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Date:
-        result = DateVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Time:
-        result = TimeVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Timestamp:
-        result = TimestampVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Interval:
-        result = IntervalVerify.Verify(verifier, tablePos);
-        break;
-      case Type.List:
-        result = ListVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Struct_:
-        result = Struct_Verify.Verify(verifier, tablePos);
-        break;
-      case Type.Union:
-        result = UnionVerify.Verify(verifier, tablePos);
-        break;
-      case Type.FixedSizeBinary:
-        result = FixedSizeBinaryVerify.Verify(verifier, tablePos);
-        break;
-      case Type.FixedSizeList:
-        result = FixedSizeListVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Map:
-        result = MapVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Duration:
-        result = DurationVerify.Verify(verifier, tablePos);
-        break;
-      case Type.LargeBinary:
-        result = LargeBinaryVerify.Verify(verifier, tablePos);
-        break;
-      case Type.LargeUtf8:
-        result = LargeUtf8Verify.Verify(verifier, tablePos);
-        break;
-      case Type.LargeList:
-        result = LargeListVerify.Verify(verifier, tablePos);
-        break;
-      case Type.RunEndEncoded:
-        result = RunEndEncodedVerify.Verify(verifier, tablePos);
-        break;
-      case Type.BinaryView:
-        result = BinaryViewVerify.Verify(verifier, tablePos);
-        break;
-      case Type.Utf8View:
-        result = Utf8ViewVerify.Verify(verifier, tablePos);
-        break;
-      case Type.ListView:
-        result = ListViewVerify.Verify(verifier, tablePos);
-        break;
-      case Type.LargeListView:
-        result = LargeListViewVerify.Verify(verifier, tablePos);
-        break;
-      default: result = true;
-        break;
-    }
-    return result;
-  }
-}
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Enums/UnionMode.cs b/csharp/src/Apache.Arrow/Flatbuf/Enums/UnionMode.cs
deleted file mode 100644
index 724ff4a..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Enums/UnionMode.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-internal enum UnionMode : short
-{
- Sparse = 0,
- Dense = 1,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Field.cs b/csharp/src/Apache.Arrow/Flatbuf/Field.cs
deleted file mode 100644
index efbc6af..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Field.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// ----------------------------------------------------------------------
-/// A field represents a named column in a record / row batch or child of a
-/// nested type.
-internal struct Field : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Field GetRootAsField(ByteBuffer _bb) { return GetRootAsField(_bb, new Field()); }
-  public static Field GetRootAsField(ByteBuffer _bb, Field obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Field __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// Name is not required, in i.e. a List
-  public string Name { get { int o = __p.__offset(4); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
-#if ENABLE_SPAN_T
-  public Span<byte> GetNameBytes() { return __p.__vector_as_span<byte>(4, 1); }
-#else
-  public ArraySegment<byte>? GetNameBytes() { return __p.__vector_as_arraysegment(4); }
-#endif
-  public byte[] GetNameArray() { return __p.__vector_as_array<byte>(4); }
-  /// Whether or not this field can contain nulls. Should be true in general.
-  public bool Nullable { get { int o = __p.__offset(6); return o != 0 ? 0!=__p.bb.Get(o + __p.bb_pos) : (bool)false; } }
-  public Type TypeType { get { int o = __p.__offset(8); return o != 0 ? (Type)__p.bb.Get(o + __p.bb_pos) : Apache.Arrow.Flatbuf.Type.NONE; } }
-  /// This is the type of the decoded value if the field is dictionary encoded.
-  public TTable? Type<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(10); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
-  public Null TypeAsNull() { return Type<Null>().Value; }
-  public Int TypeAsInt() { return Type<Int>().Value; }
-  public FloatingPoint TypeAsFloatingPoint() { return Type<FloatingPoint>().Value; }
-  public Binary TypeAsBinary() { return Type<Binary>().Value; }
-  public Utf8 TypeAsUtf8() { return Type<Utf8>().Value; }
-  public Bool TypeAsBool() { return Type<Bool>().Value; }
-  public Decimal TypeAsDecimal() { return Type<Decimal>().Value; }
-  public Date TypeAsDate() { return Type<Date>().Value; }
-  public Time TypeAsTime() { return Type<Time>().Value; }
-  public Timestamp TypeAsTimestamp() { return Type<Timestamp>().Value; }
-  public Interval TypeAsInterval() { return Type<Interval>().Value; }
-  public List TypeAsList() { return Type<List>().Value; }
-  public Struct_ TypeAsStruct_() { return Type<Struct_>().Value; }
-  public Union TypeAsUnion() { return Type<Union>().Value; }
-  public FixedSizeBinary TypeAsFixedSizeBinary() { return Type<FixedSizeBinary>().Value; }
-  public FixedSizeList TypeAsFixedSizeList() { return Type<FixedSizeList>().Value; }
-  public Map TypeAsMap() { return Type<Map>().Value; }
-  public Duration TypeAsDuration() { return Type<Duration>().Value; }
-  public LargeBinary TypeAsLargeBinary() { return Type<LargeBinary>().Value; }
-  public LargeUtf8 TypeAsLargeUtf8() { return Type<LargeUtf8>().Value; }
-  public LargeList TypeAsLargeList() { return Type<LargeList>().Value; }
-  public RunEndEncoded TypeAsRunEndEncoded() { return Type<RunEndEncoded>().Value; }
-  public BinaryView TypeAsBinaryView() { return Type<BinaryView>().Value; }
-  public Utf8View TypeAsUtf8View() { return Type<Utf8View>().Value; }
-  public ListView TypeAsListView() { return Type<ListView>().Value; }
-  public LargeListView TypeAsLargeListView() { return Type<LargeListView>().Value; }
-  /// Present only if the field is dictionary encoded.
-  public DictionaryEncoding? Dictionary { get { int o = __p.__offset(12); return o != 0 ? (DictionaryEncoding?)(new DictionaryEncoding()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
-  /// children apply only to nested data types like Struct, List and Union. For
-  /// primitive types children will have length 0.
-  public Field? Children(int j) { int o = __p.__offset(14); return o != 0 ? (Field?)(new Field()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
-  public int ChildrenLength { get { int o = __p.__offset(14); return o != 0 ? __p.__vector_len(o) : 0; } }
-  /// User-defined metadata
-  public KeyValue? CustomMetadata(int j) { int o = __p.__offset(16); return o != 0 ? (KeyValue?)(new KeyValue()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
-  public int CustomMetadataLength { get { int o = __p.__offset(16); return o != 0 ? __p.__vector_len(o) : 0; } }
-
-  public static Offset<Field> CreateField(FlatBufferBuilder builder,
-      StringOffset nameOffset = default(StringOffset),
-      bool nullable = false,
-      Type type_type = Apache.Arrow.Flatbuf.Type.NONE,
-      int typeOffset = 0,
-      Offset<DictionaryEncoding> dictionaryOffset = default(Offset<DictionaryEncoding>),
-      VectorOffset childrenOffset = default(VectorOffset),
-      VectorOffset custom_metadataOffset = default(VectorOffset)) {
-    builder.StartTable(7);
-    Field.AddCustomMetadata(builder, custom_metadataOffset);
-    Field.AddChildren(builder, childrenOffset);
-    Field.AddDictionary(builder, dictionaryOffset);
-    Field.AddType(builder, typeOffset);
-    Field.AddName(builder, nameOffset);
-    Field.AddTypeType(builder, type_type);
-    Field.AddNullable(builder, nullable);
-    return Field.EndField(builder);
-  }
-
-  public static void StartField(FlatBufferBuilder builder) { builder.StartTable(7); }
-  public static void AddName(FlatBufferBuilder builder, StringOffset nameOffset) { builder.AddOffset(0, nameOffset.Value, 0); }
-  public static void AddNullable(FlatBufferBuilder builder, bool nullable) { builder.AddBool(1, nullable, false); }
-  public static void AddTypeType(FlatBufferBuilder builder, Type typeType) { builder.AddByte(2, (byte)typeType, 0); }
-  public static void AddType(FlatBufferBuilder builder, int typeOffset) { builder.AddOffset(3, typeOffset, 0); }
-  public static void AddDictionary(FlatBufferBuilder builder, Offset<DictionaryEncoding> dictionaryOffset) { builder.AddOffset(4, dictionaryOffset.Value, 0); }
-  public static void AddChildren(FlatBufferBuilder builder, VectorOffset childrenOffset) { builder.AddOffset(5, childrenOffset.Value, 0); }
-  public static VectorOffset CreateChildrenVector(FlatBufferBuilder builder, Offset<Field>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
-  public static VectorOffset CreateChildrenVectorBlock(FlatBufferBuilder builder, Offset<Field>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateChildrenVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<Field>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateChildrenVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<Field>>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartChildrenVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
-  public static void AddCustomMetadata(FlatBufferBuilder builder, VectorOffset customMetadataOffset) { builder.AddOffset(6, customMetadataOffset.Value, 0); }
-  public static VectorOffset CreateCustomMetadataVector(FlatBufferBuilder builder, Offset<KeyValue>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, Offset<KeyValue>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<KeyValue>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<KeyValue>>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartCustomMetadataVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
-  public static Offset<Field> EndField(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Field>(o);
-  }
-}
-
-
-static internal class FieldVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyString(tablePos, 4 /*Name*/, false)
-      && verifier.VerifyField(tablePos, 6 /*Nullable*/, 1 /*bool*/, 1, false)
-      && verifier.VerifyField(tablePos, 8 /*TypeType*/, 1 /*Type*/, 1, false)
-      && verifier.VerifyUnion(tablePos, 8, 10 /*Type*/, TypeVerify.Verify, false)
-      && verifier.VerifyTable(tablePos, 12 /*Dictionary*/, DictionaryEncodingVerify.Verify, false)
-      && verifier.VerifyVectorOfTables(tablePos, 14 /*Children*/, FieldVerify.Verify, false)
-      && verifier.VerifyVectorOfTables(tablePos, 16 /*CustomMetadata*/, KeyValueVerify.Verify, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FieldNode.cs b/csharp/src/Apache.Arrow/Flatbuf/FieldNode.cs
deleted file mode 100644
index 960970d..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FieldNode.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// ----------------------------------------------------------------------
-/// Data structures for describing a table row batch (a collection of
-/// equal-length Arrow arrays)
-/// Metadata about a field at some level of a nested type tree (but not
-/// its children).
-///
-/// For example, a List<Int16> with values `[[1, 2, 3], null, [4], [5, 6], null]`
-/// would have {length: 5, null_count: 2} for its List node, and {length: 6,
-/// null_count: 0} for its Int16 node, as separate FieldNode structs
-internal struct FieldNode : IFlatbufferObject
-{
-  private Struct __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
-  public FieldNode __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// The number of value slots in the Arrow array at this level of a nested
-  /// tree
-  public long Length { get { return __p.bb.GetLong(__p.bb_pos + 0); } }
-  /// The number of observed nulls. Fields with null_count == 0 may choose not
-  /// to write their physical validity bitmap out as a materialized buffer,
-  /// instead setting the length of the bitmap buffer to 0.
-  public long NullCount { get { return __p.bb.GetLong(__p.bb_pos + 8); } }
-
-  public static Offset<FieldNode> CreateFieldNode(FlatBufferBuilder builder, long Length, long NullCount) {
-    builder.Prep(8, 16);
-    builder.PutLong(NullCount);
-    builder.PutLong(Length);
-    return new Offset<FieldNode>(builder.Offset);
-  }
-}
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FixedSizeBinary.cs b/csharp/src/Apache.Arrow/Flatbuf/FixedSizeBinary.cs
deleted file mode 100644
index babe81f..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FixedSizeBinary.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct FixedSizeBinary : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static FixedSizeBinary GetRootAsFixedSizeBinary(ByteBuffer _bb) { return GetRootAsFixedSizeBinary(_bb, new FixedSizeBinary()); }
-  public static FixedSizeBinary GetRootAsFixedSizeBinary(ByteBuffer _bb, FixedSizeBinary obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public FixedSizeBinary __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// Number of bytes per value
-  public int ByteWidth { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
-
-  public static Offset<FixedSizeBinary> CreateFixedSizeBinary(FlatBufferBuilder builder,
-      int byteWidth = 0) {
-    builder.StartTable(1);
-    FixedSizeBinary.AddByteWidth(builder, byteWidth);
-    return FixedSizeBinary.EndFixedSizeBinary(builder);
-  }
-
-  public static void StartFixedSizeBinary(FlatBufferBuilder builder) { builder.StartTable(1); }
-  public static void AddByteWidth(FlatBufferBuilder builder, int byteWidth) { builder.AddInt(0, byteWidth, 0); }
-  public static Offset<FixedSizeBinary> EndFixedSizeBinary(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<FixedSizeBinary>(o);
-  }
-}
-
-
-static internal class FixedSizeBinaryVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*ByteWidth*/, 4 /*int*/, 4, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FixedSizeList.cs b/csharp/src/Apache.Arrow/Flatbuf/FixedSizeList.cs
deleted file mode 100644
index 6293a7f..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FixedSizeList.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct FixedSizeList : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static FixedSizeList GetRootAsFixedSizeList(ByteBuffer _bb) { return GetRootAsFixedSizeList(_bb, new FixedSizeList()); }
-  public static FixedSizeList GetRootAsFixedSizeList(ByteBuffer _bb, FixedSizeList obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public FixedSizeList __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// Number of list items per value
-  public int ListSize { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
-
-  public static Offset<FixedSizeList> CreateFixedSizeList(FlatBufferBuilder builder,
-      int listSize = 0) {
-    builder.StartTable(1);
-    FixedSizeList.AddListSize(builder, listSize);
-    return FixedSizeList.EndFixedSizeList(builder);
-  }
-
-  public static void StartFixedSizeList(FlatBufferBuilder builder) { builder.StartTable(1); }
-  public static void AddListSize(FlatBufferBuilder builder, int listSize) { builder.AddInt(0, listSize, 0); }
-  public static Offset<FixedSizeList> EndFixedSizeList(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<FixedSizeList>(o);
-  }
-}
-
-
-static internal class FixedSizeListVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*ListSize*/, 4 /*int*/, 4, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/ByteBuffer.cs b/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/ByteBuffer.cs
deleted file mode 100644
index c3b3a17..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/ByteBuffer.cs
+++ /dev/null
@@ -1,1041 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// There are three conditional compilation symbols that have an impact on performance/features of this ByteBuffer implementation.
-//
-//      UNSAFE_BYTEBUFFER
-//          This will use unsafe code to manipulate the underlying byte array. This
-//          can yield a reasonable performance increase.
-//
-//      BYTEBUFFER_NO_BOUNDS_CHECK
-//          This will disable the bounds check asserts to the byte array. This can
-//          yield a small performance gain in normal code.
-//
-//      ENABLE_SPAN_T
-//          This will enable reading and writing blocks of memory with a Span<T> instead of just
-//          T[].  You can also enable writing directly to shared memory or other types of memory
-//          by providing a custom implementation of ByteBufferAllocator.
-//          ENABLE_SPAN_T also requires UNSAFE_BYTEBUFFER to be defined, or .NET
-//          Standard 2.1.
-//
-// Using UNSAFE_BYTEBUFFER and BYTEBUFFER_NO_BOUNDS_CHECK together can yield a
-// performance gain of ~15% for some operations, however doing so is potentially
-// dangerous. Do so at your own risk!
-//
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-using System.Buffers.Binary;
-#endif
-
-#if ENABLE_SPAN_T && !UNSAFE_BYTEBUFFER && !NETSTANDARD2_1
-#warning ENABLE_SPAN_T requires UNSAFE_BYTEBUFFER to also be defined
-#endif
-
-namespace Google.FlatBuffers
-{
-    internal abstract class ByteBufferAllocator
-    {
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-        public abstract Span<byte> Span { get; }
-        public abstract ReadOnlySpan<byte> ReadOnlySpan { get; }
-        public abstract Memory<byte> Memory { get; }
-        public abstract ReadOnlyMemory<byte> ReadOnlyMemory { get; }
-
-#else
-        public byte[] Buffer
-        {
-            get;
-            protected set;
-        }
-#endif
-
-        public int Length
-        {
-            get;
-            protected set;
-        }
-
-        public abstract void GrowFront(int newSize);
-    }
-
-    internal sealed class ByteArrayAllocator : ByteBufferAllocator
-    {
-        private byte[] _buffer;
-
-        public ByteArrayAllocator(byte[] buffer)
-        {
-            _buffer = buffer;
-            InitBuffer();
-        }
-
-        public override void GrowFront(int newSize)
-        {
-            if ((Length & 0xC0000000) != 0)
-                throw new Exception(
-                    "ByteBuffer: cannot grow buffer beyond 2 gigabytes.");
-
-            if (newSize < Length)
-                throw new Exception("ByteBuffer: cannot truncate buffer.");
-
-            byte[] newBuffer = new byte[newSize];
-            System.Buffer.BlockCopy(_buffer, 0, newBuffer, newSize - Length, Length);
-            _buffer = newBuffer;
-            InitBuffer();
-        }
-
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-        public override Span<byte> Span => _buffer;
-        public override ReadOnlySpan<byte> ReadOnlySpan => _buffer;
-        public override Memory<byte> Memory => _buffer;
-        public override ReadOnlyMemory<byte> ReadOnlyMemory => _buffer;
-#endif
-
-        private void InitBuffer()
-        {
-            Length = _buffer.Length;
-#if !ENABLE_SPAN_T
-            Buffer = _buffer;
-#endif
-        }
-    }
-
-    /// <summary>
-    /// Class to mimic Java's ByteBuffer which is used heavily in Flatbuffers.
-    /// </summary>
-    internal class ByteBuffer
-    {
-        private ByteBufferAllocator _buffer;
-        private int _pos;  // Must track start of the buffer.
-
-        public ByteBuffer(ByteBufferAllocator allocator, int position)
-        {
-            _buffer = allocator;
-            _pos = position;
-        }
-
-        public ByteBuffer(int size) : this(new byte[size]) { }
-
-        public ByteBuffer(byte[] buffer) : this(buffer, 0) { }
-
-        public ByteBuffer(byte[] buffer, int pos)
-        {
-            _buffer = new ByteArrayAllocator(buffer);
-            _pos = pos;
-        }
-
-        public int Position
-        {
-            get { return _pos; }
-            set { _pos = value; }
-        }
-
-        public int Length { get { return _buffer.Length; } }
-
-        public void Reset()
-        {
-            _pos = 0;
-        }
-
-        // Create a new ByteBuffer on the same underlying data.
-        // The new ByteBuffer's position will be same as this buffer's.
-        public ByteBuffer Duplicate()
-        {
-            return new ByteBuffer(_buffer, Position);
-        }
-
-        // Increases the size of the ByteBuffer, and copies the old data towards
-        // the end of the new buffer.
-        public void GrowFront(int newSize)
-        {
-            _buffer.GrowFront(newSize);
-        }
-
-        public byte[] ToArray(int pos, int len)
-        {
-            return ToArray<byte>(pos, len);
-        }
-
-        /// <summary>
-        /// A lookup of type sizes. Used instead of Marshal.SizeOf() which has additional
-        /// overhead, but also is compatible with generic functions for simplified code.
-        /// </summary>
-        private static Dictionary<Type, int> genericSizes = new Dictionary<Type, int>()
-        {
-            { typeof(bool),     sizeof(bool) },
-            { typeof(float),    sizeof(float) },
-            { typeof(double),   sizeof(double) },
-            { typeof(sbyte),    sizeof(sbyte) },
-            { typeof(byte),     sizeof(byte) },
-            { typeof(short),    sizeof(short) },
-            { typeof(ushort),   sizeof(ushort) },
-            { typeof(int),      sizeof(int) },
-            { typeof(uint),     sizeof(uint) },
-            { typeof(ulong),    sizeof(ulong) },
-            { typeof(long),     sizeof(long) },
-        };
-
-        /// <summary>
-        /// Get the wire-size (in bytes) of a type supported by flatbuffers.
-        /// </summary>
-        /// <param name="t">The type to get the wire size of</param>
-        /// <returns></returns>
-        public static int SizeOf<T>()
-        {
-            return genericSizes[typeof(T)];
-        }
-
-        /// <summary>
-        /// Checks if the Type provided is supported as scalar value
-        /// </summary>
-        /// <typeparam name="T">The Type to check</typeparam>
-        /// <returns>True if the type is a scalar type that is supported, false otherwise</returns>
-        public static bool IsSupportedType<T>()
-        {
-            return genericSizes.ContainsKey(typeof(T));
-        }
-
-        /// <summary>
-        /// Get the wire-size (in bytes) of an typed array
-        /// </summary>
-        /// <typeparam name="T">The type of the array</typeparam>
-        /// <param name="x">The array to get the size of</param>
-        /// <returns>The number of bytes the array takes on wire</returns>
-        public static int ArraySize<T>(T[] x)
-        {
-            return SizeOf<T>() * x.Length;
-        }
-
-        /// <summary>
-        /// Get the wire-size (in bytes) of an typed array segment, taking only the
-        /// range specified by <paramref name="x"/> into account.
-        /// </summary>
-        /// <typeparam name="T">The type of the array</typeparam>
-        /// <param name="x">The array segment to get the size of</param>
-        /// <returns>The number of bytes the array segment takes on wire</returns>
-        public static int ArraySize<T>(ArraySegment<T> x)
-        {
-            return SizeOf<T>() * x.Count;
-        }
-
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-        public static int ArraySize<T>(Span<T> x)
-        {
-            return SizeOf<T>() * x.Length;
-        }
-#endif
-
-        // Get a portion of the buffer casted into an array of type T, given
-        // the buffer position and length.
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-        public T[] ToArray<T>(int pos, int len)
-            where T : struct
-        {
-            AssertOffsetAndLength(pos, len);
-            return MemoryMarshal.Cast<byte, T>(_buffer.ReadOnlySpan.Slice(pos)).Slice(0, len).ToArray();
-        }
-#else
-        public T[] ToArray<T>(int pos, int len)
-            where T : struct
-        {
-            AssertOffsetAndLength(pos, len);
-            T[] arr = new T[len];
-            Buffer.BlockCopy(_buffer.Buffer, pos, arr, 0, ArraySize(arr));
-            return arr;
-        }
-#endif
-
-        public byte[] ToSizedArray()
-        {
-            return ToArray<byte>(Position, Length - Position);
-        }
-
-        public byte[] ToFullArray()
-        {
-            return ToArray<byte>(0, Length);
-        }
-
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-        public ReadOnlyMemory<byte> ToReadOnlyMemory(int pos, int len)
-        {
-            return _buffer.ReadOnlyMemory.Slice(pos, len);
-        }
-
-        public Memory<byte> ToMemory(int pos, int len)
-        {
-            return _buffer.Memory.Slice(pos, len);
-        }
-
-        public Span<byte> ToSpan(int pos, int len)
-        {
-            return _buffer.Span.Slice(pos, len);
-        }
-#else
-        public ArraySegment<byte> ToArraySegment(int pos, int len)
-        {
-            return new ArraySegment<byte>(_buffer.Buffer, pos, len);
-        }
-
-        public MemoryStream ToMemoryStream(int pos, int len)
-        {
-            return new MemoryStream(_buffer.Buffer, pos, len);
-        }
-#endif
-
-#if !UNSAFE_BYTEBUFFER
-        // A conversion union where all the members are overlapping. This allows to reinterpret the bytes of one type
-        // as another, without additional copies.
-        [StructLayout(LayoutKind.Explicit)]
-        struct ConversionUnion
-        {
-          [FieldOffset(0)] public int intValue;
-          [FieldOffset(0)] public float floatValue;
-        }
-#endif // !UNSAFE_BYTEBUFFER
-
-        // Helper functions for the unsafe version.
-        static public ushort ReverseBytes(ushort input)
-        {
-            return (ushort)(((input & 0x00FFU) << 8) |
-                            ((input & 0xFF00U) >> 8));
-        }
-        static public uint ReverseBytes(uint input)
-        {
-            return ((input & 0x000000FFU) << 24) |
-                   ((input & 0x0000FF00U) <<  8) |
-                   ((input & 0x00FF0000U) >>  8) |
-                   ((input & 0xFF000000U) >> 24);
-        }
-        static public ulong ReverseBytes(ulong input)
-        {
-            return (((input & 0x00000000000000FFUL) << 56) |
-                    ((input & 0x000000000000FF00UL) << 40) |
-                    ((input & 0x0000000000FF0000UL) << 24) |
-                    ((input & 0x00000000FF000000UL) <<  8) |
-                    ((input & 0x000000FF00000000UL) >>  8) |
-                    ((input & 0x0000FF0000000000UL) >> 24) |
-                    ((input & 0x00FF000000000000UL) >> 40) |
-                    ((input & 0xFF00000000000000UL) >> 56));
-        }
-
-#if !UNSAFE_BYTEBUFFER && (!ENABLE_SPAN_T || !NETSTANDARD2_1)
-        // Helper functions for the safe (but slower) version.
-        protected void WriteLittleEndian(int offset, int count, ulong data)
-        {
-            if (BitConverter.IsLittleEndian)
-            {
-                for (int i = 0; i < count; i++)
-                {
-                    _buffer.Buffer[offset + i] = (byte)(data >> i * 8);
-                }
-            }
-            else
-            {
-                for (int i = 0; i < count; i++)
-                {
-                    _buffer.Buffer[offset + count - 1 - i] = (byte)(data >> i * 8);
-                }
-            }
-        }
-
-        protected ulong ReadLittleEndian(int offset, int count)
-        {
-            AssertOffsetAndLength(offset, count);
-            ulong r = 0;
-            if (BitConverter.IsLittleEndian)
-            {
-                for (int i = 0; i < count; i++)
-                {
-                    r |= (ulong)_buffer.Buffer[offset + i] << i * 8;
-                }
-            }
-            else
-            {
-                for (int i = 0; i < count; i++)
-                {
-                    r |= (ulong)_buffer.Buffer[offset + count - 1 - i] << i * 8;
-                }
-            }
-            return r;
-        }
-#elif ENABLE_SPAN_T && NETSTANDARD2_1
-        protected void WriteLittleEndian(int offset, int count, ulong data)
-        {
-            if (BitConverter.IsLittleEndian)
-            {
-                for (int i = 0; i < count; i++)
-                {
-                    _buffer.Span[offset + i] = (byte)(data >> i * 8);
-                }
-            }
-            else
-            {
-                for (int i = 0; i < count; i++)
-                {
-                    _buffer.Span[offset + count - 1 - i] = (byte)(data >> i * 8);
-                }
-            }
-        }
-
-        protected ulong ReadLittleEndian(int offset, int count)
-        {
-            AssertOffsetAndLength(offset, count);
-            ulong r = 0;
-            if (BitConverter.IsLittleEndian)
-            {
-                for (int i = 0; i < count; i++)
-                {
-                    r |= (ulong)_buffer.Span[offset + i] << i * 8;
-                }
-            }
-            else
-            {
-                for (int i = 0; i < count; i++)
-                {
-                    r |= (ulong)_buffer.Span[offset + count - 1 - i] << i * 8;
-                }
-            }
-            return r;
-        }
-#endif
-
-        private void AssertOffsetAndLength(int offset, int length)
-        {
-#if !BYTEBUFFER_NO_BOUNDS_CHECK
-            if (offset < 0 ||
-                offset > _buffer.Length - length)
-                throw new ArgumentOutOfRangeException();
-#endif
-        }
-
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-
-        public void PutSbyte(int offset, sbyte value)
-        {
-            AssertOffsetAndLength(offset, sizeof(sbyte));
-            _buffer.Span[offset] = (byte)value;
-        }
-
-        public void PutByte(int offset, byte value)
-        {
-            AssertOffsetAndLength(offset, sizeof(byte));
-            _buffer.Span[offset] = value;
-        }
-
-        public void PutByte(int offset, byte value, int count)
-        {
-            AssertOffsetAndLength(offset, sizeof(byte) * count);
-            Span<byte> span = _buffer.Span.Slice(offset, count);
-            for (var i = 0; i < span.Length; ++i)
-                span[i] = value;
-        }
-#else
-        public void PutSbyte(int offset, sbyte value)
-        {
-            AssertOffsetAndLength(offset, sizeof(sbyte));
-            _buffer.Buffer[offset] = (byte)value;
-        }
-
-        public void PutByte(int offset, byte value)
-        {
-            AssertOffsetAndLength(offset, sizeof(byte));
-            _buffer.Buffer[offset] = value;
-        }
-
-        public void PutByte(int offset, byte value, int count)
-        {
-            AssertOffsetAndLength(offset, sizeof(byte) * count);
-            for (var i = 0; i < count; ++i)
-                _buffer.Buffer[offset + i] = value;
-        }
-#endif
-
-        // this method exists in order to conform with Java ByteBuffer standards
-        public void Put(int offset, byte value)
-        {
-            PutByte(offset, value);
-        }
-
-#if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER
-        public unsafe void PutStringUTF8(int offset, string value)
-        {
-            AssertOffsetAndLength(offset, value.Length);
-            fixed (char* s = value)
-            {
-                fixed (byte* buffer = &MemoryMarshal.GetReference(_buffer.Span))
-                {
-                    Encoding.UTF8.GetBytes(s, value.Length, buffer + offset, Length - offset);
-                }
-            }
-        }
-#elif ENABLE_SPAN_T && NETSTANDARD2_1
-        public void PutStringUTF8(int offset, string value)
-        {
-            AssertOffsetAndLength(offset, value.Length);
-            Encoding.UTF8.GetBytes(value.AsSpan().Slice(0, value.Length),
-                _buffer.Span.Slice(offset));
-        }
-#else
-        public void PutStringUTF8(int offset, string value)
-        {
-            AssertOffsetAndLength(offset, value.Length);
-            Encoding.UTF8.GetBytes(value, 0, value.Length,
-                _buffer.Buffer, offset);
-        }
-#endif
-
-#if UNSAFE_BYTEBUFFER
-        // Unsafe but more efficient versions of Put*.
-        public void PutShort(int offset, short value)
-        {
-            PutUshort(offset, (ushort)value);
-        }
-
-        public unsafe void PutUshort(int offset, ushort value)
-        {
-            AssertOffsetAndLength(offset, sizeof(ushort));
-#if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
-            Span<byte> span = _buffer.Span.Slice(offset);
-            BinaryPrimitives.WriteUInt16LittleEndian(span, value);
-#else
-            fixed (byte* ptr = _buffer.Buffer)
-            {
-                *(ushort*)(ptr + offset) = BitConverter.IsLittleEndian
-                    ? value
-                    : ReverseBytes(value);
-            }
-#endif
-        }
-
-        public void PutInt(int offset, int value)
-        {
-            PutUint(offset, (uint)value);
-        }
-
-        public unsafe void PutUint(int offset, uint value)
-        {
-            AssertOffsetAndLength(offset, sizeof(uint));
-#if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
-            Span<byte> span = _buffer.Span.Slice(offset);
-            BinaryPrimitives.WriteUInt32LittleEndian(span, value);
-#else
-            fixed (byte* ptr = _buffer.Buffer)
-            {
-                *(uint*)(ptr + offset) = BitConverter.IsLittleEndian
-                    ? value
-                    : ReverseBytes(value);
-            }
-#endif
-        }
-
-        public unsafe void PutLong(int offset, long value)
-        {
-            PutUlong(offset, (ulong)value);
-        }
-
-        public unsafe void PutUlong(int offset, ulong value)
-        {
-            AssertOffsetAndLength(offset, sizeof(ulong));
-#if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
-            Span<byte> span = _buffer.Span.Slice(offset);
-            BinaryPrimitives.WriteUInt64LittleEndian(span, value);
-#else
-            fixed (byte* ptr = _buffer.Buffer)
-            {
-                *(ulong*)(ptr + offset) = BitConverter.IsLittleEndian
-                    ? value
-                    : ReverseBytes(value);
-            }
-#endif
-        }
-
-        public unsafe void PutFloat(int offset, float value)
-        {
-            AssertOffsetAndLength(offset, sizeof(float));
-#if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
-            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.Span))
-#else
-            fixed (byte* ptr = _buffer.Buffer)
-#endif
-            {
-                if (BitConverter.IsLittleEndian)
-                {
-                    *(float*)(ptr + offset) = value;
-                }
-                else
-                {
-                    *(uint*)(ptr + offset) = ReverseBytes(*(uint*)(&value));
-                }
-            }
-        }
-
-        public unsafe void PutDouble(int offset, double value)
-        {
-            AssertOffsetAndLength(offset, sizeof(double));
-#if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
-            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.Span))
-#else
-            fixed (byte* ptr = _buffer.Buffer)
-#endif
-            {
-                if (BitConverter.IsLittleEndian)
-                {
-                    *(double*)(ptr + offset) = value;
-                }
-                else
-                {
-                    *(ulong*)(ptr + offset) = ReverseBytes(*(ulong*)(&value));
-                }
-            }
-        }
-#else // !UNSAFE_BYTEBUFFER
-        // Slower versions of Put* for when unsafe code is not allowed.
-        public void PutShort(int offset, short value)
-        {
-            AssertOffsetAndLength(offset, sizeof(short));
-            WriteLittleEndian(offset, sizeof(short), (ulong)value);
-        }
-
-        public void PutUshort(int offset, ushort value)
-        {
-            AssertOffsetAndLength(offset, sizeof(ushort));
-            WriteLittleEndian(offset, sizeof(ushort), (ulong)value);
-        }
-
-        public void PutInt(int offset, int value)
-        {
-            AssertOffsetAndLength(offset, sizeof(int));
-            WriteLittleEndian(offset, sizeof(int), (ulong)value);
-        }
-
-        public void PutUint(int offset, uint value)
-        {
-            AssertOffsetAndLength(offset, sizeof(uint));
-            WriteLittleEndian(offset, sizeof(uint), (ulong)value);
-        }
-
-        public void PutLong(int offset, long value)
-        {
-            AssertOffsetAndLength(offset, sizeof(long));
-            WriteLittleEndian(offset, sizeof(long), (ulong)value);
-        }
-
-        public void PutUlong(int offset, ulong value)
-        {
-            AssertOffsetAndLength(offset, sizeof(ulong));
-            WriteLittleEndian(offset, sizeof(ulong), value);
-        }
-
-        public void PutFloat(int offset, float value)
-        {
-            AssertOffsetAndLength(offset, sizeof(float));
-            // TODO(derekbailey): use BitConvert.SingleToInt32Bits() whenever flatbuffers upgrades to a .NET version
-            // that contains it.
-            ConversionUnion union;
-            union.intValue = 0;
-            union.floatValue = value;    
-            WriteLittleEndian(offset, sizeof(float), (ulong)union.intValue);
-        }
-
-        public void PutDouble(int offset, double value)
-        {
-            AssertOffsetAndLength(offset, sizeof(double));
-            WriteLittleEndian(offset, sizeof(double), (ulong)BitConverter.DoubleToInt64Bits(value));
-        }
-
-#endif // UNSAFE_BYTEBUFFER
-
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-        public sbyte GetSbyte(int index)
-        {
-            AssertOffsetAndLength(index, sizeof(sbyte));
-            return (sbyte)_buffer.ReadOnlySpan[index];
-        }
-
-        public byte Get(int index)
-        {
-            AssertOffsetAndLength(index, sizeof(byte));
-            return _buffer.ReadOnlySpan[index];
-        }
-#else
-        public sbyte GetSbyte(int index)
-        {
-            AssertOffsetAndLength(index, sizeof(sbyte));
-            return (sbyte)_buffer.Buffer[index];
-        }
-
-        public byte Get(int index)
-        {
-            AssertOffsetAndLength(index, sizeof(byte));
-            return _buffer.Buffer[index];
-        }
-#endif
-
-#if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER
-        public unsafe string GetStringUTF8(int startPos, int len)
-        {
-            fixed (byte* buffer = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan.Slice(startPos)))
-            {
-                return Encoding.UTF8.GetString(buffer, len);
-            }
-        }
-#elif ENABLE_SPAN_T && NETSTANDARD2_1
-        public string GetStringUTF8(int startPos, int len)
-        {
-            return Encoding.UTF8.GetString(_buffer.Span.Slice(startPos, len));
-        }
-#else
-        public string GetStringUTF8(int startPos, int len)
-        {
-            return Encoding.UTF8.GetString(_buffer.Buffer, startPos, len);
-        }
-#endif
-
-#if UNSAFE_BYTEBUFFER
-        // Unsafe but more efficient versions of Get*.
-        public short GetShort(int offset)
-        {
-            return (short)GetUshort(offset);
-        }
-
-        public unsafe ushort GetUshort(int offset)
-        {
-            AssertOffsetAndLength(offset, sizeof(ushort));
-#if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
-            ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
-            return BinaryPrimitives.ReadUInt16LittleEndian(span);
-#else
-            fixed (byte* ptr = _buffer.Buffer)
-            {
-                return BitConverter.IsLittleEndian
-                    ? *(ushort*)(ptr + offset)
-                    : ReverseBytes(*(ushort*)(ptr + offset));
-            }
-#endif
-        }
-
-        public int GetInt(int offset)
-        {
-            return (int)GetUint(offset);
-        }
-
-        public unsafe uint GetUint(int offset)
-        {
-            AssertOffsetAndLength(offset, sizeof(uint));
-#if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
-            ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
-            return BinaryPrimitives.ReadUInt32LittleEndian(span);
-#else
-            fixed (byte* ptr = _buffer.Buffer)
-            {
-                return BitConverter.IsLittleEndian
-                    ? *(uint*)(ptr + offset)
-                    : ReverseBytes(*(uint*)(ptr + offset));
-            }
-#endif
-        }
-
-        public long GetLong(int offset)
-        {
-            return (long)GetUlong(offset);
-        }
-
-        public unsafe ulong GetUlong(int offset)
-        {
-            AssertOffsetAndLength(offset, sizeof(ulong));
-#if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
-            ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
-            return BinaryPrimitives.ReadUInt64LittleEndian(span);
-#else            
-            fixed (byte* ptr = _buffer.Buffer)
-            {
-                return BitConverter.IsLittleEndian
-                    ? *(ulong*)(ptr + offset)
-                    : ReverseBytes(*(ulong*)(ptr + offset));
-            }
-#endif
-        }
-
-        public unsafe float GetFloat(int offset)
-        {
-            AssertOffsetAndLength(offset, sizeof(float));
-#if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
-            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan))
-#else
-            fixed (byte* ptr = _buffer.Buffer)
-#endif
-            {
-                if (BitConverter.IsLittleEndian)
-                {
-                    return *(float*)(ptr + offset);
-                }
-                else
-                {
-                    uint uvalue = ReverseBytes(*(uint*)(ptr + offset));
-                    return *(float*)(&uvalue);
-                }
-            }
-        }
-
-        public unsafe double GetDouble(int offset)
-        {
-            AssertOffsetAndLength(offset, sizeof(double));
-#if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
-            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan))
-#else
-            fixed (byte* ptr = _buffer.Buffer)
-#endif
-            {
-                if (BitConverter.IsLittleEndian)
-                {
-                    return *(double*)(ptr + offset);
-                }
-                else
-                {
-                    ulong uvalue = ReverseBytes(*(ulong*)(ptr + offset));
-                    return *(double*)(&uvalue);
-                }
-            }
-        }
-#else // !UNSAFE_BYTEBUFFER
-        // Slower versions of Get* for when unsafe code is not allowed.
-        public short GetShort(int index)
-        {
-            return (short)ReadLittleEndian(index, sizeof(short));
-        }
-
-        public ushort GetUshort(int index)
-        {
-            return (ushort)ReadLittleEndian(index, sizeof(ushort));
-        }
-
-        public int GetInt(int index)
-        {
-            return (int)ReadLittleEndian(index, sizeof(int));
-        }
-
-        public uint GetUint(int index)
-        {
-            return (uint)ReadLittleEndian(index, sizeof(uint));
-        }
-
-        public long GetLong(int index)
-        {
-            return (long)ReadLittleEndian(index, sizeof(long));
-        }
-
-        public ulong GetUlong(int index)
-        {
-            return ReadLittleEndian(index, sizeof(ulong));
-        }
-
-        public float GetFloat(int index)
-        {
-            // TODO(derekbailey): use BitConvert.Int32BitsToSingle() whenever flatbuffers upgrades to a .NET version
-            // that contains it.
-            ConversionUnion union;
-            union.floatValue = 0;
-            union.intValue = (int)ReadLittleEndian(index, sizeof(float));
-            return union.floatValue;
-        }
-
-        public double GetDouble(int index)
-        {
-            return BitConverter.Int64BitsToDouble((long)ReadLittleEndian(index, sizeof(double)));
-        }
-#endif // UNSAFE_BYTEBUFFER
-
-        /// <summary>
-        /// Copies an array of type T into this buffer, ending at the given
-        /// offset into this buffer. The starting offset is calculated based on the length
-        /// of the array and is the value returned.
-        /// </summary>
-        /// <typeparam name="T">The type of the input data (must be a struct)</typeparam>
-        /// <param name="offset">The offset into this buffer where the copy will end</param>
-        /// <param name="x">The array to copy data from</param>
-        /// <returns>The 'start' location of this buffer now, after the copy completed</returns>
-        public int Put<T>(int offset, T[] x)
-            where T : struct
-        {
-            if (x == null)
-            {
-                throw new ArgumentNullException("Cannot put a null array");
-            }
-
-            return Put(offset, new ArraySegment<T>(x));
-        }
-
-        /// <summary>
-        /// Copies an array segment of type T into this buffer, ending at the 
-        /// given offset into this buffer. The starting offset is calculated 
-        /// based on the count of the array segment and is the value returned.
-        /// </summary>
-        /// <typeparam name="T">The type of the input data (must be a struct)
-        /// </typeparam>
-        /// <param name="offset">The offset into this buffer where the copy 
-        /// will end</param>
-        /// <param name="x">The array segment to copy data from</param>
-        /// <returns>The 'start' location of this buffer now, after the copy 
-        /// completed</returns>
-        public int Put<T>(int offset, ArraySegment<T> x)
-            where T : struct
-        {
-            if (x.Equals(default(ArraySegment<T>)))
-            {
-                throw new ArgumentNullException("Cannot put a uninitialized array segment");
-            }
-
-            if (x.Count == 0)
-            {
-                throw new ArgumentException("Cannot put an empty array");
-            }
-
-            if (!IsSupportedType<T>())
-            {
-                throw new ArgumentException("Cannot put an array of type "
-                    + typeof(T) + " into this buffer");
-            }
-
-            if (BitConverter.IsLittleEndian)
-            {
-                int numBytes = ByteBuffer.ArraySize(x);
-                offset -= numBytes;
-                AssertOffsetAndLength(offset, numBytes);
-                // if we are LE, just do a block copy
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-                MemoryMarshal.Cast<T, byte>(x).CopyTo(_buffer.Span.Slice(offset, numBytes));
-#else
-                var srcOffset = ByteBuffer.SizeOf<T>() * x.Offset;
-                Buffer.BlockCopy(x.Array, srcOffset, _buffer.Buffer, offset, numBytes);
-#endif
-            }
-            else
-            {
-                throw new NotImplementedException("Big Endian Support not implemented yet " +
-                    "for putting typed arrays");
-                // if we are BE, we have to swap each element by itself
-                //for(int i = x.Length - 1; i >= 0; i--)
-                //{
-                //  todo: low priority, but need to genericize the Put<T>() functions
-                //}
-            }
-            return offset;
-        }
-
-        /// <summary>
-        /// Copies an array segment of type T into this buffer, ending at the 
-        /// given offset into this buffer. The starting offset is calculated 
-        /// based on the count of the array segment and is the value returned.
-        /// </summary>
-        /// <typeparam name="T">The type of the input data (must be a struct)
-        /// </typeparam>
-        /// <param name="offset">The offset into this buffer where the copy 
-        /// will end</param>
-        /// <param name="ptr">The pointer to copy data from</param>
-        /// <param name="sizeInBytes">The number of bytes to copy</param>
-        /// <returns>The 'start' location of this buffer now, after the copy 
-        /// completed</returns>
-        public int Put<T>(int offset, IntPtr ptr, int sizeInBytes)
-            where T : struct
-        {
-            if (ptr == IntPtr.Zero)
-            {
-                throw new ArgumentNullException("Cannot add a null pointer");
-            }
-
-            if(sizeInBytes <= 0)
-            {
-                throw new ArgumentException("Cannot put an empty array");
-            }
-
-            if (!IsSupportedType<T>())
-            {
-                throw new ArgumentException("Cannot put an array of type "
-                    + typeof(T) + " into this buffer");
-            }
-
-            if (BitConverter.IsLittleEndian)
-            {
-                offset -= sizeInBytes;
-                AssertOffsetAndLength(offset, sizeInBytes);
-                // if we are LE, just do a block copy
-#if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER
-                unsafe
-                { 
-                    var span = new Span<byte>(ptr.ToPointer(), sizeInBytes);
-                    span.CopyTo(_buffer.Span.Slice(offset, sizeInBytes));
-                }
-#else
-                Marshal.Copy(ptr, _buffer.Buffer, offset, sizeInBytes);
-#endif
-            }
-            else
-            {
-                throw new NotImplementedException("Big Endian Support not implemented yet " +
-                    "for putting typed arrays");
-                // if we are BE, we have to swap each element by itself
-                //for(int i = x.Length - 1; i >= 0; i--)
-                //{
-                //  todo: low priority, but need to genericize the Put<T>() functions
-                //}
-            }
-            return offset;
-        }
-
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-        public int Put<T>(int offset, Span<T> x)
-            where T : struct
-        {
-            if (x.Length == 0)
-            {
-                throw new ArgumentException("Cannot put an empty array");
-            }
-
-            if (!IsSupportedType<T>())
-            {
-                throw new ArgumentException("Cannot put an array of type "
-                    + typeof(T) + " into this buffer");
-            }
-
-            if (BitConverter.IsLittleEndian)
-            {
-                int numBytes = ByteBuffer.ArraySize(x);
-                offset -= numBytes;
-                AssertOffsetAndLength(offset, numBytes);
-                // if we are LE, just do a block copy
-                MemoryMarshal.Cast<T, byte>(x).CopyTo(_buffer.Span.Slice(offset, numBytes));
-            }
-            else
-            {
-                throw new NotImplementedException("Big Endian Support not implemented yet " +
-                    "for putting typed arrays");
-                // if we are BE, we have to swap each element by itself
-                //for(int i = x.Length - 1; i >= 0; i--)
-                //{
-                //  todo: low priority, but need to genericize the Put<T>() functions
-                //}
-            }
-            return offset;
-        }
-#endif
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/ByteBufferUtil.cs b/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/ByteBufferUtil.cs
deleted file mode 100644
index 37c13d6..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/ByteBufferUtil.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2017 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-
-namespace Google.FlatBuffers
-{
-	/// <summary>
-	/// Class that collects utility functions around `ByteBuffer`.
-	/// </summary>
-	internal class ByteBufferUtil
-	{
-		// Extract the size prefix from a `ByteBuffer`.
-		public static int GetSizePrefix(ByteBuffer bb) {
-			return bb.GetInt(bb.Position);
-		}
-
-		// Create a duplicate of a size-prefixed `ByteBuffer` that has its position
-		// advanced just past the size prefix.
-		public static ByteBuffer RemoveSizePrefix(ByteBuffer bb) {
-			ByteBuffer s = bb.Duplicate();
-			s.Position += FlatBufferConstants.SizePrefixLength;
-			return s;
-		}
-	}
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/FlatBufferBuilder.cs b/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/FlatBufferBuilder.cs
deleted file mode 100644
index 422c940..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/FlatBufferBuilder.cs
+++ /dev/null
@@ -1,1023 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-/// @file
-/// @addtogroup flatbuffers_csharp_api
-/// @{
-
-namespace Google.FlatBuffers
-{
-    /// <summary>
-    /// Responsible for building up and accessing a FlatBuffer formatted byte
-    /// array (via ByteBuffer).
-    /// </summary>
-    internal class FlatBufferBuilder
-    {
-        private int _space;
-        private ByteBuffer _bb;
-        private int _minAlign = 1;
-
-        // The vtable for the current table (if _vtableSize >= 0)
-        private int[] _vtable = new int[16];
-        // The size of the vtable. -1 indicates no vtable
-        private int _vtableSize = -1;
-        // Starting offset of the current struct/table.
-        private int _objectStart;
-        // List of offsets of all vtables.
-        private int[] _vtables = new int[16];
-        // Number of entries in `vtables` in use.
-        private int _numVtables = 0;
-        // For the current vector being built.
-        private int _vectorNumElems = 0;
-
-        // For CreateSharedString
-        private Dictionary<string, StringOffset> _sharedStringMap = null;
-
-        /// <summary>
-        /// Create a FlatBufferBuilder with a given initial size.
-        /// </summary>
-        /// <param name="initialSize">
-        /// The initial size to use for the internal buffer.
-        /// </param>
-        public FlatBufferBuilder(int initialSize)
-        {
-            if (initialSize <= 0)
-                throw new ArgumentOutOfRangeException("initialSize",
-                    initialSize, "Must be greater than zero");
-            _space = initialSize;
-            _bb = new ByteBuffer(initialSize);
-        }
-
-        /// <summary>
-        /// Create a FlatBufferBuilder backed by the passed in ByteBuffer
-        /// </summary>
-        /// <param name="buffer">The ByteBuffer to write to</param>
-        public FlatBufferBuilder(ByteBuffer buffer)
-        {
-            _bb = buffer;
-            _space = buffer.Length;
-            buffer.Reset();
-        }
-
-        /// <summary>
-        /// Reset the FlatBufferBuilder by purging all data that it holds.
-        /// </summary>
-        public void Clear()
-        {
-            _space = _bb.Length;
-            _bb.Reset();
-            _minAlign = 1;
-            while (_vtableSize > 0) _vtable[--_vtableSize] = 0;
-            _vtableSize = -1;
-            _objectStart = 0;
-            _numVtables = 0;
-            _vectorNumElems = 0;
-            if (_sharedStringMap != null)
-            {
-                _sharedStringMap.Clear();
-            }
-        }
-
-        /// <summary>
-        /// Gets and sets a Boolean to disable the optimization when serializing
-        /// default values to a Table.
-        ///
-        /// In order to save space, fields that are set to their default value
-        /// don't get serialized into the buffer.
-        /// </summary>
-        public bool ForceDefaults { get; set; }
-
-        /// @cond FLATBUFFERS_INTERNAL
-
-        public int Offset { get { return _bb.Length - _space; } }
-
-        public void Pad(int size)
-        {
-             _bb.PutByte(_space -= size, 0, size);
-        }
-
-        // Doubles the size of the ByteBuffer, and copies the old data towards
-        // the end of the new buffer (since we build the buffer backwards).
-        void GrowBuffer()
-        {
-            _bb.GrowFront(_bb.Length << 1);
-        }
-
-        // Prepare to write an element of `size` after `additional_bytes`
-        // have been written, e.g. if you write a string, you need to align
-        // such the int length field is aligned to SIZEOF_INT, and the string
-        // data follows it directly.
-        // If all you need to do is align, `additional_bytes` will be 0.
-        public void Prep(int size, int additionalBytes)
-        {
-            // Track the biggest thing we've ever aligned to.
-            if (size > _minAlign)
-                _minAlign = size;
-            // Find the amount of alignment needed such that `size` is properly
-            // aligned after `additional_bytes`
-            var alignSize =
-                ((~((int)_bb.Length - _space + additionalBytes)) + 1) &
-                (size - 1);
-            // Reallocate the buffer if needed.
-            while (_space < alignSize + size + additionalBytes)
-            {
-                var oldBufSize = (int)_bb.Length;
-                GrowBuffer();
-                _space += (int)_bb.Length - oldBufSize;
-
-            }
-            if (alignSize > 0)
-                Pad(alignSize);
-        }
-
-        public void PutBool(bool x)
-        {
-          _bb.PutByte(_space -= sizeof(byte), (byte)(x ? 1 : 0));
-        }
-
-        public void PutSbyte(sbyte x)
-        {
-          _bb.PutSbyte(_space -= sizeof(sbyte), x);
-        }
-
-        public void PutByte(byte x)
-        {
-            _bb.PutByte(_space -= sizeof(byte), x);
-        }
-
-        public void PutShort(short x)
-        {
-            _bb.PutShort(_space -= sizeof(short), x);
-        }
-
-        public void PutUshort(ushort x)
-        {
-          _bb.PutUshort(_space -= sizeof(ushort), x);
-        }
-
-        public void PutInt(int x)
-        {
-            _bb.PutInt(_space -= sizeof(int), x);
-        }
-
-        public void PutUint(uint x)
-        {
-          _bb.PutUint(_space -= sizeof(uint), x);
-        }
-
-        public void PutLong(long x)
-        {
-            _bb.PutLong(_space -= sizeof(long), x);
-        }
-
-        public void PutUlong(ulong x)
-        {
-          _bb.PutUlong(_space -= sizeof(ulong), x);
-        }
-
-        public void PutFloat(float x)
-        {
-            _bb.PutFloat(_space -= sizeof(float), x);
-        }
-
-        /// <summary>
-        /// Puts an array of type T into this builder at the
-        /// current offset
-        /// </summary>
-        /// <typeparam name="T">The type of the input data </typeparam>
-        /// <param name="x">The array to copy data from</param>
-        public void Put<T>(T[] x)
-            where T : struct
-        {
-            _space = _bb.Put(_space, x);
-        }
-
-        /// <summary>
-        /// Puts an array of type T into this builder at the
-        /// current offset
-        /// </summary>
-        /// <typeparam name="T">The type of the input data </typeparam>
-        /// <param name="x">The array segment to copy data from</param>
-        public void Put<T>(ArraySegment<T> x)
-            where T : struct
-        {
-            _space = _bb.Put(_space, x);
-        }
-
-        /// <summary>
-        /// Puts data of type T into this builder at the
-        /// current offset
-        /// </summary>
-        /// <typeparam name="T">The type of the input data </typeparam>
-        /// <param name="ptr">The pointer to copy data from</param>
-        /// <param name="sizeInBytes">The length of the data in bytes</param>
-        public void Put<T>(IntPtr ptr, int sizeInBytes)
-            where T : struct
-        {
-            _space = _bb.Put<T>(_space, ptr, sizeInBytes);
-        }
-
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-        /// <summary>
-        /// Puts a span of type T into this builder at the
-        /// current offset
-        /// </summary>
-        /// <typeparam name="T">The type of the input data </typeparam>
-        /// <param name="x">The span to copy data from</param>
-        public void Put<T>(Span<T> x)
-            where T : struct
-        {
-            _space = _bb.Put(_space, x);
-        }
-#endif
-
-        public void PutDouble(double x)
-        {
-            _bb.PutDouble(_space -= sizeof(double), x);
-        }
-        /// @endcond
-
-        /// <summary>
-        /// Add a `bool` to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <param name="x">The `bool` to add to the buffer.</param>
-        public void AddBool(bool x) { Prep(sizeof(byte), 0); PutBool(x); }
-
-        /// <summary>
-        /// Add a `sbyte` to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <param name="x">The `sbyte` to add to the buffer.</param>
-        public void AddSbyte(sbyte x) { Prep(sizeof(sbyte), 0); PutSbyte(x); }
-
-        /// <summary>
-        /// Add a `byte` to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <param name="x">The `byte` to add to the buffer.</param>
-        public void AddByte(byte x) { Prep(sizeof(byte), 0); PutByte(x); }
-
-        /// <summary>
-        /// Add a `short` to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <param name="x">The `short` to add to the buffer.</param>
-        public void AddShort(short x) { Prep(sizeof(short), 0); PutShort(x); }
-
-        /// <summary>
-        /// Add an `ushort` to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <param name="x">The `ushort` to add to the buffer.</param>
-        public void AddUshort(ushort x) { Prep(sizeof(ushort), 0); PutUshort(x); }
-
-        /// <summary>
-        /// Add an `int` to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <param name="x">The `int` to add to the buffer.</param>
-        public void AddInt(int x) { Prep(sizeof(int), 0); PutInt(x); }
-
-        /// <summary>
-        /// Add an `uint` to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <param name="x">The `uint` to add to the buffer.</param>
-        public void AddUint(uint x) { Prep(sizeof(uint), 0); PutUint(x); }
-
-        /// <summary>
-        /// Add a `long` to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <param name="x">The `long` to add to the buffer.</param>
-        public void AddLong(long x) { Prep(sizeof(long), 0); PutLong(x); }
-
-        /// <summary>
-        /// Add an `ulong` to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <param name="x">The `ulong` to add to the buffer.</param>
-        public void AddUlong(ulong x) { Prep(sizeof(ulong), 0); PutUlong(x); }
-
-        /// <summary>
-        /// Add a `float` to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <param name="x">The `float` to add to the buffer.</param>
-        public void AddFloat(float x) { Prep(sizeof(float), 0); PutFloat(x); }
-
-        /// <summary>
-        /// Add an array of type T to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <typeparam name="T">The type of the input data</typeparam>
-        /// <param name="x">The array to copy data from</param>
-        public void Add<T>(T[] x)
-            where T : struct
-        {
-            Add(new ArraySegment<T>(x));
-        }
-
-        /// <summary>
-        /// Add an array of type T to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <typeparam name="T">The type of the input data</typeparam>
-        /// <param name="x">The array segment to copy data from</param>
-        public void Add<T>(ArraySegment<T> x)
-            where T : struct
-        {
-            if (x == null)
-            {
-                throw new ArgumentNullException("Cannot add a null array");
-            }
-
-            if( x.Count == 0)
-            {
-                // don't do anything if the array is empty
-                return;
-            }
-
-            if(!ByteBuffer.IsSupportedType<T>())
-            {
-                throw new ArgumentException("Cannot add this Type array to the builder");
-            }
-
-            int size = ByteBuffer.SizeOf<T>();
-            // Need to prep on size (for data alignment) and then we pass the
-            // rest of the length (minus 1) as additional bytes
-            Prep(size, size * (x.Count - 1));
-            Put(x);
-        }
-
-        /// <summary>
-        /// Adds the data of type T pointed to by the given pointer to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <typeparam name="T">The type of the input data</typeparam>
-        /// <param name="ptr">The pointer to copy data from</param>
-        /// <param name="sizeInBytes">The data size in bytes</param>
-        public void Add<T>(IntPtr ptr, int sizeInBytes)
-            where T : struct
-        {
-            if(sizeInBytes == 0)
-            {
-                // don't do anything if the array is empty
-                return;
-            }
-
-            if (ptr == IntPtr.Zero)
-            {
-                throw new ArgumentNullException("Cannot add a null pointer");
-            }
-
-            if(sizeInBytes < 0)
-            {
-                throw new ArgumentOutOfRangeException("sizeInBytes", "sizeInBytes cannot be negative");
-            }
-
-            if(!ByteBuffer.IsSupportedType<T>())
-            {
-                throw new ArgumentException("Cannot add this Type array to the builder");
-            }
-
-            int size = ByteBuffer.SizeOf<T>();
-            if((sizeInBytes % size) != 0)
-            {
-                throw new ArgumentException("The given size in bytes " + sizeInBytes + " doesn't match the element size of T ( " + size + ")", "sizeInBytes");
-            }
-
-            // Need to prep on size (for data alignment) and then we pass the
-            // rest of the length (minus 1) as additional bytes
-            Prep(size, sizeInBytes - size);
-            Put<T>(ptr, sizeInBytes);
-        }
-
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-        /// <summary>
-        /// Add a span of type T to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <typeparam name="T">The type of the input data</typeparam>
-        /// <param name="x">The span to copy data from</param>
-        public void Add<T>(Span<T> x)
-            where T : struct
-        {
-            if (!ByteBuffer.IsSupportedType<T>())
-            {
-                throw new ArgumentException("Cannot add this Type array to the builder");
-            }
-
-            int size = ByteBuffer.SizeOf<T>();
-            // Need to prep on size (for data alignment) and then we pass the
-            // rest of the length (minus 1) as additional bytes
-            Prep(size, size * (x.Length - 1));
-            Put(x);
-        }
-#endif
-
-        /// <summary>
-        /// Add a `double` to the buffer (aligns the data and grows if necessary).
-        /// </summary>
-        /// <param name="x">The `double` to add to the buffer.</param>
-        public void AddDouble(double x) { Prep(sizeof(double), 0);
-                                          PutDouble(x); }
-
-        /// <summary>
-        /// Adds an offset, relative to where it will be written.
-        /// </summary>
-        /// <param name="off">The offset to add to the buffer.</param>
-        public void AddOffset(int off)
-        {
-            Prep(sizeof(int), 0);  // Ensure alignment is already done.
-            if (off > Offset)
-                throw new ArgumentException();
-
-            if (off != 0)
-                off = Offset - off + sizeof(int);
-            PutInt(off);
-        }
-
-        /// @cond FLATBUFFERS_INTERNAL
-        public void StartVector(int elemSize, int count, int alignment)
-        {
-            NotNested();
-            _vectorNumElems = count;
-            Prep(sizeof(int), elemSize * count);
-            Prep(alignment, elemSize * count); // Just in case alignment > int.
-        }
-        /// @endcond
-
-        /// <summary>
-        /// Writes data necessary to finish a vector construction.
-        /// </summary>
-        public VectorOffset EndVector()
-        {
-            PutInt(_vectorNumElems);
-            return new VectorOffset(Offset);
-        }
-
-        /// <summary>
-        /// Creates a vector of tables.
-        /// </summary>
-        /// <param name="offsets">Offsets of the tables.</param>
-        public VectorOffset CreateVectorOfTables<T>(Offset<T>[] offsets) where T : struct
-        {
-            NotNested();
-            StartVector(sizeof(int), offsets.Length, sizeof(int));
-            for (int i = offsets.Length - 1; i >= 0; i--) AddOffset(offsets[i].Value);
-            return EndVector();
-        }
-
-        /// @cond FLATBUFFERS_INTERNAL
-        public void Nested(int obj)
-        {
-            // Structs are always stored inline, so need to be created right
-            // where they are used. You'll get this assert if you created it
-            // elsewhere.
-            if (obj != Offset)
-                throw new Exception(
-                    "FlatBuffers: struct must be serialized inline.");
-        }
-
-        public void NotNested()
-        {
-            // You should not be creating any other objects or strings/vectors
-            // while an object is being constructed
-            if (_vtableSize >= 0)
-                throw new Exception(
-                    "FlatBuffers: object serialization must not be nested.");
-        }
-
-        public void StartTable(int numfields)
-        {
-            if (numfields < 0)
-                throw new ArgumentOutOfRangeException("Flatbuffers: invalid numfields");
-
-            NotNested();
-
-            if (_vtable.Length < numfields)
-                _vtable = new int[numfields];
-
-            _vtableSize = numfields;
-            _objectStart = Offset;
-        }
-
-
-        // Set the current vtable at `voffset` to the current location in the
-        // buffer.
-        public void Slot(int voffset)
-        {
-            if (voffset >= _vtableSize)
-                throw new IndexOutOfRangeException("Flatbuffers: invalid voffset");
-
-            _vtable[voffset] = Offset;
-        }
-
-        /// <summary>
-        /// Adds a Boolean to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddBool(int o, bool x, bool d) { if (ForceDefaults || x != d) { AddBool(x); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Boolean to the Table at index `o` in its vtable using the nullable value `x`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The nullable boolean value to put into the buffer. If it doesn't have a value
-        /// it will skip writing to the buffer.</param>       
-        public void AddBool(int o, bool? x) { if (x.HasValue) { AddBool(x.Value); Slot(o); } }
-
-        
-        /// <summary>
-        /// Adds a SByte to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddSbyte(int o, sbyte x, sbyte d) { if (ForceDefaults || x != d) { AddSbyte(x); Slot(o); } }
-
-        /// <summary>
-        /// Adds a SByte to the Table at index `o` in its vtable using the nullable value `x`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The nullable sbyte value to put into the buffer. If it doesn't have a value
-        /// it will skip writing to the buffer.</param>  
-        public void AddSbyte(int o, sbyte? x) { if (x.HasValue) { AddSbyte(x.Value); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Byte to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddByte(int o, byte x, byte d) { if (ForceDefaults || x != d) { AddByte(x); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Byte to the Table at index `o` in its vtable using the nullable value `x`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The nullable byte value to put into the buffer. If it doesn't have a value
-        /// it will skip writing to the buffer.</param>  
-        public void AddByte(int o, byte? x) { if (x.HasValue) { AddByte(x.Value); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Int16 to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddShort(int o, short x, int d) { if (ForceDefaults || x != d) { AddShort(x); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Int16 to the Table at index `o` in its vtable using the nullable value `x`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The nullable int16 value to put into the buffer. If it doesn't have a value
-        /// it will skip writing to the buffer.</param>  
-        public void AddShort(int o, short? x) { if (x.HasValue) { AddShort(x.Value); Slot(o); } }
-
-        /// <summary>
-        /// Adds a UInt16 to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddUshort(int o, ushort x, ushort d) { if (ForceDefaults || x != d) { AddUshort(x); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Uint16 to the Table at index `o` in its vtable using the nullable value `x`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The nullable uint16 value to put into the buffer. If it doesn't have a value
-        /// it will skip writing to the buffer.</param>  
-        public void AddUshort(int o, ushort? x) { if (x.HasValue) { AddUshort(x.Value); Slot(o); } }
-
-        /// <summary>
-        /// Adds an Int32 to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddInt(int o, int x, int d) { if (ForceDefaults || x != d) { AddInt(x); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Int32 to the Table at index `o` in its vtable using the nullable value `x`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The nullable int32 value to put into the buffer. If it doesn't have a value
-        /// it will skip writing to the buffer.</param>  
-        public void AddInt(int o, int? x) { if (x.HasValue) { AddInt(x.Value); Slot(o); } }
-
-        /// <summary>
-        /// Adds a UInt32 to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddUint(int o, uint x, uint d) { if (ForceDefaults || x != d) { AddUint(x); Slot(o); } }
-
-        /// <summary>
-        /// Adds a UInt32 to the Table at index `o` in its vtable using the nullable value `x`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The nullable uint32 value to put into the buffer. If it doesn't have a value
-        /// it will skip writing to the buffer.</param>  
-        public void AddUint(int o, uint? x) { if (x.HasValue) { AddUint(x.Value); Slot(o); } }
-
-        /// <summary>
-        /// Adds an Int64 to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddLong(int o, long x, long d) { if (ForceDefaults || x != d) { AddLong(x); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Int64 to the Table at index `o` in its vtable using the nullable value `x`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The nullable int64 value to put into the buffer. If it doesn't have a value
-        /// it will skip writing to the buffer.</param>  
-        public void AddLong(int o, long? x) { if (x.HasValue) { AddLong(x.Value); Slot(o); } }
-
-        /// <summary>
-        /// Adds a UInt64 to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddUlong(int o, ulong x, ulong d) { if (ForceDefaults || x != d) { AddUlong(x); Slot(o); } }
-
-        /// <summary>
-        /// Adds a UInt64 to the Table at index `o` in its vtable using the nullable value `x`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The nullable int64 value to put into the buffer. If it doesn't have a value
-        /// it will skip writing to the buffer.</param>  
-        public void AddUlong(int o, ulong? x) { if (x.HasValue) { AddUlong(x.Value); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Single to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddFloat(int o, float x, double d) { if (ForceDefaults || x != d) { AddFloat(x); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Single to the Table at index `o` in its vtable using the nullable value `x`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The nullable single value to put into the buffer. If it doesn't have a value
-        /// it will skip writing to the buffer.</param>  
-        public void AddFloat(int o, float? x) { if (x.HasValue) { AddFloat(x.Value); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Double to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddDouble(int o, double x, double d) { if (ForceDefaults || x != d) { AddDouble(x); Slot(o); } }
-
-        /// <summary>
-        /// Adds a Double to the Table at index `o` in its vtable using the nullable value `x`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The nullable double value to put into the buffer. If it doesn't have a value
-        /// it will skip writing to the buffer.</param>  
-        public void AddDouble(int o, double? x) { if (x.HasValue) { AddDouble(x.Value); Slot(o); } }
-
-        /// <summary>
-        /// Adds a buffer offset to the Table at index `o` in its vtable using the value `x` and default `d`
-        /// </summary>
-        /// <param name="o">The index into the vtable</param>
-        /// <param name="x">The value to put into the buffer. If the value is equal to the default
-        /// the value will be skipped.</param>
-        /// <param name="d">The default value to compare the value against</param>
-        public void AddOffset(int o, int x, int d) { if (x != d) { AddOffset(x); Slot(o); } }
-        /// @endcond
-
-        /// <summary>
-        /// Encode the string `s` in the buffer using UTF-8.
-        /// </summary>
-        /// <param name="s">The string to encode.</param>
-        /// <returns>
-        /// The offset in the buffer where the encoded string starts.
-        /// </returns>
-        public StringOffset CreateString(string s)
-        {
-            if (s == null)
-            {
-                return new StringOffset(0);
-            }
-            NotNested();
-            AddByte(0);
-            var utf8StringLen = Encoding.UTF8.GetByteCount(s);
-            StartVector(1, utf8StringLen, 1);
-            _bb.PutStringUTF8(_space -= utf8StringLen, s);
-            return new StringOffset(EndVector().Value);
-        }
-
-
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-        /// <summary>
-        /// Creates a string in the buffer from a Span containing
-        /// a UTF8 string.
-        /// </summary>
-        /// <param name="chars">the UTF8 string to add to the buffer</param>
-        /// <returns>
-        /// The offset in the buffer where the encoded string starts.
-        /// </returns>
-        public StringOffset CreateUTF8String(Span<byte> chars)
-        {
-            NotNested();
-            AddByte(0);
-            var utf8StringLen = chars.Length;
-            StartVector(1, utf8StringLen, 1);
-            _space = _bb.Put(_space, chars);
-            return new StringOffset(EndVector().Value);
-        }
-#endif
-
-        /// <summary>
-        /// Store a string in the buffer, which can contain any binary data.
-        /// If a string with this exact contents has already been serialized before,
-        /// instead simply returns the offset of the existing string.
-        /// </summary>
-        /// <param name="s">The string to encode.</param>
-        /// <returns>
-        /// The offset in the buffer where the encoded string starts.
-        /// </returns>
-        public StringOffset CreateSharedString(string s)
-        {
-            if (s == null)
-            {
-              return new StringOffset(0);
-            }
-
-            if (_sharedStringMap == null)
-            {
-                _sharedStringMap = new Dictionary<string, StringOffset>();
-            }
-
-            if (_sharedStringMap.ContainsKey(s))
-            {
-                return _sharedStringMap[s];
-            }
-
-            var stringOffset = CreateString(s);
-            _sharedStringMap.Add(s, stringOffset);
-            return stringOffset;
-        }
-
-        /// @cond FLATBUFFERS_INTERNAL
-        // Structs are stored inline, so nothing additional is being added.
-        // `d` is always 0.
-        public void AddStruct(int voffset, int x, int d)
-        {
-            if (x != d)
-            {
-                Nested(x);
-                Slot(voffset);
-            }
-        }
-
-        public int EndTable()
-        {
-            if (_vtableSize < 0)
-                throw new InvalidOperationException(
-                  "Flatbuffers: calling EndTable without a StartTable");
-
-            AddInt((int)0);
-            var vtableloc = Offset;
-            // Write out the current vtable.
-            int i = _vtableSize - 1;
-            // Trim trailing zeroes.
-            for (; i >= 0 && _vtable[i] == 0; i--) {}
-            int trimmedSize = i + 1;
-            for (; i >= 0 ; i--) {
-                // Offset relative to the start of the table.
-                short off = (short)(_vtable[i] != 0
-                                        ? vtableloc - _vtable[i]
-                                        : 0);
-                AddShort(off);
-
-                // clear out written entry
-                _vtable[i] = 0;
-            }
-
-            const int standardFields = 2; // The fields below:
-            AddShort((short)(vtableloc - _objectStart));
-            AddShort((short)((trimmedSize + standardFields) *
-                             sizeof(short)));
-
-            // Search for an existing vtable that matches the current one.
-            int existingVtable = 0;
-            for (i = 0; i < _numVtables; i++) {
-                int vt1 = _bb.Length - _vtables[i];
-                int vt2 = _space;
-                short len = _bb.GetShort(vt1);
-                if (len == _bb.GetShort(vt2)) {
-                    for (int j = sizeof(short); j < len; j += sizeof(short)) {
-                        if (_bb.GetShort(vt1 + j) != _bb.GetShort(vt2 + j)) {
-                            goto endLoop;
-                        }
-                    }
-                    existingVtable = _vtables[i];
-                    break;
-                }
-
-                endLoop: { }
-            }
-
-            if (existingVtable != 0) {
-                // Found a match:
-                // Remove the current vtable.
-                _space = _bb.Length - vtableloc;
-                // Point table to existing vtable.
-                _bb.PutInt(_space, existingVtable - vtableloc);
-            } else {
-                // No match:
-                // Add the location of the current vtable to the list of
-                // vtables.
-                if (_numVtables == _vtables.Length)
-                {
-                    // Arrays.CopyOf(vtables num_vtables * 2);
-                    var newvtables = new int[ _numVtables * 2];
-                    Array.Copy(_vtables, newvtables, _vtables.Length);
-
-                    _vtables = newvtables;
-                };
-                _vtables[_numVtables++] = Offset;
-                // Point table to current vtable.
-                _bb.PutInt(_bb.Length - vtableloc, Offset - vtableloc);
-            }
-
-            _vtableSize = -1;
-            return vtableloc;
-        }
-
-        // This checks a required field has been set in a given table that has
-        // just been constructed.
-        public void Required(int table, int field)
-        {
-          int table_start = _bb.Length - table;
-          int vtable_start = table_start - _bb.GetInt(table_start);
-          bool ok = _bb.GetShort(vtable_start + field) != 0;
-          // If this fails, the caller will show what field needs to be set.
-          if (!ok)
-            throw new InvalidOperationException("FlatBuffers: field " + field +
-                                                " must be set");
-        }
-        /// @endcond
-
-        /// <summary>
-        /// Finalize a buffer, pointing to the given `root_table`.
-        /// </summary>
-        /// <param name="rootTable">
-        /// An offset to be added to the buffer.
-        /// </param>
-        /// <param name="sizePrefix">
-        /// Whether to prefix the size to the buffer.
-        /// </param>
-        protected void Finish(int rootTable, bool sizePrefix)
-        {
-            Prep(_minAlign, sizeof(int) + (sizePrefix ? sizeof(int) : 0));
-            AddOffset(rootTable);
-            if (sizePrefix) {
-                AddInt(_bb.Length - _space);
-            }
-            _bb.Position = _space;
-        }
-
-        /// <summary>
-        /// Finalize a buffer, pointing to the given `root_table`.
-        /// </summary>
-        /// <param name="rootTable">
-        /// An offset to be added to the buffer.
-        /// </param>
-        public void Finish(int rootTable)
-        {
-            Finish(rootTable, false);
-        }
-
-        /// <summary>
-        /// Finalize a buffer, pointing to the given `root_table`, with the size prefixed.
-        /// </summary>
-        /// <param name="rootTable">
-        /// An offset to be added to the buffer.
-        /// </param>
-        public void FinishSizePrefixed(int rootTable)
-        {
-            Finish(rootTable, true);
-        }
-
-        /// <summary>
-        /// Get the ByteBuffer representing the FlatBuffer.
-        /// </summary>
-        /// <remarks>
-        /// This is typically only called after you call `Finish()`.
-        /// The actual data starts at the ByteBuffer's current position,
-        /// not necessarily at `0`.
-        /// </remarks>
-        /// <returns>
-        /// Returns the ByteBuffer for this FlatBuffer.
-        /// </returns>
-        public ByteBuffer DataBuffer { get { return _bb; } }
-
-        /// <summary>
-        /// A utility function to copy and return the ByteBuffer data as a
-        /// `byte[]`.
-        /// </summary>
-        /// <returns>
-        /// A full copy of the FlatBuffer data.
-        /// </returns>
-        public byte[] SizedByteArray()
-        {
-            return _bb.ToSizedArray();
-        }
-
-        /// <summary>
-        /// Finalize a buffer, pointing to the given `rootTable`.
-        /// </summary>
-        /// <param name="rootTable">
-        /// An offset to be added to the buffer.
-        /// </param>
-        /// <param name="fileIdentifier">
-        /// A FlatBuffer file identifier to be added to the buffer before
-        /// `root_table`.
-        /// </param>
-        /// <param name="sizePrefix">
-        /// Whether to prefix the size to the buffer.
-        /// </param>
-        protected void Finish(int rootTable, string fileIdentifier, bool sizePrefix)
-        {
-            Prep(_minAlign, sizeof(int) + (sizePrefix ? sizeof(int) : 0) +
-                            FlatBufferConstants.FileIdentifierLength);
-            if (fileIdentifier.Length !=
-                FlatBufferConstants.FileIdentifierLength)
-                throw new ArgumentException(
-                    "FlatBuffers: file identifier must be length " +
-                    FlatBufferConstants.FileIdentifierLength,
-                    "fileIdentifier");
-            for (int i = FlatBufferConstants.FileIdentifierLength - 1; i >= 0;
-                 i--)
-            {
-               AddByte((byte)fileIdentifier[i]);
-            }
-            Finish(rootTable, sizePrefix);
-        }
-
-        /// <summary>
-        /// Finalize a buffer, pointing to the given `rootTable`.
-        /// </summary>
-        /// <param name="rootTable">
-        /// An offset to be added to the buffer.
-        /// </param>
-        /// <param name="fileIdentifier">
-        /// A FlatBuffer file identifier to be added to the buffer before
-        /// `root_table`.
-        /// </param>
-        public void Finish(int rootTable, string fileIdentifier)
-        {
-            Finish(rootTable, fileIdentifier, false);
-        }
-
-        /// <summary>
-        /// Finalize a buffer, pointing to the given `rootTable`, with the size prefixed.
-        /// </summary>
-        /// <param name="rootTable">
-        /// An offset to be added to the buffer.
-        /// </param>
-        /// <param name="fileIdentifier">
-        /// A FlatBuffer file identifier to be added to the buffer before
-        /// `root_table`.
-        /// </param>
-        public void FinishSizePrefixed(int rootTable, string fileIdentifier)
-        {
-            Finish(rootTable, fileIdentifier, true);
-        }
-    }
-}
-
-/// @}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/FlatBufferConstants.cs b/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/FlatBufferConstants.cs
deleted file mode 100644
index c26f1b6..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/FlatBufferConstants.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Google.FlatBuffers
-{
-    internal static class FlatBufferConstants
-    {
-        public const int FileIdentifierLength = 4;
-        public const int SizePrefixLength = 4;
-        /** A version identifier to force a compile error if someone
-        accidentally tries to build generated code with a runtime of
-        two mismatched version. Versions need to always match, as
-        the runtime and generated code are modified in sync.
-        Changes to the C# implementation need to be sure to change
-        the version here and in the code generator on every possible
-        incompatible change */
-        public static void FLATBUFFERS_23_5_9() {}
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/FlatBufferVerify.cs b/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/FlatBufferVerify.cs
deleted file mode 100644
index 418d38e..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/FlatBufferVerify.cs
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-using System;
-using System.Reflection;using System.Collections.Generic;
-using System.IO;
-
-namespace Google.FlatBuffers
-{
-
-  /// <summary>
-  /// The Class of the Verifier Options
-  /// </summary>
-  internal class Options
-  {
-    public const int DEFAULT_MAX_DEPTH = 64;
-    public const int DEFAULT_MAX_TABLES = 1000000;
-
-    private int max_depth = 0;
-    private int max_tables = 0;
-    private bool string_end_check = false;
-    private bool alignment_check = false;
-
-    public Options()
-    {
-      max_depth = DEFAULT_MAX_DEPTH;
-      max_tables = DEFAULT_MAX_TABLES;
-      string_end_check = true;
-      alignment_check = true;
-    }
-
-    public Options(int maxDepth, int maxTables, bool stringEndCheck, bool alignmentCheck)
-    {
-      max_depth = maxDepth;
-      max_tables = maxTables;
-      string_end_check = stringEndCheck;
-      alignment_check = alignmentCheck;
-    }
-    /// <summary> Maximum depth of nested tables allowed in a valid flatbuffer. </summary>
-    public int maxDepth
-    {
-      get { return max_depth; }
-      set { max_depth = value; }
-    }
-    /// <summary> Maximum number of tables allowed in a valid flatbuffer. </summary>
-    public int maxTables
-    {
-      get { return max_tables; }
-      set { max_tables = value; }
-    }
-    /// <summary> Check that string contains its null terminator </summary>
-    public bool stringEndCheck
-    {
-      get { return string_end_check; }
-      set { string_end_check = value; }
-    }
-    /// <summary> Check alignment of elements </summary>
-    public bool alignmentCheck
-    {
-      get { return alignment_check; }
-      set { alignment_check = value; }
-    }
-  }
-
-  internal struct checkElementStruct
-  {
-    public bool elementValid;
-    public uint elementOffset;
-  }
-
-  internal delegate bool VerifyTableAction(Verifier verifier, uint tablePos);
-  internal delegate bool VerifyUnionAction(Verifier verifier, byte typeId, uint tablePos);
-
-  /// <summary>
-  /// The Main Class of the FlatBuffer Verifier
-  /// </summary>
-  internal class Verifier
-  {
-    private ByteBuffer verifier_buffer = null;
-    private Options verifier_options = null;
-    private int depth_cnt = 0;
-    private int num_tables_cnt = 0;
-
-    public const int SIZE_BYTE = 1;
-    public const int SIZE_INT = 4;
-    public const int SIZE_U_OFFSET = 4;
-    public const int SIZE_S_OFFSET = 4;
-    public const int SIZE_V_OFFSET = 2;
-    public const int SIZE_PREFIX_LENGTH = FlatBufferConstants.SizePrefixLength;         // default size = 4
-    public const int FLATBUFFERS_MAX_BUFFER_SIZE = System.Int32.MaxValue;               // default size = 2147483647
-    public const int FILE_IDENTIFIER_LENGTH = FlatBufferConstants.FileIdentifierLength; // default size = 4
-
-    /// <summary> The Base Constructor of the Verifier object </summary>
-    public Verifier()
-    {
-      // Verifier buffer
-      verifier_buffer = null;
-      // Verifier settings 
-      verifier_options = null;
-      // Depth counter
-      depth_cnt = 0;
-      // Tables counter
-      num_tables_cnt = 0;
-    }
-
-    /// <summary> The Constructor of the Verifier object with input parameters: ByteBuffer and/or Options </summary>
-    /// <param name="buf"> Input flat byte buffer defined as ByteBuffer type</param>
-    /// <param name="options"> Options object with settings for the configuration the Verifier </param>
-    public Verifier(ByteBuffer buf, Options options = null)
-    {
-      verifier_buffer = buf;
-      verifier_options = options ?? new Options();
-      depth_cnt = 0;
-      num_tables_cnt = 0;
-    }
-
-    /// <summary> Bytes Buffer for Verify</summary>
-    public ByteBuffer Buf
-    {
-      get { return verifier_buffer; }
-      set { verifier_buffer = value; }
-    }
-    /// <summary> Options of the Verifier </summary>
-    public Options options
-    {
-      get { return verifier_options; }
-      set { verifier_options = value; }
-    }
-    /// <summary> Counter of tables depth in a tested flatbuffer  </summary>
-    public int depth
-    {
-      get { return depth_cnt; }
-      set { depth_cnt = value; }
-    }
-    /// <summary> Counter of tables in a tested flatbuffer </summary>
-    public int numTables
-    {
-      get { return num_tables_cnt; }
-      set { num_tables_cnt = value; }
-    }
-
-
-    /// <summary> Method set maximum tables depth of valid structure</summary>
-    /// <param name="value"> Specify Value of the maximum depth of the structure</param>
-    public Verifier SetMaxDepth(int value)
-    {
-      verifier_options.maxDepth = value;
-      return this;
-    }
-    /// <summary> Specify maximum number of tables in structure </summary>
-    /// <param name="value"> Specify Value of the maximum number of the tables in the structure</param>
-    public Verifier SetMaxTables(int value)
-    {
-      verifier_options.maxTables = value;
-      return this;
-    }
-    /// <summary> Enable/disable buffer content alignment check </summary>
-    /// <param name="value"> Value of the State for buffer content alignment check (Enable = true) </param>
-    public Verifier SetAlignmentCheck(bool value)
-    {
-      verifier_options.alignmentCheck = value;
-      return this;
-    }
-    /// <summary> Enable/disable checking of string termination '0' character </summary>
-    /// <param name="value"> Value of the option for string termination '0' character check (Enable = true)</param>
-    public Verifier SetStringCheck(bool value)
-    {
-      verifier_options.stringEndCheck = value;
-      return this;
-    }
-
-    /// <summary> Check if there is identifier in buffer </summary>
-    /// <param name="buf"> Input flat byte buffer defined as ByteBuffer type </param>
-    /// <param name="startPos">Start position of data in the Byte Buffer</param>
-    /// <param name="identifier"> Identifier for the Byte Buffer</param>
-    /// <returns> Return True when the Byte Buffer Identifier is present</returns>
-    private bool BufferHasIdentifier(ByteBuffer buf, uint startPos, string identifier)
-    {
-      if (identifier.Length != FILE_IDENTIFIER_LENGTH)
-      {
-        throw new ArgumentException("FlatBuffers: file identifier must be length" + Convert.ToString(FILE_IDENTIFIER_LENGTH));
-      }
-      for (int i = 0; i < FILE_IDENTIFIER_LENGTH; i++)
-      {
-        if ((sbyte)identifier[i] != verifier_buffer.GetSbyte(Convert.ToInt32(SIZE_S_OFFSET + i + startPos)))
-        {
-          return false;
-        }
-      }
-
-      return true;
-    }
-
-    /// <summary> Get UOffsetT from buffer at given position - it must be verified before read </summary>
-    /// <param name="buf"> Input flat byte buffer defined as ByteBuffer type </param>
-    /// <param name="pos"> Position of data in the Byte Buffer</param>
-    /// <returns> Return the UOffset Value (Unsigned Integer type - 4 bytes) in pos </returns>
-    private uint ReadUOffsetT(ByteBuffer buf, uint pos)
-    {
-      return buf.GetUint(Convert.ToInt32(pos));
-    }
-    /// <summary> Get SOffsetT from buffer at given position - it must be verified before read </summary>
-    /// <param name="buf"> Input flat byte buffer defined as ByteBuffer type </param>
-    /// <param name="pos"> Position of data in the Byte Buffer</param>
-    /// <returns> Return the SOffset Value (Signed Integer type - 4 bytes) in pos </returns>
-    private int ReadSOffsetT(ByteBuffer buf, int pos)
-    {
-      return buf.GetInt(pos);
-    }
-    /// <summary> Get VOffsetT from buffer at given position - it must be verified before read </summary>
-    /// <param name="buf"> Input flat byte buffer defined as ByteBuffer type </param>
-    /// <param name="pos"> Position of data in the Byte Buffer</param>
-    /// <returns> Return the VOffset Value (Short type - 2 bytes) in pos </returns>
-    private short ReadVOffsetT(ByteBuffer buf, int pos)
-    {
-      return buf.GetShort(pos);
-    }
-
-    /// <summary> Get table data area relative offset from vtable. Result is relative to table start
-    ///           Fields which are deprecated are ignored by checking against the vtable's length. </summary>
-    /// <param name="pos"> Position of data in the Byte Buffer </param>
-    /// <param name="vtableOffset"> offset of value in the Table</param>
-    /// <returns> Return the relative VOffset Value (Short type - 2 bytes) in calculated offset </returns>
-    private short GetVRelOffset(int pos, short vtableOffset)
-    {
-      short VOffset = 0;
-      // Used try/catch because pos typa as int 32bit
-      try
-      {
-        // First, get vtable offset
-        short vtable = Convert.ToInt16(pos - ReadSOffsetT(verifier_buffer, pos));
-        // Check that offset points to vtable area (is smaller than vtable size)
-        if (vtableOffset < ReadVOffsetT(verifier_buffer, vtable))
-        {
-          // Now, we can read offset value - TODO check this value against size of table data
-          VOffset = ReadVOffsetT(verifier_buffer, vtable + vtableOffset);
-        }
-        else
-        {
-          VOffset = 0;
-        }
-      }
-      catch (Exception e)
-      {
-        Console.WriteLine("Exception: {0}", e);
-        return VOffset;
-      }
-      return VOffset;
-
-    }
-    /// <summary> Get table data area absolute offset from vtable. Result is the absolute buffer offset.
-    /// The result value offset cannot be '0' (pointing to itself) so after validation this method returns '0'
-    /// value as a marker for missing optional entry </summary>
-    /// <param name="tablePos"> Table Position value in the Byte Buffer </param>
-    /// <param name="vtableOffset"> offset value in the Table</param>
-    /// <returns> Return the absolute UOffset Value </returns>
-    private uint GetVOffset(uint tablePos, short vtableOffset)
-    {
-      uint UOffset = 0;
-      // First, get vtable relative offset
-      short relPos = GetVRelOffset(Convert.ToInt32(tablePos), vtableOffset);
-      if (relPos != 0)
-      {
-        // Calculate offset based on table position
-        UOffset = Convert.ToUInt32(tablePos + relPos);
-      }
-      else
-      {
-        UOffset = 0;
-      }
-      return UOffset;
-    }
-
-    /// <summary> Check flatbuffer complexity (tables depth, elements counter and so on) </summary>
-    /// <returns> If complexity is too high function returns false as verification error </returns>
-    private bool CheckComplexity()
-    {
-      return ((depth <= options.maxDepth) && (numTables <= options.maxTables));
-    }
-
-    /// <summary> Check alignment of element. </summary>
-    /// <returns> Return True when alignment of the element is correct</returns>
-    private bool CheckAlignment(uint element, ulong align)
-    {
-      return (((element & (align - 1)) == 0) || (!options.alignmentCheck));
-    }
-
-    /// <summary> Check if element is valid in buffer area. </summary> 
-    /// <param name="pos"> Value defines the offset/position to element</param>
-    /// <param name="elementSize"> Size of element</param>
-    /// <returns> Return True when Element is correct </returns>
-    private bool CheckElement(uint pos, ulong elementSize)
-    {
-      return ((elementSize < Convert.ToUInt64(verifier_buffer.Length)) && (pos <= (Convert.ToUInt32(verifier_buffer.Length) - elementSize)));
-    }
-    /// <summary> Check if element is a valid scalar. </summary>
-    /// <param name="pos"> Value defines the offset to scalar</param>
-    /// <param name="elementSize"> Size of element</param>
-    /// <returns> Return True when Scalar Element is correct </returns>
-    private bool CheckScalar(uint pos, ulong elementSize)
-    {
-      return ((CheckAlignment(pos, elementSize)) && (CheckElement(pos, elementSize)));
-    }
-    /// <summary> Check offset. It is a scalar with size of UOffsetT. </summary>
-    private bool CheckOffset(uint offset)
-    {
-      return (CheckScalar(offset, SIZE_U_OFFSET));
-    }
-
-    private checkElementStruct CheckVectorOrString(uint pos, ulong elementSize)
-    {
-      var result = new checkElementStruct
-      {
-        elementValid = false,
-        elementOffset = 0
-      };
-
-      uint vectorPos = pos;
-      // Check we can read the vector/string size field (it is of uoffset size)
-      if (!CheckScalar(vectorPos, SIZE_U_OFFSET))
-      {
-        // result.elementValid = false; result.elementOffset = 0;
-        return result;
-      }
-      // Check the whole array. If this is a string, the byte past the array
-      // must be 0.
-      uint size = ReadUOffsetT(verifier_buffer, vectorPos);
-      ulong max_elements = (FLATBUFFERS_MAX_BUFFER_SIZE / elementSize);
-      if (size >= max_elements)
-      {
-        // Protect against byte_size overflowing. 
-        // result.elementValid = false; result.elementOffset = 0;
-        return result;
-      }
-
-      uint bytes_size = SIZE_U_OFFSET + (Convert.ToUInt32(elementSize) * size);
-      uint buffer_end_pos = vectorPos + bytes_size;
-      result.elementValid = CheckElement(vectorPos, bytes_size);
-      result.elementOffset = buffer_end_pos;
-      return (result);
-    }
-
-    /// <summary>Verify a string at given position.</summary>
-    private bool CheckString(uint pos)
-    {
-      var result = CheckVectorOrString(pos, SIZE_BYTE);
-      if (options.stringEndCheck)
-      {
-        result.elementValid = result.elementValid && CheckScalar(result.elementOffset, 1); // Must have terminator
-        result.elementValid = result.elementValid && (verifier_buffer.GetSbyte(Convert.ToInt32(result.elementOffset)) == 0); // Terminating byte must be 0.
-      }
-      return result.elementValid;
-    }
-
-    /// <summary> Verify the vector of elements of given size </summary>
-    private bool CheckVector(uint pos, ulong elementSize)
-    {
-      var result = CheckVectorOrString(pos, elementSize);
-      return result.elementValid;
-    }
-    /// <summary> Verify table content using structure dependent generated function </summary>
-    private bool CheckTable(uint tablePos, VerifyTableAction verifyAction)
-    {
-      return verifyAction(this, tablePos);
-    }
-
-    /// <summary> String check wrapper function to be used in vector of strings check </summary>
-    private bool CheckStringFunc(Verifier verifier, uint pos)
-    {
-      return verifier.CheckString(pos);
-    }
-
-    /// <summary> Check vector of objects. Use generated object verification function </summary>
-    private bool CheckVectorOfObjects(uint pos, VerifyTableAction verifyAction)
-    {
-      if (!CheckVector(pos, SIZE_U_OFFSET))
-      {
-        return false;
-      }
-      uint size = ReadUOffsetT(verifier_buffer, pos);
-      // Vector data starts just after vector size/length
-      uint vecStart = pos + SIZE_U_OFFSET;
-      uint vecOff = 0;
-      // Iterate offsets and verify referenced objects
-      for (uint i = 0; i < size; i++)
-      {
-        vecOff = vecStart + (i * SIZE_U_OFFSET);
-        if (!CheckIndirectOffset(vecOff))
-        {
-          return false;
-        }
-        uint objOffset = GetIndirectOffset(vecOff);
-        if (!verifyAction(this, objOffset))
-        {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    /// <summary> Check if the offset referenced by offsetPos is the valid offset pointing to buffer</summary>
-    //  offsetPos - offset to offset data
-    private bool CheckIndirectOffset(uint pos)
-    {
-      // Check the input offset is valid
-      if(!CheckScalar(pos, SIZE_U_OFFSET))
-      {
-        return false;
-      }
-      // Get indirect offset
-      uint offset = ReadUOffsetT(verifier_buffer, pos);
-      // May not point to itself neither wrap around  (buffers are max 2GB)
-      if ((offset == 0) || (offset >= FLATBUFFERS_MAX_BUFFER_SIZE))
-      {
-        return false;
-      }
-      // Must be inside the buffer
-      return CheckElement(pos + offset, 1);
-    }
-
-    /// <summary> Check flatbuffer content using generated object verification function </summary>
-    private bool CheckBufferFromStart(string identifier, uint startPos, VerifyTableAction verifyAction)
-    {
-      if ((identifier != null) &&
-          (identifier.Length == 0) &&
-          ((verifier_buffer.Length < (SIZE_U_OFFSET + FILE_IDENTIFIER_LENGTH)) || (!BufferHasIdentifier(verifier_buffer, startPos, identifier))))
-      {
-        return false;
-      }
-      if(!CheckIndirectOffset(startPos))
-      {
-        return false;
-      }
-      uint offset = GetIndirectOffset(startPos);
-      return CheckTable(offset, verifyAction); //  && GetComputedSize()
-    }
-
-    /// <summary> Get indirect offset. It is an offset referenced by offset Pos </summary>
-    private uint GetIndirectOffset(uint pos)
-    {
-      // Get indirect offset referenced by offsetPos
-      uint offset = pos + ReadUOffsetT(verifier_buffer, pos);
-      return offset;
-    }
-
-    /// <summary> Verify beginning of table </summary>
-    /// <param name="tablePos"> Position in the Table </param>
-    /// <returns> Return True when the verification of the beginning of the table is passed</returns> 
-    // (this method is used internally by generated verification functions)
-    public bool VerifyTableStart(uint tablePos)
-    {
-      // Starting new table verification increases complexity of structure
-      depth_cnt++;
-      num_tables_cnt++;
-
-      if (!CheckScalar(tablePos, SIZE_S_OFFSET))
-      {
-        return false;
-      }
-      uint vtable = (uint)(tablePos - ReadSOffsetT(verifier_buffer, Convert.ToInt32(tablePos)));
-      return ((CheckComplexity()) && (CheckScalar(vtable, SIZE_V_OFFSET)) && (CheckAlignment(Convert.ToUInt32(ReadVOffsetT(verifier_buffer, Convert.ToInt32(vtable))), SIZE_V_OFFSET)) && (CheckElement(vtable, Convert.ToUInt64(ReadVOffsetT(verifier_buffer, Convert.ToInt32(vtable))))));
-    }
-
-    /// <summary> Verify end of table. In practice, this function does not check buffer but handles
-    /// verification statistics update </summary>
-    // (this method is used internally by generated verification functions)
-    public bool VerifyTableEnd(uint tablePos)
-    {
-      depth--;
-      return true;
-    }
-
-    /// <summary> Verify static/inlined data area field </summary>
-    /// <param name="tablePos"> Position in the Table</param>
-    /// <param name="offsetId"> Offset to the static/inlined data element </param>
-    /// <param name="elementSize"> Size of the element </param>
-    /// <param name="align"> Alignment bool value </param>
-    /// <param name="required"> Required Value when the offset == 0 </param>
-    /// <returns>Return True when the verification of the static/inlined data element is passed</returns>
-    // (this method is used internally by generated verification functions)
-    public bool VerifyField(uint tablePos, short offsetId, ulong elementSize, ulong align, bool required)
-    {
-      uint offset = GetVOffset(tablePos, offsetId);
-      if (offset != 0)
-      {
-        return ((CheckAlignment(offset, align)) && (CheckElement(offset, elementSize)));
-      }
-      return !required; // it is OK if field is not required
-    }
-
-    /// <summary> Verify string </summary> 
-    /// <param name="tablePos"> Position in the Table</param>
-    /// <param name="vOffset"> Offset to the String element </param>
-    /// <param name="required"> Required Value when the offset == 0 </param>
-    /// <returns>Return True when the verification of the String is passed</returns>
-    // (this method is used internally by generated verification functions)
-    public bool VerifyString(uint tablePos, short vOffset, bool required)
-    {
-      var offset = GetVOffset(tablePos, vOffset);
-      if (offset == 0)
-      {
-        return !required;
-      }
-      if (!CheckIndirectOffset(offset))
-      {
-        return false;
-      }
-      var strOffset = GetIndirectOffset(offset);
-      return CheckString(strOffset);
-    }
-
-    /// <summary> Verify vector of fixed size structures and scalars </summary>
-    /// <param name="tablePos"> Position in the Table</param>
-    /// <param name="vOffset"> Offset to the Vector of Data </param>
-    /// <param name="elementSize"> Size of the element</param>
-    /// <param name="required"> Required Value when the offset == 0 </param>
-    /// <returns>Return True when the verification of the Vector of Data passed</returns>
-    // (this method is used internally by generated verification functions)
-    public bool VerifyVectorOfData(uint tablePos, short vOffset, ulong elementSize, bool required)
-    {
-      var offset = GetVOffset(tablePos, vOffset);
-      if (offset == 0)
-      {
-        return !required;
-      }
-      if (!CheckIndirectOffset(offset))
-      {
-        return false;
-      }
-      var vecOffset = GetIndirectOffset(offset);
-      return  CheckVector(vecOffset, elementSize);
-    }
-
-    /// <summary> Verify array of strings </summary>
-    /// <param name="tablePos"> Position in the Table</param>
-    /// <param name="offsetId"> Offset to the Vector of String </param>
-    /// <param name="required"> Required Value when the offset == 0 </param>
-    /// <returns>Return True when the verification of the Vector of String passed</returns>
-    // (this method is used internally by generated verification functions)
-    public bool VerifyVectorOfStrings(uint tablePos, short offsetId, bool required)
-    {
-      var offset = GetVOffset(tablePos, offsetId);
-      if (offset == 0)
-      {
-        return !required;
-      }
-      if (!CheckIndirectOffset(offset))
-      {
-        return false;
-      }
-      var vecOffset = GetIndirectOffset(offset);
-      return CheckVectorOfObjects(vecOffset, CheckStringFunc); 
-    }
-
-    /// <summary> Verify vector of tables (objects). Tables are verified using generated verifyObjFunc </summary>
-    /// <param name="tablePos"> Position in the Table</param>
-    /// <param name="offsetId"> Offset to the Vector of Table </param>
-    /// <param name="verifyAction"> Method used to the verification Table </param>
-    /// <param name="required"> Required Value when the offset == 0 </param>
-    /// <returns>Return True when the verification of the Vector of Table passed</returns>
-    // (this method is used internally by generated verification functions)
-    public bool VerifyVectorOfTables(uint tablePos, short offsetId, VerifyTableAction verifyAction, bool required)
-    {
-      var offset = GetVOffset(tablePos, offsetId);
-      if (offset == 0)
-      {
-        return !required;
-      }
-      if (!CheckIndirectOffset(offset))
-      {
-        return false;
-      }
-      var vecOffset = GetIndirectOffset(offset);
-      return CheckVectorOfObjects(vecOffset, verifyAction);
-    }
-
-    /// <summary> Verify table object using generated verification function. </summary>
-    /// <param name="tablePos"> Position in the Table</param>
-    /// <param name="offsetId"> Offset to the Table </param>
-    /// <param name="verifyAction"> Method used to the verification Table </param>
-    /// <param name="required"> Required Value when the offset == 0 </param>
-    /// <returns>Return True when the verification of the Table passed</returns>
-    // (this method is used internally by generated verification functions)
-    public bool VerifyTable(uint tablePos, short offsetId, VerifyTableAction verifyAction, bool required)
-    {
-      var offset = GetVOffset(tablePos, offsetId);
-      if (offset == 0)
-      {
-        return !required;
-      }
-      if (!CheckIndirectOffset(offset))
-      {
-        return false;
-      }
-      var tabOffset = GetIndirectOffset(offset);
-      return CheckTable(tabOffset, verifyAction);
-    }
-
-    /// <summary> Verify nested buffer object. When verifyObjFunc is provided, it is used to verify object structure. </summary>
-    /// <param name="tablePos"> Position in the Table </param>
-    /// <param name="offsetId"> Offset to the Table </param>
-    /// <param name="verifyAction">  Method used to the verification Table </param>
-    /// <param name="required"> Required Value when the offset == 0  </param>
-    // (this method is used internally by generated verification functions)
-    public bool VerifyNestedBuffer(uint tablePos, short offsetId, VerifyTableAction verifyAction, bool required)
-    {
-      var offset = GetVOffset(tablePos, offsetId);
-      if (offset == 0)
-      {
-        return !required;
-      }
-      uint vecOffset = GetIndirectOffset(offset);
-      if (!CheckVector(vecOffset, SIZE_BYTE))
-      {
-        return false;
-      }
-      if (verifyAction != null)
-      {
-        var vecLength = ReadUOffsetT(verifier_buffer, vecOffset);
-        // Buffer begins after vector length
-        var vecStart = vecOffset + SIZE_U_OFFSET;
-        // Create and Copy nested buffer bytes from part of Verify Buffer
-        var nestedByteBuffer = new ByteBuffer(verifier_buffer.ToArray(Convert.ToInt32(vecStart), Convert.ToInt32(vecLength)));
-        var nestedVerifier = new Verifier(nestedByteBuffer, options);
-        // There is no internal identifier - use empty one
-        if (!nestedVerifier.CheckBufferFromStart("", 0, verifyAction))
-        {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    /// <summary> Verify static/inlined data area at absolute offset </summary>
-    /// <param name="pos"> Position of static/inlined data area in the Byte Buffer</param>
-    /// <param name="elementSize"> Size of the union data</param>
-    /// <param name="align"> Alignment bool value </param>
-    /// <returns>Return True when the verification of the Union Data is passed</returns>
-    // (this method is used internally by generated verification functions)
-    public bool VerifyUnionData(uint pos, ulong elementSize, ulong align)
-    {
-      bool result = ((CheckAlignment(pos, align)) && (CheckElement(pos, elementSize)));
-      return result;
-    }
-
-    /// <summary> Verify string referenced by absolute offset value </summary>
-    /// <param name="pos"> Position of Union String in the Byte Buffer</param>
-    /// <returns>Return True when the verification of the Union String is passed</returns> 
-    // (this method is used internally by generated verification functions)
-    public bool VerifyUnionString(uint pos)
-    {
-      bool result = CheckString(pos);
-      return result;
-    }
-
-    /// <summary> Method verifies union object using generated verification function </summary>
-    /// <param name="tablePos"> Position in the Table</param>
-    /// <param name="typeIdVOffset"> Offset in the Table</param>
-    /// <param name="valueVOffset"> Offset to Element</param>
-    /// <param name="verifyAction"> Verification Method used for Union</param>
-    /// <param name="required"> Required Value when the offset == 0 </param>
-    // (this method is used internally by generated verification functions)
-    public bool VerifyUnion(uint tablePos, short typeIdVOffset, short valueVOffset, VerifyUnionAction verifyAction, bool required)
-    {
-      // Check the union type index
-      var offset = GetVOffset(tablePos, typeIdVOffset);
-      if (offset == 0)
-      {
-        return !required;
-      }
-      if (!((CheckAlignment(offset, SIZE_BYTE)) && (CheckElement(offset, SIZE_BYTE))))
-      {
-        return false;
-      }
-      // Check union data
-      offset = GetVOffset(tablePos, valueVOffset);
-      // Take type id
-      var typeId = verifier_buffer.Get(Convert.ToInt32(offset));
-      if (offset == 0)
-      {
-        // When value data is not present, allow union verification function to deal with illegal offset
-        return verifyAction(this, typeId, Convert.ToUInt32(verifier_buffer.Length));
-      }
-      if (!CheckIndirectOffset(offset))
-      {
-        return false;
-      }
-      // Take value offset and validate union structure
-      uint unionOffset = GetIndirectOffset(offset);
-      return verifyAction(this, typeId, unionOffset);
-    }
-
-    /// <summary> Verify vector of unions (objects). Unions are verified using generated verifyObjFunc </summary>
-    /// <param name="tablePos"> Position of the Table</param>
-    /// <param name="typeOffsetId"> Offset in the Table (Union type id)</param>
-    /// <param name="offsetId"> Offset to vector of Data Structure offset</param>
-    /// <param name="verifyAction"> Verification Method used for Union</param>
-    /// <param name="required"> Required Value when the offset == 0 </param>
-    /// <returns>Return True when the verification of the Vector of Unions passed</returns>
-    // (this method is used internally by generated verification functions)
-    public bool VerifyVectorOfUnion(uint tablePos, short typeOffsetId, short offsetId, VerifyUnionAction verifyAction, bool required)
-    {
-      // type id offset must be valid
-      var offset = GetVOffset(tablePos, typeOffsetId);
-      if (offset == 0)
-      {
-        return !required;
-      }
-      if (!CheckIndirectOffset(offset))
-      {
-        return false;
-      }
-      // Get type id table absolute offset
-      var typeIdVectorOffset = GetIndirectOffset(offset);
-      // values offset must be valid
-      offset = GetVOffset(tablePos, offsetId);
-      if (!CheckIndirectOffset(offset))
-      {
-        return false;
-      }
-      var valueVectorOffset = GetIndirectOffset(offset);
-      // validate referenced vectors
-      if(!CheckVector(typeIdVectorOffset, SIZE_BYTE) ||
-         !CheckVector(valueVectorOffset, SIZE_U_OFFSET))
-      {
-        return false;
-      }
-      // Both vectors should have the same length
-      var typeIdVectorLength = ReadUOffsetT(verifier_buffer, typeIdVectorOffset);
-      var valueVectorLength = ReadUOffsetT(verifier_buffer, valueVectorOffset);
-      if (typeIdVectorLength != valueVectorLength)
-      {
-        return false;
-      }
-      // Verify each union from vectors
-      var typeIdStart = typeIdVectorOffset + SIZE_U_OFFSET;
-      var valueStart = valueVectorOffset + SIZE_U_OFFSET;
-      for (uint i = 0; i < typeIdVectorLength; i++)
-      {
-        // Get type id
-        byte typeId = verifier_buffer.Get(Convert.ToInt32(typeIdStart + i * SIZE_U_OFFSET));
-        // get offset to vector item
-        uint off = valueStart + i * SIZE_U_OFFSET;
-        // Check the vector item has a proper offset
-        if (!CheckIndirectOffset(off))
-        {
-          return false;
-        }
-        uint valueOffset = GetIndirectOffset(off);
-        // Verify object
-        if (!verifyAction(this, typeId, valueOffset))
-        {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    // Method verifies flatbuffer data using generated Table verification function.
-    // The data buffer is already provided when creating [Verifier] object (see [NewVerifier])
-    //
-    //   - identifier - the expected identifier of buffer data.
-    //     When empty identifier is provided the identifier validation is skipped.
-    //   - sizePrefixed - this flag should be true when buffer is prefixed with content size
-    //   - verifyObjFunc - function to be used for verification. This function is generated by compiler and included in each table definition file with name "<Tablename>Verify"
-    //
-    // Example:
-    //
-    //  /* Verify Monster table. Ignore buffer name and assume buffer does not contain data length prefix */
-    //  isValid = verifier.verifyBuffer(bb, false, MonsterVerify)
-    //
-    //  /* Verify Monster table. Buffer name is 'MONS' and contains data length prefix */
-    //  isValid = verifier.verifyBuffer("MONS", true, MonsterVerify)
-    /// <summary> Method verifies flatbuffer data using generated Table verification function </summary>
-    /// 
-    /// <param name="identifier"> The expected identifier of buffer data</param>
-    /// <param name="sizePrefixed"> Flag should be true when buffer is prefixed with content size</param>
-    /// <param name="verifyAction"> Function to be used for verification. This function is generated by compiler and included in each table definition file</param>
-    /// <returns> Return True when verification of FlatBuffer passed</returns>
-    /// <example>
-    /// Example 1. Verify Monster table. Ignore buffer name and assume buffer does not contain data length prefix 
-    /// <code>  isValid = verifier.VerifyBuffer(bb, false, MonsterVerify)</code>
-    /// Example 2. Verify Monster table. Buffer name is 'MONS' and contains data length prefix 
-    /// <code>  isValid = verifier.VerifyBuffer("MONS", true, MonsterVerify)</code>
-    /// </example>
-    public bool VerifyBuffer(string identifier, bool sizePrefixed, VerifyTableAction verifyAction)
-    {
-      // Reset counters - starting verification from beginning
-      depth = 0;
-      numTables = 0;
-
-      var start = (uint)(verifier_buffer.Position);
-      if (sizePrefixed) 
-      {
-        start = (uint)(verifier_buffer.Position) + SIZE_PREFIX_LENGTH;
-        if(!CheckScalar((uint)(verifier_buffer.Position), SIZE_PREFIX_LENGTH))
-        {
-          return false;
-        }
-        uint size = ReadUOffsetT(verifier_buffer, (uint)(verifier_buffer.Position));
-        if (size != ((uint)(verifier_buffer.Length) - start))
-        {
-          return false;
-        }
-      } 
-      return CheckBufferFromStart(identifier, start, verifyAction);
-    }
-  }
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/IFlatbufferObject.cs b/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/IFlatbufferObject.cs
deleted file mode 100644
index 72073b0..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/IFlatbufferObject.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace Google.FlatBuffers
-{
-    /// <summary>
-    /// This is the base for both structs and tables.
-    /// </summary>
-    internal interface IFlatbufferObject
-    {
-        void __init(int _i, ByteBuffer _bb);
-
-        ByteBuffer ByteBuffer { get; }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/Offset.cs b/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/Offset.cs
deleted file mode 100644
index 582bb3b..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/Offset.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace Google.FlatBuffers
-{
-    /// <summary>
-    /// Offset class for typesafe assignments.
-    /// </summary>
-    internal struct Offset<T> where T : struct
-    {
-        public int Value;
-        public Offset(int value)
-        {
-            Value = value;
-        }
-    }
-
-    internal struct StringOffset
-    {
-        public int Value;
-        public StringOffset(int value)
-        {
-            Value = value;
-        }
-    }
-
-    internal struct VectorOffset
-    {
-        public int Value;
-        public VectorOffset(int value)
-        {
-            Value = value;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/Struct.cs b/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/Struct.cs
deleted file mode 100644
index 313aade..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/Struct.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace Google.FlatBuffers
-{
-    /// <summary>
-    /// All structs in the generated code derive from this class, and add their own accessors.
-    /// </summary>
-    internal struct Struct
-    {
-        public int bb_pos { get; private set; }
-        public ByteBuffer bb { get; private set; }
-
-        // Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
-        public Struct(int _i, ByteBuffer _bb) : this()
-        {
-            bb = _bb;
-            bb_pos = _i;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/Table.cs b/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/Table.cs
deleted file mode 100644
index 860ba55..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/FlatBuffers/Table.cs
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Text;
-using System.Runtime.InteropServices;
-
-namespace Google.FlatBuffers
-{
-    /// <summary>
-    /// All tables in the generated code derive from this struct, and add their own accessors.
-    /// </summary>
-    internal struct Table
-    {
-        public int bb_pos { get; private set; }
-        public ByteBuffer bb { get; private set; }
-
-        public ByteBuffer ByteBuffer { get { return bb; } }
-
-        // Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
-        public Table(int _i, ByteBuffer _bb) : this()
-        {
-            bb = _bb;
-            bb_pos = _i;
-        }
-
-        // Look up a field in the vtable, return an offset into the object, or 0 if the field is not
-        // present.
-        public int __offset(int vtableOffset)
-        {
-            int vtable = bb_pos - bb.GetInt(bb_pos);
-            return vtableOffset < bb.GetShort(vtable) ? (int)bb.GetShort(vtable + vtableOffset) : 0;
-        }
-
-        public static int __offset(int vtableOffset, int offset, ByteBuffer bb)
-        {
-            int vtable = bb.Length - offset;
-            return (int)bb.GetShort(vtable + vtableOffset - bb.GetInt(vtable)) + vtable;
-        }
-
-        // Retrieve the relative offset stored at "offset"
-        public int __indirect(int offset)
-        {
-            return offset + bb.GetInt(offset);
-        }
-
-        public static int __indirect(int offset, ByteBuffer bb)
-        {
-            return offset + bb.GetInt(offset);
-        }
-
-        // Create a .NET String from UTF-8 data stored inside the flatbuffer.
-        public string __string(int offset)
-        {
-            int stringOffset = bb.GetInt(offset);
-            if (stringOffset == 0)
-                return null;
-
-            offset += stringOffset;
-            var len = bb.GetInt(offset);
-            var startPos = offset + sizeof(int);
-            return bb.GetStringUTF8(startPos, len);
-        }
-
-        // Get the length of a vector whose offset is stored at "offset" in this object.
-        public int __vector_len(int offset)
-        {
-            offset += bb_pos;
-            offset += bb.GetInt(offset);
-            return bb.GetInt(offset);
-        }
-
-        // Get the start of data of a vector whose offset is stored at "offset" in this object.
-        public int __vector(int offset)
-        {
-            offset += bb_pos;
-            return offset + bb.GetInt(offset) + sizeof(int);  // data starts after the length
-        }
-
-#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
-        // Get the data of a vector whose offset is stored at "offset" in this object as an
-        // Spant&lt;byte&gt;. If the vector is not present in the ByteBuffer,
-        // then an empty span will be returned.
-        public Span<T> __vector_as_span<T>(int offset, int elementSize) where T : struct
-        {
-            if (!BitConverter.IsLittleEndian)
-            {
-               throw new NotSupportedException("Getting typed span on a Big Endian " +
-                                               "system is not support");
-            }
-
-            var o = this.__offset(offset);
-            if (0 == o)
-            {
-                return new Span<T>();
-            }
-
-            var pos = this.__vector(o);
-            var len = this.__vector_len(o);
-            return MemoryMarshal.Cast<byte, T>(bb.ToSpan(pos, len * elementSize));
-        }
-#else
-        // Get the data of a vector whose offset is stored at "offset" in this object as an
-        // ArraySegment&lt;byte&gt;. If the vector is not present in the ByteBuffer,
-        // then a null value will be returned.
-        public ArraySegment<byte>? __vector_as_arraysegment(int offset)
-        {
-            var o = this.__offset(offset);
-            if (0 == o)
-            {
-                return null;
-            }
-
-            var pos = this.__vector(o);
-            var len = this.__vector_len(o);
-            return bb.ToArraySegment(pos, len);
-        }
-#endif
-
-        // Get the data of a vector whose offset is stored at "offset" in this object as an
-        // T[]. If the vector is not present in the ByteBuffer, then a null value will be
-        // returned.
-        public T[] __vector_as_array<T>(int offset)
-            where T : struct
-        {
-            if(!BitConverter.IsLittleEndian)
-            {
-                throw new NotSupportedException("Getting typed arrays on a Big Endian " +
-                    "system is not support");
-            }
-
-            var o = this.__offset(offset);
-            if (0 == o)
-            {
-                return null;
-            }
-
-            var pos = this.__vector(o);
-            var len = this.__vector_len(o);
-            return bb.ToArray<T>(pos, len);
-        }
-
-        // Initialize any Table-derived type to point to the union at the given offset.
-        public T __union<T>(int offset) where T : struct, IFlatbufferObject
-        {
-            T t = new T();
-            t.__init(__indirect(offset), bb);
-            return t;
-        }
-
-        public static bool __has_identifier(ByteBuffer bb, string ident)
-        {
-            if (ident.Length != FlatBufferConstants.FileIdentifierLength)
-                throw new ArgumentException("FlatBuffers: file identifier must be length " + FlatBufferConstants.FileIdentifierLength, "ident");
-
-            for (var i = 0; i < FlatBufferConstants.FileIdentifierLength; i++)
-            {
-                if (ident[i] != (char)bb.Get(bb.Position + sizeof(int) + i)) return false;
-            }
-
-            return true;
-        }
-
-        // Compare strings in the ByteBuffer.
-        public static int CompareStrings(int offset_1, int offset_2, ByteBuffer bb)
-        {
-            offset_1 += bb.GetInt(offset_1);
-            offset_2 += bb.GetInt(offset_2);
-            var len_1 = bb.GetInt(offset_1);
-            var len_2 = bb.GetInt(offset_2);
-            var startPos_1 = offset_1 + sizeof(int);
-            var startPos_2 = offset_2 + sizeof(int);
-            var len = Math.Min(len_1, len_2);
-            for(int i = 0; i < len; i++) {
-                byte b1 = bb.Get(i + startPos_1);
-                byte b2 = bb.Get(i + startPos_2);
-                if (b1 != b2)
-                    return b1 - b2;
-            }
-            return len_1 - len_2;
-        }
-
-        // Compare string from the ByteBuffer with the string object
-        public static int CompareStrings(int offset_1, byte[] key, ByteBuffer bb)
-        {
-            offset_1 += bb.GetInt(offset_1);
-            var len_1 = bb.GetInt(offset_1);
-            var len_2 = key.Length;
-            var startPos_1 = offset_1 + sizeof(int);
-            var len = Math.Min(len_1, len_2);
-            for (int i = 0; i < len; i++) {
-                byte b = bb.Get(i + startPos_1);
-                if (b != key[i])
-                    return b - key[i];
-            }
-            return len_1 - len_2;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Footer.cs b/csharp/src/Apache.Arrow/Flatbuf/Footer.cs
deleted file mode 100644
index 6c1530d..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Footer.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// ----------------------------------------------------------------------
-/// Arrow File metadata
-///
-internal struct Footer : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Footer GetRootAsFooter(ByteBuffer _bb) { return GetRootAsFooter(_bb, new Footer()); }
-  public static Footer GetRootAsFooter(ByteBuffer _bb, Footer obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public static bool VerifyFooter(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("", false, FooterVerify.Verify); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Footer __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public MetadataVersion Version { get { int o = __p.__offset(4); return o != 0 ? (MetadataVersion)__p.bb.GetShort(o + __p.bb_pos) : MetadataVersion.V1; } }
-  public Schema? Schema { get { int o = __p.__offset(6); return o != 0 ? (Schema?)(new Schema()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
-  public Block? Dictionaries(int j) { int o = __p.__offset(8); return o != 0 ? (Block?)(new Block()).__assign(__p.__vector(o) + j * 24, __p.bb) : null; }
-  public int DictionariesLength { get { int o = __p.__offset(8); return o != 0 ? __p.__vector_len(o) : 0; } }
-  public Block? RecordBatches(int j) { int o = __p.__offset(10); return o != 0 ? (Block?)(new Block()).__assign(__p.__vector(o) + j * 24, __p.bb) : null; }
-  public int RecordBatchesLength { get { int o = __p.__offset(10); return o != 0 ? __p.__vector_len(o) : 0; } }
-  /// User-defined metadata
-  public KeyValue? CustomMetadata(int j) { int o = __p.__offset(12); return o != 0 ? (KeyValue?)(new KeyValue()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
-  public int CustomMetadataLength { get { int o = __p.__offset(12); return o != 0 ? __p.__vector_len(o) : 0; } }
-
-  public static Offset<Footer> CreateFooter(FlatBufferBuilder builder,
-      MetadataVersion version = MetadataVersion.V1,
-      Offset<Schema> schemaOffset = default(Offset<Schema>),
-      VectorOffset dictionariesOffset = default(VectorOffset),
-      VectorOffset recordBatchesOffset = default(VectorOffset),
-      VectorOffset custom_metadataOffset = default(VectorOffset)) {
-    builder.StartTable(5);
-    Footer.AddCustomMetadata(builder, custom_metadataOffset);
-    Footer.AddRecordBatches(builder, recordBatchesOffset);
-    Footer.AddDictionaries(builder, dictionariesOffset);
-    Footer.AddSchema(builder, schemaOffset);
-    Footer.AddVersion(builder, version);
-    return Footer.EndFooter(builder);
-  }
-
-  public static void StartFooter(FlatBufferBuilder builder) { builder.StartTable(5); }
-  public static void AddVersion(FlatBufferBuilder builder, MetadataVersion version) { builder.AddShort(0, (short)version, 0); }
-  public static void AddSchema(FlatBufferBuilder builder, Offset<Schema> schemaOffset) { builder.AddOffset(1, schemaOffset.Value, 0); }
-  public static void AddDictionaries(FlatBufferBuilder builder, VectorOffset dictionariesOffset) { builder.AddOffset(2, dictionariesOffset.Value, 0); }
-  public static void StartDictionariesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(24, numElems, 8); }
-  public static void AddRecordBatches(FlatBufferBuilder builder, VectorOffset recordBatchesOffset) { builder.AddOffset(3, recordBatchesOffset.Value, 0); }
-  public static void StartRecordBatchesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(24, numElems, 8); }
-  public static void AddCustomMetadata(FlatBufferBuilder builder, VectorOffset customMetadataOffset) { builder.AddOffset(4, customMetadataOffset.Value, 0); }
-  public static VectorOffset CreateCustomMetadataVector(FlatBufferBuilder builder, Offset<KeyValue>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, Offset<KeyValue>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<KeyValue>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<KeyValue>>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartCustomMetadataVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
-  public static Offset<Footer> EndFooter(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Footer>(o);
-  }
-  public static void FinishFooterBuffer(FlatBufferBuilder builder, Offset<Footer> offset) { builder.Finish(offset.Value); }
-  public static void FinishSizePrefixedFooterBuffer(FlatBufferBuilder builder, Offset<Footer> offset) { builder.FinishSizePrefixed(offset.Value); }
-}
-
-
-static internal class FooterVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Version*/, 2 /*MetadataVersion*/, 2, false)
-      && verifier.VerifyTable(tablePos, 6 /*Schema*/, SchemaVerify.Verify, false)
-      && verifier.VerifyVectorOfData(tablePos, 8 /*Dictionaries*/, 24 /*Block*/, false)
-      && verifier.VerifyVectorOfData(tablePos, 10 /*RecordBatches*/, 24 /*Block*/, false)
-      && verifier.VerifyVectorOfTables(tablePos, 12 /*CustomMetadata*/, KeyValueVerify.Verify, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/KeyValue.cs b/csharp/src/Apache.Arrow/Flatbuf/KeyValue.cs
deleted file mode 100644
index 3dffb61..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/KeyValue.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// ----------------------------------------------------------------------
-/// user defined key value pairs to add custom metadata to arrow
-/// key namespacing is the responsibility of the user
-internal struct KeyValue : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static KeyValue GetRootAsKeyValue(ByteBuffer _bb) { return GetRootAsKeyValue(_bb, new KeyValue()); }
-  public static KeyValue GetRootAsKeyValue(ByteBuffer _bb, KeyValue obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public KeyValue __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public string Key { get { int o = __p.__offset(4); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
-#if ENABLE_SPAN_T
-  public Span<byte> GetKeyBytes() { return __p.__vector_as_span<byte>(4, 1); }
-#else
-  public ArraySegment<byte>? GetKeyBytes() { return __p.__vector_as_arraysegment(4); }
-#endif
-  public byte[] GetKeyArray() { return __p.__vector_as_array<byte>(4); }
-  public string Value { get { int o = __p.__offset(6); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
-#if ENABLE_SPAN_T
-  public Span<byte> GetValueBytes() { return __p.__vector_as_span<byte>(6, 1); }
-#else
-  public ArraySegment<byte>? GetValueBytes() { return __p.__vector_as_arraysegment(6); }
-#endif
-  public byte[] GetValueArray() { return __p.__vector_as_array<byte>(6); }
-
-  public static Offset<KeyValue> CreateKeyValue(FlatBufferBuilder builder,
-      StringOffset keyOffset = default(StringOffset),
-      StringOffset valueOffset = default(StringOffset)) {
-    builder.StartTable(2);
-    KeyValue.AddValue(builder, valueOffset);
-    KeyValue.AddKey(builder, keyOffset);
-    return KeyValue.EndKeyValue(builder);
-  }
-
-  public static void StartKeyValue(FlatBufferBuilder builder) { builder.StartTable(2); }
-  public static void AddKey(FlatBufferBuilder builder, StringOffset keyOffset) { builder.AddOffset(0, keyOffset.Value, 0); }
-  public static void AddValue(FlatBufferBuilder builder, StringOffset valueOffset) { builder.AddOffset(1, valueOffset.Value, 0); }
-  public static Offset<KeyValue> EndKeyValue(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<KeyValue>(o);
-  }
-}
-
-
-static internal class KeyValueVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyString(tablePos, 4 /*Key*/, false)
-      && verifier.VerifyString(tablePos, 6 /*Value*/, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/LargeListView.cs b/csharp/src/Apache.Arrow/Flatbuf/LargeListView.cs
deleted file mode 100644
index 685e913..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/LargeListView.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Same as ListView, but with 64-bit offsets and sizes, allowing to represent
-/// extremely large data values.
-internal struct LargeListView : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static LargeListView GetRootAsLargeListView(ByteBuffer _bb) { return GetRootAsLargeListView(_bb, new LargeListView()); }
-  public static LargeListView GetRootAsLargeListView(ByteBuffer _bb, LargeListView obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public LargeListView __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartLargeListView(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<LargeListView> EndLargeListView(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<LargeListView>(o);
-  }
-}
-
-
-static internal class LargeListViewVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/ListView.cs b/csharp/src/Apache.Arrow/Flatbuf/ListView.cs
deleted file mode 100644
index d2e54e4..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/ListView.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Represents the same logical types that List can, but contains offsets and
-/// sizes allowing for writes in any order and sharing of child values among
-/// list values.
-internal struct ListView : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static ListView GetRootAsListView(ByteBuffer _bb) { return GetRootAsListView(_bb, new ListView()); }
-  public static ListView GetRootAsListView(ByteBuffer _bb, ListView obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public ListView __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartListView(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<ListView> EndListView(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<ListView>(o);
-  }
-}
-
-
-static internal class ListViewVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Map.cs b/csharp/src/Apache.Arrow/Flatbuf/Map.cs
deleted file mode 100644
index 4b4c292..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Map.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// A Map is a logical nested type that is represented as
-///
-/// List<entries: Struct<key: K, value: V>>
-///
-/// In this layout, the keys and values are each respectively contiguous. We do
-/// not constrain the key and value types, so the application is responsible
-/// for ensuring that the keys are hashable and unique. Whether the keys are sorted
-/// may be set in the metadata for this field.
-///
-/// In a field with Map type, the field has a child Struct field, which then
-/// has two children: key type and the second the value type. The names of the
-/// child fields may be respectively "entries", "key", and "value", but this is
-/// not enforced.
-///
-/// Map
-/// ```text
-///   - child[0] entries: Struct
-///     - child[0] key: K
-///     - child[1] value: V
-/// ```
-/// Neither the "entries" field nor the "key" field may be nullable.
-///
-/// The metadata is structured so that Arrow systems without special handling
-/// for Map can make Map an alias for List. The "layout" attribute for the Map
-/// field must have the same contents as a List.
-internal struct Map : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Map GetRootAsMap(ByteBuffer _bb) { return GetRootAsMap(_bb, new Map()); }
-  public static Map GetRootAsMap(ByteBuffer _bb, Map obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Map __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// Set to true if the keys within each value are sorted
-  public bool KeysSorted { get { int o = __p.__offset(4); return o != 0 ? 0!=__p.bb.Get(o + __p.bb_pos) : (bool)false; } }
-
-  public static Offset<Map> CreateMap(FlatBufferBuilder builder,
-      bool keysSorted = false) {
-    builder.StartTable(1);
-    Map.AddKeysSorted(builder, keysSorted);
-    return Map.EndMap(builder);
-  }
-
-  public static void StartMap(FlatBufferBuilder builder) { builder.StartTable(1); }
-  public static void AddKeysSorted(FlatBufferBuilder builder, bool keysSorted) { builder.AddBool(0, keysSorted, false); }
-  public static Offset<Map> EndMap(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Map>(o);
-  }
-}
-
-
-static internal class MapVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*KeysSorted*/, 1 /*bool*/, 1, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Message.cs b/csharp/src/Apache.Arrow/Flatbuf/Message.cs
deleted file mode 100644
index 5cd469d..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Message.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct Message : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Message GetRootAsMessage(ByteBuffer _bb) { return GetRootAsMessage(_bb, new Message()); }
-  public static Message GetRootAsMessage(ByteBuffer _bb, Message obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public static bool VerifyMessage(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("", false, MessageVerify.Verify); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Message __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public MetadataVersion Version { get { int o = __p.__offset(4); return o != 0 ? (MetadataVersion)__p.bb.GetShort(o + __p.bb_pos) : MetadataVersion.V1; } }
-  public MessageHeader HeaderType { get { int o = __p.__offset(6); return o != 0 ? (MessageHeader)__p.bb.Get(o + __p.bb_pos) : MessageHeader.NONE; } }
-  public TTable? Header<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(8); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
-  public Schema HeaderAsSchema() { return Header<Schema>().Value; }
-  public DictionaryBatch HeaderAsDictionaryBatch() { return Header<DictionaryBatch>().Value; }
-  public RecordBatch HeaderAsRecordBatch() { return Header<RecordBatch>().Value; }
-  public Tensor HeaderAsTensor() { return Header<Tensor>().Value; }
-  public SparseTensor HeaderAsSparseTensor() { return Header<SparseTensor>().Value; }
-  public long BodyLength { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
-  public KeyValue? CustomMetadata(int j) { int o = __p.__offset(12); return o != 0 ? (KeyValue?)(new KeyValue()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
-  public int CustomMetadataLength { get { int o = __p.__offset(12); return o != 0 ? __p.__vector_len(o) : 0; } }
-
-  public static Offset<Message> CreateMessage(FlatBufferBuilder builder,
-      MetadataVersion version = MetadataVersion.V1,
-      MessageHeader header_type = MessageHeader.NONE,
-      int headerOffset = 0,
-      long bodyLength = 0,
-      VectorOffset custom_metadataOffset = default(VectorOffset)) {
-    builder.StartTable(5);
-    Message.AddBodyLength(builder, bodyLength);
-    Message.AddCustomMetadata(builder, custom_metadataOffset);
-    Message.AddHeader(builder, headerOffset);
-    Message.AddVersion(builder, version);
-    Message.AddHeaderType(builder, header_type);
-    return Message.EndMessage(builder);
-  }
-
-  public static void StartMessage(FlatBufferBuilder builder) { builder.StartTable(5); }
-  public static void AddVersion(FlatBufferBuilder builder, MetadataVersion version) { builder.AddShort(0, (short)version, 0); }
-  public static void AddHeaderType(FlatBufferBuilder builder, MessageHeader headerType) { builder.AddByte(1, (byte)headerType, 0); }
-  public static void AddHeader(FlatBufferBuilder builder, int headerOffset) { builder.AddOffset(2, headerOffset, 0); }
-  public static void AddBodyLength(FlatBufferBuilder builder, long bodyLength) { builder.AddLong(3, bodyLength, 0); }
-  public static void AddCustomMetadata(FlatBufferBuilder builder, VectorOffset customMetadataOffset) { builder.AddOffset(4, customMetadataOffset.Value, 0); }
-  public static VectorOffset CreateCustomMetadataVector(FlatBufferBuilder builder, Offset<KeyValue>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, Offset<KeyValue>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<KeyValue>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<KeyValue>>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartCustomMetadataVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
-  public static Offset<Message> EndMessage(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Message>(o);
-  }
-  public static void FinishMessageBuffer(FlatBufferBuilder builder, Offset<Message> offset) { builder.Finish(offset.Value); }
-  public static void FinishSizePrefixedMessageBuffer(FlatBufferBuilder builder, Offset<Message> offset) { builder.FinishSizePrefixed(offset.Value); }
-}
-
-
-static internal class MessageVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Version*/, 2 /*MetadataVersion*/, 2, false)
-      && verifier.VerifyField(tablePos, 6 /*HeaderType*/, 1 /*MessageHeader*/, 1, false)
-      && verifier.VerifyUnion(tablePos, 6, 8 /*Header*/, MessageHeaderVerify.Verify, false)
-      && verifier.VerifyField(tablePos, 10 /*BodyLength*/, 8 /*long*/, 8, false)
-      && verifier.VerifyVectorOfTables(tablePos, 12 /*CustomMetadata*/, KeyValueVerify.Verify, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/RecordBatch.cs b/csharp/src/Apache.Arrow/Flatbuf/RecordBatch.cs
deleted file mode 100644
index 2df8716..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/RecordBatch.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// A data header describing the shared memory layout of a "record" or "row"
-/// batch. Some systems call this a "row batch" internally and others a "record
-/// batch".
-internal struct RecordBatch : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static RecordBatch GetRootAsRecordBatch(ByteBuffer _bb) { return GetRootAsRecordBatch(_bb, new RecordBatch()); }
-  public static RecordBatch GetRootAsRecordBatch(ByteBuffer _bb, RecordBatch obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public RecordBatch __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// number of records / rows. The arrays in the batch should all have this
-  /// length
-  public long Length { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
-  /// Nodes correspond to the pre-ordered flattened logical schema
-  public FieldNode? Nodes(int j) { int o = __p.__offset(6); return o != 0 ? (FieldNode?)(new FieldNode()).__assign(__p.__vector(o) + j * 16, __p.bb) : null; }
-  public int NodesLength { get { int o = __p.__offset(6); return o != 0 ? __p.__vector_len(o) : 0; } }
-  /// Buffers correspond to the pre-ordered flattened buffer tree
-  ///
-  /// The number of buffers appended to this list depends on the schema. For
-  /// example, most primitive arrays will have 2 buffers, 1 for the validity
-  /// bitmap and 1 for the values. For struct arrays, there will only be a
-  /// single buffer for the validity (nulls) bitmap
-  public Buffer? Buffers(int j) { int o = __p.__offset(8); return o != 0 ? (Buffer?)(new Buffer()).__assign(__p.__vector(o) + j * 16, __p.bb) : null; }
-  public int BuffersLength { get { int o = __p.__offset(8); return o != 0 ? __p.__vector_len(o) : 0; } }
-  /// Optional compression of the message body
-  public BodyCompression? Compression { get { int o = __p.__offset(10); return o != 0 ? (BodyCompression?)(new BodyCompression()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
-  /// Some types such as Utf8View are represented using a variable number of buffers.
-  /// For each such Field in the pre-ordered flattened logical schema, there will be
-  /// an entry in variadicBufferCounts to indicate the number of number of variadic
-  /// buffers which belong to that Field in the current RecordBatch.
-  ///
-  /// For example, the schema
-  ///     col1: Struct<alpha: Int32, beta: BinaryView, gamma: Float64>
-  ///     col2: Utf8View
-  /// contains two Fields with variadic buffers so variadicBufferCounts will have
-  /// two entries, the first counting the variadic buffers of `col1.beta` and the
-  /// second counting `col2`'s.
-  ///
-  /// This field may be omitted if and only if the schema contains no Fields with
-  /// a variable number of buffers, such as BinaryView and Utf8View.
-  public long VariadicBufferCounts(int j) { int o = __p.__offset(12); return o != 0 ? __p.bb.GetLong(__p.__vector(o) + j * 8) : (long)0; }
-  public int VariadicBufferCountsLength { get { int o = __p.__offset(12); return o != 0 ? __p.__vector_len(o) : 0; } }
-#if ENABLE_SPAN_T
-  public Span<long> GetVariadicCountsBytes() { return __p.__vector_as_span<long>(12, 8); }
-#else
-  public ArraySegment<byte>? GetVariadicCountsBytes() { return __p.__vector_as_arraysegment(12); }
-#endif
-  public long[] GetVariadicCountsArray() { return __p.__vector_as_array<long>(12); }
-
-  public static Offset<RecordBatch> CreateRecordBatch(FlatBufferBuilder builder,
-      long length = 0,
-      VectorOffset nodesOffset = default(VectorOffset),
-      VectorOffset buffersOffset = default(VectorOffset),
-      Offset<BodyCompression> compressionOffset = default(Offset<BodyCompression>),
-      VectorOffset variadicCountsOffset = default(VectorOffset)) {
-    builder.StartTable(5);
-    RecordBatch.AddLength(builder, length);
-    RecordBatch.AddVariadicCounts(builder, variadicCountsOffset);
-    RecordBatch.AddCompression(builder, compressionOffset);
-    RecordBatch.AddBuffers(builder, buffersOffset);
-    RecordBatch.AddNodes(builder, nodesOffset);
-    return RecordBatch.EndRecordBatch(builder);
-  }
-
-  public static void StartRecordBatch(FlatBufferBuilder builder) { builder.StartTable(5); }
-  public static void AddLength(FlatBufferBuilder builder, long length) { builder.AddLong(0, length, 0); }
-  public static void AddNodes(FlatBufferBuilder builder, VectorOffset nodesOffset) { builder.AddOffset(1, nodesOffset.Value, 0); }
-  public static void StartNodesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(16, numElems, 8); }
-  public static void AddBuffers(FlatBufferBuilder builder, VectorOffset buffersOffset) { builder.AddOffset(2, buffersOffset.Value, 0); }
-  public static void StartBuffersVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(16, numElems, 8); }
-  public static void AddCompression(FlatBufferBuilder builder, Offset<BodyCompression> compressionOffset) { builder.AddOffset(3, compressionOffset.Value, 0); }
-  public static void AddVariadicCounts(FlatBufferBuilder builder, VectorOffset variadicCountsOffset) { builder.AddOffset(4, variadicCountsOffset.Value, 0); }
-  public static VectorOffset CreateVariadicCountsVector(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddLong(data[i]); return builder.EndVector(); }
-  public static VectorOffset CreateVariadicCountsVectorBlock(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateVariadicCountsVectorBlock(FlatBufferBuilder builder, ArraySegment<long> data) { builder.StartVector(8, data.Count, 8); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateVariadicCountsVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<long>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartVariadicCountsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
-  public static Offset<RecordBatch> EndRecordBatch(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<RecordBatch>(o);
-  }
-}
-
-
-static internal class RecordBatchVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Length*/, 8 /*long*/, 8, false)
-      && verifier.VerifyVectorOfData(tablePos, 6 /*Nodes*/, 16 /*FieldNode*/, false)
-      && verifier.VerifyVectorOfData(tablePos, 8 /*Buffers*/, 16 /*Buffer*/, false)
-      && verifier.VerifyTable(tablePos, 10 /*Compression*/, BodyCompressionVerify.Verify, false)
-      && verifier.VerifyVectorOfData(tablePos, 12 /*VariadicCounts*/, 8 /*long*/, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/RunEndEncoded.cs b/csharp/src/Apache.Arrow/Flatbuf/RunEndEncoded.cs
deleted file mode 100644
index 78c602c..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/RunEndEncoded.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Contains two child arrays, run_ends and values.
-/// The run_ends child array must be a 16/32/64-bit integer array
-/// which encodes the indices at which the run with the value in 
-/// each corresponding index in the values child array ends.
-/// Like list/struct types, the value array can be of any type.
-internal struct RunEndEncoded : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static RunEndEncoded GetRootAsRunEndEncoded(ByteBuffer _bb) { return GetRootAsRunEndEncoded(_bb, new RunEndEncoded()); }
-  public static RunEndEncoded GetRootAsRunEndEncoded(ByteBuffer _bb, RunEndEncoded obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public RunEndEncoded __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartRunEndEncoded(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<RunEndEncoded> EndRunEndEncoded(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<RunEndEncoded>(o);
-  }
-}
-
-
-static internal class RunEndEncodedVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Schema.cs b/csharp/src/Apache.Arrow/Flatbuf/Schema.cs
deleted file mode 100644
index 1d7b3f4..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Schema.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// ----------------------------------------------------------------------
-/// A Schema describes the columns in a row batch
-internal struct Schema : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Schema GetRootAsSchema(ByteBuffer _bb) { return GetRootAsSchema(_bb, new Schema()); }
-  public static Schema GetRootAsSchema(ByteBuffer _bb, Schema obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public static bool VerifySchema(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("", false, SchemaVerify.Verify); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Schema __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// endianness of the buffer
-  /// it is Little Endian by default
-  /// if endianness doesn't match the underlying system then the vectors need to be converted
-  public Endianness Endianness { get { int o = __p.__offset(4); return o != 0 ? (Endianness)__p.bb.GetShort(o + __p.bb_pos) : Endianness.Little; } }
-  public Field? Fields(int j) { int o = __p.__offset(6); return o != 0 ? (Field?)(new Field()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
-  public int FieldsLength { get { int o = __p.__offset(6); return o != 0 ? __p.__vector_len(o) : 0; } }
-  public KeyValue? CustomMetadata(int j) { int o = __p.__offset(8); return o != 0 ? (KeyValue?)(new KeyValue()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
-  public int CustomMetadataLength { get { int o = __p.__offset(8); return o != 0 ? __p.__vector_len(o) : 0; } }
-  /// Features used in the stream/file.
-  public Feature Features(int j) { int o = __p.__offset(10); return o != 0 ? (Feature)__p.bb.GetLong(__p.__vector(o) + j * 8) : (Feature)0; }
-  public int FeaturesLength { get { int o = __p.__offset(10); return o != 0 ? __p.__vector_len(o) : 0; } }
-#if ENABLE_SPAN_T
-  public Span<Feature> GetFeaturesBytes() { return __p.__vector_as_span<Feature>(10, 8); }
-#else
-  public ArraySegment<byte>? GetFeaturesBytes() { return __p.__vector_as_arraysegment(10); }
-#endif
-  public Feature[] GetFeaturesArray() { int o = __p.__offset(10); if (o == 0) return null; int p = __p.__vector(o); int l = __p.__vector_len(o); Feature[] a = new Feature[l]; for (int i = 0; i < l; i++) { a[i] = (Feature)__p.bb.GetLong(p + i * 8); } return a; }
-
-  public static Offset<Schema> CreateSchema(FlatBufferBuilder builder,
-      Endianness endianness = Endianness.Little,
-      VectorOffset fieldsOffset = default(VectorOffset),
-      VectorOffset custom_metadataOffset = default(VectorOffset),
-      VectorOffset featuresOffset = default(VectorOffset)) {
-    builder.StartTable(4);
-    Schema.AddFeatures(builder, featuresOffset);
-    Schema.AddCustomMetadata(builder, custom_metadataOffset);
-    Schema.AddFields(builder, fieldsOffset);
-    Schema.AddEndianness(builder, endianness);
-    return Schema.EndSchema(builder);
-  }
-
-  public static void StartSchema(FlatBufferBuilder builder) { builder.StartTable(4); }
-  public static void AddEndianness(FlatBufferBuilder builder, Endianness endianness) { builder.AddShort(0, (short)endianness, 0); }
-  public static void AddFields(FlatBufferBuilder builder, VectorOffset fieldsOffset) { builder.AddOffset(1, fieldsOffset.Value, 0); }
-  public static VectorOffset CreateFieldsVector(FlatBufferBuilder builder, Offset<Field>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
-  public static VectorOffset CreateFieldsVectorBlock(FlatBufferBuilder builder, Offset<Field>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateFieldsVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<Field>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateFieldsVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<Field>>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartFieldsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
-  public static void AddCustomMetadata(FlatBufferBuilder builder, VectorOffset customMetadataOffset) { builder.AddOffset(2, customMetadataOffset.Value, 0); }
-  public static VectorOffset CreateCustomMetadataVector(FlatBufferBuilder builder, Offset<KeyValue>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, Offset<KeyValue>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<KeyValue>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateCustomMetadataVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<KeyValue>>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartCustomMetadataVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
-  public static void AddFeatures(FlatBufferBuilder builder, VectorOffset featuresOffset) { builder.AddOffset(3, featuresOffset.Value, 0); }
-  public static VectorOffset CreateFeaturesVector(FlatBufferBuilder builder, Feature[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddLong((long)data[i]); return builder.EndVector(); }
-  public static VectorOffset CreateFeaturesVectorBlock(FlatBufferBuilder builder, Feature[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateFeaturesVectorBlock(FlatBufferBuilder builder, ArraySegment<Feature> data) { builder.StartVector(8, data.Count, 8); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateFeaturesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Feature>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartFeaturesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
-  public static Offset<Schema> EndSchema(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Schema>(o);
-  }
-  public static void FinishSchemaBuffer(FlatBufferBuilder builder, Offset<Schema> offset) { builder.Finish(offset.Value); }
-  public static void FinishSizePrefixedSchemaBuffer(FlatBufferBuilder builder, Offset<Schema> offset) { builder.FinishSizePrefixed(offset.Value); }
-}
-
-
-static internal class SchemaVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Endianness*/, 2 /*Endianness*/, 2, false)
-      && verifier.VerifyVectorOfTables(tablePos, 6 /*Fields*/, FieldVerify.Verify, false)
-      && verifier.VerifyVectorOfTables(tablePos, 8 /*CustomMetadata*/, KeyValueVerify.Verify, false)
-      && verifier.VerifyVectorOfData(tablePos, 10 /*Features*/, 8 /*Feature*/, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/SparseMatrixCompressedAxis.cs b/csharp/src/Apache.Arrow/Flatbuf/SparseMatrixCompressedAxis.cs
deleted file mode 100644
index 67bf992..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/SparseMatrixCompressedAxis.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-internal enum SparseMatrixCompressedAxis : short
-{
-  Row = 0,
-  Column = 1,
-};
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/SparseMatrixIndexCSX.cs b/csharp/src/Apache.Arrow/Flatbuf/SparseMatrixIndexCSX.cs
deleted file mode 100644
index feea620..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/SparseMatrixIndexCSX.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Compressed Sparse format, that is matrix-specific.
-internal struct SparseMatrixIndexCSX : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static SparseMatrixIndexCSX GetRootAsSparseMatrixIndexCSX(ByteBuffer _bb) { return GetRootAsSparseMatrixIndexCSX(_bb, new SparseMatrixIndexCSX()); }
-  public static SparseMatrixIndexCSX GetRootAsSparseMatrixIndexCSX(ByteBuffer _bb, SparseMatrixIndexCSX obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public SparseMatrixIndexCSX __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// Which axis, row or column, is compressed
-  public SparseMatrixCompressedAxis CompressedAxis { get { int o = __p.__offset(4); return o != 0 ? (SparseMatrixCompressedAxis)__p.bb.GetShort(o + __p.bb_pos) : SparseMatrixCompressedAxis.Row; } }
-  /// The type of values in indptrBuffer
-  public Int? IndptrType { get { int o = __p.__offset(6); return o != 0 ? (Int?)(new Int()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
-  /// indptrBuffer stores the location and size of indptr array that
-  /// represents the range of the rows.
-  /// The i-th row spans from `indptr[i]` to `indptr[i+1]` in the data.
-  /// The length of this array is 1 + (the number of rows), and the type
-  /// of index value is long.
-  ///
-  /// For example, let X be the following 6x4 matrix:
-  /// ```text
-  ///   X := [[0, 1, 2, 0],
-  ///         [0, 0, 3, 0],
-  ///         [0, 4, 0, 5],
-  ///         [0, 0, 0, 0],
-  ///         [6, 0, 7, 8],
-  ///         [0, 9, 0, 0]].
-  /// ```
-  /// The array of non-zero values in X is:
-  /// ```text
-  ///   values(X) = [1, 2, 3, 4, 5, 6, 7, 8, 9].
-  /// ```
-  /// And the indptr of X is:
-  /// ```text
-  ///   indptr(X) = [0, 2, 3, 5, 5, 8, 10].
-  /// ```
-  public Buffer? IndptrBuffer { get { int o = __p.__offset(8); return o != 0 ? (Buffer?)(new Buffer()).__assign(o + __p.bb_pos, __p.bb) : null; } }
-  /// The type of values in indicesBuffer
-  public Int? IndicesType { get { int o = __p.__offset(10); return o != 0 ? (Int?)(new Int()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
-  /// indicesBuffer stores the location and size of the array that
-  /// contains the column indices of the corresponding non-zero values.
-  /// The type of index value is long.
-  ///
-  /// For example, the indices of the above X is:
-  /// ```text
-  ///   indices(X) = [1, 2, 2, 1, 3, 0, 2, 3, 1].
-  /// ```
-  /// Note that the indices are sorted in lexicographical order for each row.
-  public Buffer? IndicesBuffer { get { int o = __p.__offset(12); return o != 0 ? (Buffer?)(new Buffer()).__assign(o + __p.bb_pos, __p.bb) : null; } }
-
-  public static void StartSparseMatrixIndexCSX(FlatBufferBuilder builder) { builder.StartTable(5); }
-  public static void AddCompressedAxis(FlatBufferBuilder builder, SparseMatrixCompressedAxis compressedAxis) { builder.AddShort(0, (short)compressedAxis, 0); }
-  public static void AddIndptrType(FlatBufferBuilder builder, Offset<Int> indptrTypeOffset) { builder.AddOffset(1, indptrTypeOffset.Value, 0); }
-  public static void AddIndptrBuffer(FlatBufferBuilder builder, Offset<Buffer> indptrBufferOffset) { builder.AddStruct(2, indptrBufferOffset.Value, 0); }
-  public static void AddIndicesType(FlatBufferBuilder builder, Offset<Int> indicesTypeOffset) { builder.AddOffset(3, indicesTypeOffset.Value, 0); }
-  public static void AddIndicesBuffer(FlatBufferBuilder builder, Offset<Buffer> indicesBufferOffset) { builder.AddStruct(4, indicesBufferOffset.Value, 0); }
-  public static Offset<SparseMatrixIndexCSX> EndSparseMatrixIndexCSX(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    builder.Required(o, 6);  // indptrType
-    builder.Required(o, 8);  // indptrBuffer
-    builder.Required(o, 10);  // indicesType
-    builder.Required(o, 12);  // indicesBuffer
-    return new Offset<SparseMatrixIndexCSX>(o);
-  }
-}
-
-
-static internal class SparseMatrixIndexCSXVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*CompressedAxis*/, 2 /*SparseMatrixCompressedAxis*/, 2, false)
-      && verifier.VerifyTable(tablePos, 6 /*IndptrType*/, IntVerify.Verify, true)
-      && verifier.VerifyField(tablePos, 8 /*IndptrBuffer*/, 16 /*Buffer*/, 8, true)
-      && verifier.VerifyTable(tablePos, 10 /*IndicesType*/, IntVerify.Verify, true)
-      && verifier.VerifyField(tablePos, 12 /*IndicesBuffer*/, 16 /*Buffer*/, 8, true)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/SparseTensor.cs b/csharp/src/Apache.Arrow/Flatbuf/SparseTensor.cs
deleted file mode 100644
index 099950f..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/SparseTensor.cs
+++ /dev/null
@@ -1,110 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct SparseTensor : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static SparseTensor GetRootAsSparseTensor(ByteBuffer _bb) { return GetRootAsSparseTensor(_bb, new SparseTensor()); }
-  public static SparseTensor GetRootAsSparseTensor(ByteBuffer _bb, SparseTensor obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public static bool VerifySparseTensor(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("", false, SparseTensorVerify.Verify); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public SparseTensor __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public Type TypeType { get { int o = __p.__offset(4); return o != 0 ? (Type)__p.bb.Get(o + __p.bb_pos) : Apache.Arrow.Flatbuf.Type.NONE; } }
-  /// The type of data contained in a value cell.
-  /// Currently only fixed-width value types are supported,
-  /// no strings or nested types.
-  public TTable? Type<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(6); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
-  public Null TypeAsNull() { return Type<Null>().Value; }
-  public Int TypeAsInt() { return Type<Int>().Value; }
-  public FloatingPoint TypeAsFloatingPoint() { return Type<FloatingPoint>().Value; }
-  public Binary TypeAsBinary() { return Type<Binary>().Value; }
-  public Utf8 TypeAsUtf8() { return Type<Utf8>().Value; }
-  public Bool TypeAsBool() { return Type<Bool>().Value; }
-  public Decimal TypeAsDecimal() { return Type<Decimal>().Value; }
-  public Date TypeAsDate() { return Type<Date>().Value; }
-  public Time TypeAsTime() { return Type<Time>().Value; }
-  public Timestamp TypeAsTimestamp() { return Type<Timestamp>().Value; }
-  public Interval TypeAsInterval() { return Type<Interval>().Value; }
-  public List TypeAsList() { return Type<List>().Value; }
-  public Struct_ TypeAsStruct_() { return Type<Struct_>().Value; }
-  public Union TypeAsUnion() { return Type<Union>().Value; }
-  public FixedSizeBinary TypeAsFixedSizeBinary() { return Type<FixedSizeBinary>().Value; }
-  public FixedSizeList TypeAsFixedSizeList() { return Type<FixedSizeList>().Value; }
-  public Map TypeAsMap() { return Type<Map>().Value; }
-  public Duration TypeAsDuration() { return Type<Duration>().Value; }
-  public LargeBinary TypeAsLargeBinary() { return Type<LargeBinary>().Value; }
-  public LargeUtf8 TypeAsLargeUtf8() { return Type<LargeUtf8>().Value; }
-  public LargeList TypeAsLargeList() { return Type<LargeList>().Value; }
-  public RunEndEncoded TypeAsRunEndEncoded() { return Type<RunEndEncoded>().Value; }
-  public BinaryView TypeAsBinaryView() { return Type<BinaryView>().Value; }
-  public Utf8View TypeAsUtf8View() { return Type<Utf8View>().Value; }
-  public ListView TypeAsListView() { return Type<ListView>().Value; }
-  public LargeListView TypeAsLargeListView() { return Type<LargeListView>().Value; }
-  /// The dimensions of the tensor, optionally named.
-  public TensorDim? Shape(int j) { int o = __p.__offset(8); return o != 0 ? (TensorDim?)(new TensorDim()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
-  public int ShapeLength { get { int o = __p.__offset(8); return o != 0 ? __p.__vector_len(o) : 0; } }
-  /// The number of non-zero values in a sparse tensor.
-  public long NonZeroLength { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
-  public SparseTensorIndex SparseIndexType { get { int o = __p.__offset(12); return o != 0 ? (SparseTensorIndex)__p.bb.Get(o + __p.bb_pos) : SparseTensorIndex.NONE; } }
-  /// Sparse tensor index
-  public TTable? SparseIndex<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(14); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
-  public SparseTensorIndexCOO SparseIndexAsSparseTensorIndexCOO() { return SparseIndex<SparseTensorIndexCOO>().Value; }
-  public SparseMatrixIndexCSX SparseIndexAsSparseMatrixIndexCSX() { return SparseIndex<SparseMatrixIndexCSX>().Value; }
-  public SparseTensorIndexCSF SparseIndexAsSparseTensorIndexCSF() { return SparseIndex<SparseTensorIndexCSF>().Value; }
-  /// The location and size of the tensor's data
-  public Buffer? Data { get { int o = __p.__offset(16); return o != 0 ? (Buffer?)(new Buffer()).__assign(o + __p.bb_pos, __p.bb) : null; } }
-
-  public static void StartSparseTensor(FlatBufferBuilder builder) { builder.StartTable(7); }
-  public static void AddTypeType(FlatBufferBuilder builder, Type typeType) { builder.AddByte(0, (byte)typeType, 0); }
-  public static void AddType(FlatBufferBuilder builder, int typeOffset) { builder.AddOffset(1, typeOffset, 0); }
-  public static void AddShape(FlatBufferBuilder builder, VectorOffset shapeOffset) { builder.AddOffset(2, shapeOffset.Value, 0); }
-  public static VectorOffset CreateShapeVector(FlatBufferBuilder builder, Offset<TensorDim>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
-  public static VectorOffset CreateShapeVectorBlock(FlatBufferBuilder builder, Offset<TensorDim>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateShapeVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<TensorDim>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateShapeVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<TensorDim>>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartShapeVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
-  public static void AddNonZeroLength(FlatBufferBuilder builder, long nonZeroLength) { builder.AddLong(3, nonZeroLength, 0); }
-  public static void AddSparseIndexType(FlatBufferBuilder builder, SparseTensorIndex sparseIndexType) { builder.AddByte(4, (byte)sparseIndexType, 0); }
-  public static void AddSparseIndex(FlatBufferBuilder builder, int sparseIndexOffset) { builder.AddOffset(5, sparseIndexOffset, 0); }
-  public static void AddData(FlatBufferBuilder builder, Offset<Buffer> dataOffset) { builder.AddStruct(6, dataOffset.Value, 0); }
-  public static Offset<SparseTensor> EndSparseTensor(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    builder.Required(o, 6);  // type
-    builder.Required(o, 8);  // shape
-    builder.Required(o, 14);  // sparseIndex
-    builder.Required(o, 16);  // data
-    return new Offset<SparseTensor>(o);
-  }
-  public static void FinishSparseTensorBuffer(FlatBufferBuilder builder, Offset<SparseTensor> offset) { builder.Finish(offset.Value); }
-  public static void FinishSizePrefixedSparseTensorBuffer(FlatBufferBuilder builder, Offset<SparseTensor> offset) { builder.FinishSizePrefixed(offset.Value); }
-}
-
-
-static internal class SparseTensorVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*TypeType*/, 1 /*Type*/, 1, false)
-      && verifier.VerifyUnion(tablePos, 4, 6 /*Type*/, TypeVerify.Verify, true)
-      && verifier.VerifyVectorOfTables(tablePos, 8 /*Shape*/, TensorDimVerify.Verify, true)
-      && verifier.VerifyField(tablePos, 10 /*NonZeroLength*/, 8 /*long*/, 8, false)
-      && verifier.VerifyField(tablePos, 12 /*SparseIndexType*/, 1 /*SparseTensorIndex*/, 1, false)
-      && verifier.VerifyUnion(tablePos, 12, 14 /*SparseIndex*/, SparseTensorIndexVerify.Verify, true)
-      && verifier.VerifyField(tablePos, 16 /*Data*/, 16 /*Buffer*/, 8, true)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/SparseTensorIndex.cs b/csharp/src/Apache.Arrow/Flatbuf/SparseTensorIndex.cs
deleted file mode 100644
index 16bfb2d..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/SparseTensorIndex.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-internal enum SparseTensorIndex : byte
-{
-  NONE = 0,
-  SparseTensorIndexCOO = 1,
-  SparseMatrixIndexCSX = 2,
-  SparseTensorIndexCSF = 3,
-};
-
-
-
-static internal class SparseTensorIndexVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
-  {
-    bool result = true;
-    switch((SparseTensorIndex)typeId)
-    {
-      case SparseTensorIndex.SparseTensorIndexCOO:
-        result = SparseTensorIndexCOOVerify.Verify(verifier, tablePos);
-        break;
-      case SparseTensorIndex.SparseMatrixIndexCSX:
-        result = SparseMatrixIndexCSXVerify.Verify(verifier, tablePos);
-        break;
-      case SparseTensorIndex.SparseTensorIndexCSF:
-        result = SparseTensorIndexCSFVerify.Verify(verifier, tablePos);
-        break;
-      default: result = true;
-        break;
-    }
-    return result;
-  }
-}
-
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/SparseTensorIndexCOO.cs b/csharp/src/Apache.Arrow/Flatbuf/SparseTensorIndexCOO.cs
deleted file mode 100644
index f0cdae2..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/SparseTensorIndexCOO.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// ----------------------------------------------------------------------
-/// EXPERIMENTAL: Data structures for sparse tensors
-/// Coordinate (COO) format of sparse tensor index.
-///
-/// COO's index list are represented as a NxM matrix,
-/// where N is the number of non-zero values,
-/// and M is the number of dimensions of a sparse tensor.
-///
-/// indicesBuffer stores the location and size of the data of this indices
-/// matrix.  The value type and the stride of the indices matrix is
-/// specified in indicesType and indicesStrides fields.
-///
-/// For example, let X be a 2x3x4x5 tensor, and it has the following
-/// 6 non-zero values:
-/// ```text
-///   X[0, 1, 2, 0] := 1
-///   X[1, 1, 2, 3] := 2
-///   X[0, 2, 1, 0] := 3
-///   X[0, 1, 3, 0] := 4
-///   X[0, 1, 2, 1] := 5
-///   X[1, 2, 0, 4] := 6
-/// ```
-/// In COO format, the index matrix of X is the following 4x6 matrix:
-/// ```text
-///   [[0, 0, 0, 0, 1, 1],
-///    [1, 1, 1, 2, 1, 2],
-///    [2, 2, 3, 1, 2, 0],
-///    [0, 1, 0, 0, 3, 4]]
-/// ```
-/// When isCanonical is true, the indices is sorted in lexicographical order
-/// (row-major order), and it does not have duplicated entries.  Otherwise,
-/// the indices may not be sorted, or may have duplicated entries.
-internal struct SparseTensorIndexCOO : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static SparseTensorIndexCOO GetRootAsSparseTensorIndexCOO(ByteBuffer _bb) { return GetRootAsSparseTensorIndexCOO(_bb, new SparseTensorIndexCOO()); }
-  public static SparseTensorIndexCOO GetRootAsSparseTensorIndexCOO(ByteBuffer _bb, SparseTensorIndexCOO obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public SparseTensorIndexCOO __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// The type of values in indicesBuffer
-  public Int? IndicesType { get { int o = __p.__offset(4); return o != 0 ? (Int?)(new Int()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
-  /// Non-negative byte offsets to advance one value cell along each dimension
-  /// If omitted, default to row-major order (C-like).
-  public long IndicesStrides(int j) { int o = __p.__offset(6); return o != 0 ? __p.bb.GetLong(__p.__vector(o) + j * 8) : (long)0; }
-  public int IndicesStridesLength { get { int o = __p.__offset(6); return o != 0 ? __p.__vector_len(o) : 0; } }
-#if ENABLE_SPAN_T
-  public Span<long> GetIndicesStridesBytes() { return __p.__vector_as_span<long>(6, 8); }
-#else
-  public ArraySegment<byte>? GetIndicesStridesBytes() { return __p.__vector_as_arraysegment(6); }
-#endif
-  public long[] GetIndicesStridesArray() { return __p.__vector_as_array<long>(6); }
-  /// The location and size of the indices matrix's data
-  public Buffer? IndicesBuffer { get { int o = __p.__offset(8); return o != 0 ? (Buffer?)(new Buffer()).__assign(o + __p.bb_pos, __p.bb) : null; } }
-  /// This flag is true if and only if the indices matrix is sorted in
-  /// row-major order, and does not have duplicated entries.
-  /// This sort order is the same as of Tensorflow's SparseTensor,
-  /// but it is inverse order of SciPy's canonical coo_matrix
-  /// (SciPy employs column-major order for its coo_matrix).
-  public bool IsCanonical { get { int o = __p.__offset(10); return o != 0 ? 0!=__p.bb.Get(o + __p.bb_pos) : (bool)false; } }
-
-  public static void StartSparseTensorIndexCOO(FlatBufferBuilder builder) { builder.StartTable(4); }
-  public static void AddIndicesType(FlatBufferBuilder builder, Offset<Int> indicesTypeOffset) { builder.AddOffset(0, indicesTypeOffset.Value, 0); }
-  public static void AddIndicesStrides(FlatBufferBuilder builder, VectorOffset indicesStridesOffset) { builder.AddOffset(1, indicesStridesOffset.Value, 0); }
-  public static VectorOffset CreateIndicesStridesVector(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddLong(data[i]); return builder.EndVector(); }
-  public static VectorOffset CreateIndicesStridesVectorBlock(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateIndicesStridesVectorBlock(FlatBufferBuilder builder, ArraySegment<long> data) { builder.StartVector(8, data.Count, 8); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateIndicesStridesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<long>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartIndicesStridesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
-  public static void AddIndicesBuffer(FlatBufferBuilder builder, Offset<Buffer> indicesBufferOffset) { builder.AddStruct(2, indicesBufferOffset.Value, 0); }
-  public static void AddIsCanonical(FlatBufferBuilder builder, bool isCanonical) { builder.AddBool(3, isCanonical, false); }
-  public static Offset<SparseTensorIndexCOO> EndSparseTensorIndexCOO(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    builder.Required(o, 4);  // indicesType
-    builder.Required(o, 8);  // indicesBuffer
-    return new Offset<SparseTensorIndexCOO>(o);
-  }
-}
-
-
-static internal class SparseTensorIndexCOOVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTable(tablePos, 4 /*IndicesType*/, IntVerify.Verify, true)
-      && verifier.VerifyVectorOfData(tablePos, 6 /*IndicesStrides*/, 8 /*long*/, false)
-      && verifier.VerifyField(tablePos, 8 /*IndicesBuffer*/, 16 /*Buffer*/, 8, true)
-      && verifier.VerifyField(tablePos, 10 /*IsCanonical*/, 1 /*bool*/, 1, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/SparseTensorIndexCSF.cs b/csharp/src/Apache.Arrow/Flatbuf/SparseTensorIndexCSF.cs
deleted file mode 100644
index 1ca54ed..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/SparseTensorIndexCSF.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Compressed Sparse Fiber (CSF) sparse tensor index.
-internal struct SparseTensorIndexCSF : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static SparseTensorIndexCSF GetRootAsSparseTensorIndexCSF(ByteBuffer _bb) { return GetRootAsSparseTensorIndexCSF(_bb, new SparseTensorIndexCSF()); }
-  public static SparseTensorIndexCSF GetRootAsSparseTensorIndexCSF(ByteBuffer _bb, SparseTensorIndexCSF obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public SparseTensorIndexCSF __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// CSF is a generalization of compressed sparse row (CSR) index.
-  /// See [smith2017knl](http://shaden.io/pub-files/smith2017knl.pdf)
-  ///
-  /// CSF index recursively compresses each dimension of a tensor into a set
-  /// of prefix trees. Each path from a root to leaf forms one tensor
-  /// non-zero index. CSF is implemented with two arrays of buffers and one
-  /// arrays of integers.
-  ///
-  /// For example, let X be a 2x3x4x5 tensor and let it have the following
-  /// 8 non-zero values:
-  /// ```text
-  ///   X[0, 0, 0, 1] := 1
-  ///   X[0, 0, 0, 2] := 2
-  ///   X[0, 1, 0, 0] := 3
-  ///   X[0, 1, 0, 2] := 4
-  ///   X[0, 1, 1, 0] := 5
-  ///   X[1, 1, 1, 0] := 6
-  ///   X[1, 1, 1, 1] := 7
-  ///   X[1, 1, 1, 2] := 8
-  /// ```
-  /// As a prefix tree this would be represented as:
-  /// ```text
-  ///         0          1
-  ///        / \         |
-  ///       0   1        1
-  ///      /   / \       |
-  ///     0   0   1      1
-  ///    /|  /|   |    /| |
-  ///   1 2 0 2   0   0 1 2
-  /// ```
-  /// The type of values in indptrBuffers
-  public Int? IndptrType { get { int o = __p.__offset(4); return o != 0 ? (Int?)(new Int()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
-  /// indptrBuffers stores the sparsity structure.
-  /// Each two consecutive dimensions in a tensor correspond to a buffer in
-  /// indptrBuffers. A pair of consecutive values at `indptrBuffers[dim][i]`
-  /// and `indptrBuffers[dim][i + 1]` signify a range of nodes in
-  /// `indicesBuffers[dim + 1]` who are children of `indicesBuffers[dim][i]` node.
-  ///
-  /// For example, the indptrBuffers for the above X is:
-  /// ```text
-  ///   indptrBuffer(X) = [
-  ///                       [0, 2, 3],
-  ///                       [0, 1, 3, 4],
-  ///                       [0, 2, 4, 5, 8]
-  ///                     ].
-  /// ```
-  public Buffer? IndptrBuffers(int j) { int o = __p.__offset(6); return o != 0 ? (Buffer?)(new Buffer()).__assign(__p.__vector(o) + j * 16, __p.bb) : null; }
-  public int IndptrBuffersLength { get { int o = __p.__offset(6); return o != 0 ? __p.__vector_len(o) : 0; } }
-  /// The type of values in indicesBuffers
-  public Int? IndicesType { get { int o = __p.__offset(8); return o != 0 ? (Int?)(new Int()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
-  /// indicesBuffers stores values of nodes.
-  /// Each tensor dimension corresponds to a buffer in indicesBuffers.
-  /// For example, the indicesBuffers for the above X is:
-  /// ```text
-  ///   indicesBuffer(X) = [
-  ///                        [0, 1],
-  ///                        [0, 1, 1],
-  ///                        [0, 0, 1, 1],
-  ///                        [1, 2, 0, 2, 0, 0, 1, 2]
-  ///                      ].
-  /// ```
-  public Buffer? IndicesBuffers(int j) { int o = __p.__offset(10); return o != 0 ? (Buffer?)(new Buffer()).__assign(__p.__vector(o) + j * 16, __p.bb) : null; }
-  public int IndicesBuffersLength { get { int o = __p.__offset(10); return o != 0 ? __p.__vector_len(o) : 0; } }
-  /// axisOrder stores the sequence in which dimensions were traversed to
-  /// produce the prefix tree.
-  /// For example, the axisOrder for the above X is:
-  /// ```text
-  ///   axisOrder(X) = [0, 1, 2, 3].
-  /// ```
-  public int AxisOrder(int j) { int o = __p.__offset(12); return o != 0 ? __p.bb.GetInt(__p.__vector(o) + j * 4) : (int)0; }
-  public int AxisOrderLength { get { int o = __p.__offset(12); return o != 0 ? __p.__vector_len(o) : 0; } }
-#if ENABLE_SPAN_T
-  public Span<int> GetAxisOrderBytes() { return __p.__vector_as_span<int>(12, 4); }
-#else
-  public ArraySegment<byte>? GetAxisOrderBytes() { return __p.__vector_as_arraysegment(12); }
-#endif
-  public int[] GetAxisOrderArray() { return __p.__vector_as_array<int>(12); }
-
-  public static Offset<SparseTensorIndexCSF> CreateSparseTensorIndexCSF(FlatBufferBuilder builder,
-      Offset<Int> indptrTypeOffset = default(Offset<Int>),
-      VectorOffset indptrBuffersOffset = default(VectorOffset),
-      Offset<Int> indicesTypeOffset = default(Offset<Int>),
-      VectorOffset indicesBuffersOffset = default(VectorOffset),
-      VectorOffset axisOrderOffset = default(VectorOffset)) {
-    builder.StartTable(5);
-    SparseTensorIndexCSF.AddAxisOrder(builder, axisOrderOffset);
-    SparseTensorIndexCSF.AddIndicesBuffers(builder, indicesBuffersOffset);
-    SparseTensorIndexCSF.AddIndicesType(builder, indicesTypeOffset);
-    SparseTensorIndexCSF.AddIndptrBuffers(builder, indptrBuffersOffset);
-    SparseTensorIndexCSF.AddIndptrType(builder, indptrTypeOffset);
-    return SparseTensorIndexCSF.EndSparseTensorIndexCSF(builder);
-  }
-
-  public static void StartSparseTensorIndexCSF(FlatBufferBuilder builder) { builder.StartTable(5); }
-  public static void AddIndptrType(FlatBufferBuilder builder, Offset<Int> indptrTypeOffset) { builder.AddOffset(0, indptrTypeOffset.Value, 0); }
-  public static void AddIndptrBuffers(FlatBufferBuilder builder, VectorOffset indptrBuffersOffset) { builder.AddOffset(1, indptrBuffersOffset.Value, 0); }
-  public static void StartIndptrBuffersVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(16, numElems, 8); }
-  public static void AddIndicesType(FlatBufferBuilder builder, Offset<Int> indicesTypeOffset) { builder.AddOffset(2, indicesTypeOffset.Value, 0); }
-  public static void AddIndicesBuffers(FlatBufferBuilder builder, VectorOffset indicesBuffersOffset) { builder.AddOffset(3, indicesBuffersOffset.Value, 0); }
-  public static void StartIndicesBuffersVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(16, numElems, 8); }
-  public static void AddAxisOrder(FlatBufferBuilder builder, VectorOffset axisOrderOffset) { builder.AddOffset(4, axisOrderOffset.Value, 0); }
-  public static VectorOffset CreateAxisOrderVector(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddInt(data[i]); return builder.EndVector(); }
-  public static VectorOffset CreateAxisOrderVectorBlock(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateAxisOrderVectorBlock(FlatBufferBuilder builder, ArraySegment<int> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateAxisOrderVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<int>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartAxisOrderVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
-  public static Offset<SparseTensorIndexCSF> EndSparseTensorIndexCSF(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    builder.Required(o, 4);  // indptrType
-    builder.Required(o, 6);  // indptrBuffers
-    builder.Required(o, 8);  // indicesType
-    builder.Required(o, 10);  // indicesBuffers
-    builder.Required(o, 12);  // axisOrder
-    return new Offset<SparseTensorIndexCSF>(o);
-  }
-}
-
-
-static internal class SparseTensorIndexCSFVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTable(tablePos, 4 /*IndptrType*/, IntVerify.Verify, true)
-      && verifier.VerifyVectorOfData(tablePos, 6 /*IndptrBuffers*/, 16 /*Buffer*/, true)
-      && verifier.VerifyTable(tablePos, 8 /*IndicesType*/, IntVerify.Verify, true)
-      && verifier.VerifyVectorOfData(tablePos, 10 /*IndicesBuffers*/, 16 /*Buffer*/, true)
-      && verifier.VerifyVectorOfData(tablePos, 12 /*AxisOrder*/, 4 /*int*/, true)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Tensor.cs b/csharp/src/Apache.Arrow/Flatbuf/Tensor.cs
deleted file mode 100644
index eb39257..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Tensor.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct Tensor : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Tensor GetRootAsTensor(ByteBuffer _bb) { return GetRootAsTensor(_bb, new Tensor()); }
-  public static Tensor GetRootAsTensor(ByteBuffer _bb, Tensor obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public static bool VerifyTensor(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("", false, TensorVerify.Verify); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Tensor __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public Type TypeType { get { int o = __p.__offset(4); return o != 0 ? (Type)__p.bb.Get(o + __p.bb_pos) : Apache.Arrow.Flatbuf.Type.NONE; } }
-  /// The type of data contained in a value cell. Currently only fixed-width
-  /// value types are supported, no strings or nested types
-  public TTable? Type<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(6); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
-  public Null TypeAsNull() { return Type<Null>().Value; }
-  public Int TypeAsInt() { return Type<Int>().Value; }
-  public FloatingPoint TypeAsFloatingPoint() { return Type<FloatingPoint>().Value; }
-  public Binary TypeAsBinary() { return Type<Binary>().Value; }
-  public Utf8 TypeAsUtf8() { return Type<Utf8>().Value; }
-  public Bool TypeAsBool() { return Type<Bool>().Value; }
-  public Decimal TypeAsDecimal() { return Type<Decimal>().Value; }
-  public Date TypeAsDate() { return Type<Date>().Value; }
-  public Time TypeAsTime() { return Type<Time>().Value; }
-  public Timestamp TypeAsTimestamp() { return Type<Timestamp>().Value; }
-  public Interval TypeAsInterval() { return Type<Interval>().Value; }
-  public List TypeAsList() { return Type<List>().Value; }
-  public Struct_ TypeAsStruct_() { return Type<Struct_>().Value; }
-  public Union TypeAsUnion() { return Type<Union>().Value; }
-  public FixedSizeBinary TypeAsFixedSizeBinary() { return Type<FixedSizeBinary>().Value; }
-  public FixedSizeList TypeAsFixedSizeList() { return Type<FixedSizeList>().Value; }
-  public Map TypeAsMap() { return Type<Map>().Value; }
-  public Duration TypeAsDuration() { return Type<Duration>().Value; }
-  public LargeBinary TypeAsLargeBinary() { return Type<LargeBinary>().Value; }
-  public LargeUtf8 TypeAsLargeUtf8() { return Type<LargeUtf8>().Value; }
-  public LargeList TypeAsLargeList() { return Type<LargeList>().Value; }
-  public RunEndEncoded TypeAsRunEndEncoded() { return Type<RunEndEncoded>().Value; }
-  public BinaryView TypeAsBinaryView() { return Type<BinaryView>().Value; }
-  public Utf8View TypeAsUtf8View() { return Type<Utf8View>().Value; }
-  public ListView TypeAsListView() { return Type<ListView>().Value; }
-  public LargeListView TypeAsLargeListView() { return Type<LargeListView>().Value; }
-  /// The dimensions of the tensor, optionally named
-  public TensorDim? Shape(int j) { int o = __p.__offset(8); return o != 0 ? (TensorDim?)(new TensorDim()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
-  public int ShapeLength { get { int o = __p.__offset(8); return o != 0 ? __p.__vector_len(o) : 0; } }
-  /// Non-negative byte offsets to advance one value cell along each dimension
-  /// If omitted, default to row-major order (C-like).
-  public long Strides(int j) { int o = __p.__offset(10); return o != 0 ? __p.bb.GetLong(__p.__vector(o) + j * 8) : (long)0; }
-  public int StridesLength { get { int o = __p.__offset(10); return o != 0 ? __p.__vector_len(o) : 0; } }
-#if ENABLE_SPAN_T
-  public Span<long> GetStridesBytes() { return __p.__vector_as_span<long>(10, 8); }
-#else
-  public ArraySegment<byte>? GetStridesBytes() { return __p.__vector_as_arraysegment(10); }
-#endif
-  public long[] GetStridesArray() { return __p.__vector_as_array<long>(10); }
-  /// The location and size of the tensor's data
-  public Buffer? Data { get { int o = __p.__offset(12); return o != 0 ? (Buffer?)(new Buffer()).__assign(o + __p.bb_pos, __p.bb) : null; } }
-
-  public static void StartTensor(FlatBufferBuilder builder) { builder.StartTable(5); }
-  public static void AddTypeType(FlatBufferBuilder builder, Type typeType) { builder.AddByte(0, (byte)typeType, 0); }
-  public static void AddType(FlatBufferBuilder builder, int typeOffset) { builder.AddOffset(1, typeOffset, 0); }
-  public static void AddShape(FlatBufferBuilder builder, VectorOffset shapeOffset) { builder.AddOffset(2, shapeOffset.Value, 0); }
-  public static VectorOffset CreateShapeVector(FlatBufferBuilder builder, Offset<TensorDim>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
-  public static VectorOffset CreateShapeVectorBlock(FlatBufferBuilder builder, Offset<TensorDim>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateShapeVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<TensorDim>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateShapeVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<TensorDim>>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartShapeVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
-  public static void AddStrides(FlatBufferBuilder builder, VectorOffset stridesOffset) { builder.AddOffset(3, stridesOffset.Value, 0); }
-  public static VectorOffset CreateStridesVector(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddLong(data[i]); return builder.EndVector(); }
-  public static VectorOffset CreateStridesVectorBlock(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateStridesVectorBlock(FlatBufferBuilder builder, ArraySegment<long> data) { builder.StartVector(8, data.Count, 8); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateStridesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<long>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartStridesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
-  public static void AddData(FlatBufferBuilder builder, Offset<Buffer> dataOffset) { builder.AddStruct(4, dataOffset.Value, 0); }
-  public static Offset<Tensor> EndTensor(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    builder.Required(o, 6);  // type
-    builder.Required(o, 8);  // shape
-    builder.Required(o, 12);  // data
-    return new Offset<Tensor>(o);
-  }
-  public static void FinishTensorBuffer(FlatBufferBuilder builder, Offset<Tensor> offset) { builder.Finish(offset.Value); }
-  public static void FinishSizePrefixedTensorBuffer(FlatBufferBuilder builder, Offset<Tensor> offset) { builder.FinishSizePrefixed(offset.Value); }
-}
-
-
-static internal class TensorVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*TypeType*/, 1 /*Type*/, 1, false)
-      && verifier.VerifyUnion(tablePos, 4, 6 /*Type*/, TypeVerify.Verify, true)
-      && verifier.VerifyVectorOfTables(tablePos, 8 /*Shape*/, TensorDimVerify.Verify, true)
-      && verifier.VerifyVectorOfData(tablePos, 10 /*Strides*/, 8 /*long*/, false)
-      && verifier.VerifyField(tablePos, 12 /*Data*/, 16 /*Buffer*/, 8, true)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/TensorDim.cs b/csharp/src/Apache.Arrow/Flatbuf/TensorDim.cs
deleted file mode 100644
index 43d2ef5..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/TensorDim.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// ----------------------------------------------------------------------
-/// Data structures for dense tensors
-/// Shape data for a single axis in a tensor
-internal struct TensorDim : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static TensorDim GetRootAsTensorDim(ByteBuffer _bb) { return GetRootAsTensorDim(_bb, new TensorDim()); }
-  public static TensorDim GetRootAsTensorDim(ByteBuffer _bb, TensorDim obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public TensorDim __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// Length of dimension
-  public long Size { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
-  /// Name of the dimension, optional
-  public string Name { get { int o = __p.__offset(6); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
-#if ENABLE_SPAN_T
-  public Span<byte> GetNameBytes() { return __p.__vector_as_span<byte>(6, 1); }
-#else
-  public ArraySegment<byte>? GetNameBytes() { return __p.__vector_as_arraysegment(6); }
-#endif
-  public byte[] GetNameArray() { return __p.__vector_as_array<byte>(6); }
-
-  public static Offset<TensorDim> CreateTensorDim(FlatBufferBuilder builder,
-      long size = 0,
-      StringOffset nameOffset = default(StringOffset)) {
-    builder.StartTable(2);
-    TensorDim.AddSize(builder, size);
-    TensorDim.AddName(builder, nameOffset);
-    return TensorDim.EndTensorDim(builder);
-  }
-
-  public static void StartTensorDim(FlatBufferBuilder builder) { builder.StartTable(2); }
-  public static void AddSize(FlatBufferBuilder builder, long size) { builder.AddLong(0, size, 0); }
-  public static void AddName(FlatBufferBuilder builder, StringOffset nameOffset) { builder.AddOffset(1, nameOffset.Value, 0); }
-  public static Offset<TensorDim> EndTensorDim(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<TensorDim>(o);
-  }
-}
-
-
-static internal class TensorDimVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Size*/, 8 /*long*/, 8, false)
-      && verifier.VerifyString(tablePos, 6 /*Name*/, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Binary.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Binary.cs
deleted file mode 100644
index 1c7b334..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Binary.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Opaque binary data
-internal struct Binary : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Binary GetRootAsBinary(ByteBuffer _bb) { return GetRootAsBinary(_bb, new Binary()); }
-  public static Binary GetRootAsBinary(ByteBuffer _bb, Binary obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Binary __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartBinary(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<Binary> EndBinary(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Binary>(o);
-  }
-}
-
-
-static internal class BinaryVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Bool.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Bool.cs
deleted file mode 100644
index 529ce7d..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Bool.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct Bool : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Bool GetRootAsBool(ByteBuffer _bb) { return GetRootAsBool(_bb, new Bool()); }
-  public static Bool GetRootAsBool(ByteBuffer _bb, Bool obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Bool __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartBool(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<Bool> EndBool(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Bool>(o);
-  }
-}
-
-
-static internal class BoolVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Date.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Date.cs
deleted file mode 100644
index aef1db9..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Date.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Date is either a 32-bit or 64-bit signed integer type representing an
-/// elapsed time since UNIX epoch (1970-01-01), stored in either of two units:
-///
-/// * Milliseconds (64 bits) indicating UNIX time elapsed since the epoch (no
-///   leap seconds), where the values are evenly divisible by 86400000
-/// * Days (32 bits) since the UNIX epoch
-internal struct Date : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Date GetRootAsDate(ByteBuffer _bb) { return GetRootAsDate(_bb, new Date()); }
-  public static Date GetRootAsDate(ByteBuffer _bb, Date obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Date __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public DateUnit Unit { get { int o = __p.__offset(4); return o != 0 ? (DateUnit)__p.bb.GetShort(o + __p.bb_pos) : DateUnit.MILLISECOND; } }
-
-  public static Offset<Date> CreateDate(FlatBufferBuilder builder,
-      DateUnit unit = DateUnit.MILLISECOND) {
-    builder.StartTable(1);
-    Date.AddUnit(builder, unit);
-    return Date.EndDate(builder);
-  }
-
-  public static void StartDate(FlatBufferBuilder builder) { builder.StartTable(1); }
-  public static void AddUnit(FlatBufferBuilder builder, DateUnit unit) { builder.AddShort(0, (short)unit, 1); }
-  public static Offset<Date> EndDate(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Date>(o);
-  }
-}
-
-
-static internal class DateVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Unit*/, 2 /*DateUnit*/, 2, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Decimal.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Decimal.cs
deleted file mode 100644
index fd30378..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Decimal.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Exact decimal value represented as an integer value in two's
-/// complement. Currently only 128-bit (16-byte) and 256-bit (32-byte) integers
-/// are used. The representation uses the endianness indicated
-/// in the Schema.
-internal struct Decimal : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Decimal GetRootAsDecimal(ByteBuffer _bb) { return GetRootAsDecimal(_bb, new Decimal()); }
-  public static Decimal GetRootAsDecimal(ByteBuffer _bb, Decimal obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Decimal __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  /// Total number of decimal digits
-  public int Precision { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
-  /// Number of digits after the decimal point "."
-  public int Scale { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
-  /// Number of bits per value. The only accepted widths are 128 and 256.
-  /// We use bitWidth for consistency with Int::bitWidth.
-  public int BitWidth { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)128; } }
-
-  public static Offset<Decimal> CreateDecimal(FlatBufferBuilder builder,
-      int precision = 0,
-      int scale = 0,
-      int bitWidth = 128) {
-    builder.StartTable(3);
-    Decimal.AddBitWidth(builder, bitWidth);
-    Decimal.AddScale(builder, scale);
-    Decimal.AddPrecision(builder, precision);
-    return Decimal.EndDecimal(builder);
-  }
-
-  public static void StartDecimal(FlatBufferBuilder builder) { builder.StartTable(3); }
-  public static void AddPrecision(FlatBufferBuilder builder, int precision) { builder.AddInt(0, precision, 0); }
-  public static void AddScale(FlatBufferBuilder builder, int scale) { builder.AddInt(1, scale, 0); }
-  public static void AddBitWidth(FlatBufferBuilder builder, int bitWidth) { builder.AddInt(2, bitWidth, 128); }
-  public static Offset<Decimal> EndDecimal(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Decimal>(o);
-  }
-}
-
-
-static internal class DecimalVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Precision*/, 4 /*int*/, 4, false)
-      && verifier.VerifyField(tablePos, 6 /*Scale*/, 4 /*int*/, 4, false)
-      && verifier.VerifyField(tablePos, 8 /*BitWidth*/, 4 /*int*/, 4, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Duration.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Duration.cs
deleted file mode 100644
index 28c2a51..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Duration.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct Duration : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Duration GetRootAsDuration(ByteBuffer _bb) { return GetRootAsDuration(_bb, new Duration()); }
-  public static Duration GetRootAsDuration(ByteBuffer _bb, Duration obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Duration __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public TimeUnit Unit { get { int o = __p.__offset(4); return o != 0 ? (TimeUnit)__p.bb.GetShort(o + __p.bb_pos) : TimeUnit.MILLISECOND; } }
-
-  public static Offset<Duration> CreateDuration(FlatBufferBuilder builder,
-      TimeUnit unit = TimeUnit.MILLISECOND) {
-    builder.StartTable(1);
-    Duration.AddUnit(builder, unit);
-    return Duration.EndDuration(builder);
-  }
-
-  public static void StartDuration(FlatBufferBuilder builder) { builder.StartTable(1); }
-  public static void AddUnit(FlatBufferBuilder builder, TimeUnit unit) { builder.AddShort(0, (short)unit, 1); }
-  public static Offset<Duration> EndDuration(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Duration>(o);
-  }
-}
-
-
-static internal class DurationVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Unit*/, 2 /*TimeUnit*/, 2, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/FloatingPoint.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/FloatingPoint.cs
deleted file mode 100644
index 611c130..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/FloatingPoint.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct FloatingPoint : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static FloatingPoint GetRootAsFloatingPoint(ByteBuffer _bb) { return GetRootAsFloatingPoint(_bb, new FloatingPoint()); }
-  public static FloatingPoint GetRootAsFloatingPoint(ByteBuffer _bb, FloatingPoint obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public FloatingPoint __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public Precision Precision { get { int o = __p.__offset(4); return o != 0 ? (Precision)__p.bb.GetShort(o + __p.bb_pos) : Precision.HALF; } }
-
-  public static Offset<FloatingPoint> CreateFloatingPoint(FlatBufferBuilder builder,
-      Precision precision = Precision.HALF) {
-    builder.StartTable(1);
-    FloatingPoint.AddPrecision(builder, precision);
-    return FloatingPoint.EndFloatingPoint(builder);
-  }
-
-  public static void StartFloatingPoint(FlatBufferBuilder builder) { builder.StartTable(1); }
-  public static void AddPrecision(FlatBufferBuilder builder, Precision precision) { builder.AddShort(0, (short)precision, 0); }
-  public static Offset<FloatingPoint> EndFloatingPoint(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<FloatingPoint>(o);
-  }
-}
-
-
-static internal class FloatingPointVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Precision*/, 2 /*Precision*/, 2, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Int.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Int.cs
deleted file mode 100644
index d0cec48..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Int.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct Int : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Int GetRootAsInt(ByteBuffer _bb) { return GetRootAsInt(_bb, new Int()); }
-  public static Int GetRootAsInt(ByteBuffer _bb, Int obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Int __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public int BitWidth { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
-  public bool IsSigned { get { int o = __p.__offset(6); return o != 0 ? 0!=__p.bb.Get(o + __p.bb_pos) : (bool)false; } }
-
-  public static Offset<Int> CreateInt(FlatBufferBuilder builder,
-      int bitWidth = 0,
-      bool is_signed = false) {
-    builder.StartTable(2);
-    Int.AddBitWidth(builder, bitWidth);
-    Int.AddIsSigned(builder, is_signed);
-    return Int.EndInt(builder);
-  }
-
-  public static void StartInt(FlatBufferBuilder builder) { builder.StartTable(2); }
-  public static void AddBitWidth(FlatBufferBuilder builder, int bitWidth) { builder.AddInt(0, bitWidth, 0); }
-  public static void AddIsSigned(FlatBufferBuilder builder, bool isSigned) { builder.AddBool(1, isSigned, false); }
-  public static Offset<Int> EndInt(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Int>(o);
-  }
-}
-
-
-static internal class IntVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*BitWidth*/, 4 /*int*/, 4, false)
-      && verifier.VerifyField(tablePos, 6 /*IsSigned*/, 1 /*bool*/, 1, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Interval.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Interval.cs
deleted file mode 100644
index 7d31603..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Interval.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct Interval : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Interval GetRootAsInterval(ByteBuffer _bb) { return GetRootAsInterval(_bb, new Interval()); }
-  public static Interval GetRootAsInterval(ByteBuffer _bb, Interval obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Interval __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public IntervalUnit Unit { get { int o = __p.__offset(4); return o != 0 ? (IntervalUnit)__p.bb.GetShort(o + __p.bb_pos) : IntervalUnit.YEAR_MONTH; } }
-
-  public static Offset<Interval> CreateInterval(FlatBufferBuilder builder,
-      IntervalUnit unit = IntervalUnit.YEAR_MONTH) {
-    builder.StartTable(1);
-    Interval.AddUnit(builder, unit);
-    return Interval.EndInterval(builder);
-  }
-
-  public static void StartInterval(FlatBufferBuilder builder) { builder.StartTable(1); }
-  public static void AddUnit(FlatBufferBuilder builder, IntervalUnit unit) { builder.AddShort(0, (short)unit, 0); }
-  public static Offset<Interval> EndInterval(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Interval>(o);
-  }
-}
-
-
-static internal class IntervalVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Unit*/, 2 /*IntervalUnit*/, 2, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/LargeBinary.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/LargeBinary.cs
deleted file mode 100644
index bcc3384..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/LargeBinary.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Same as Binary, but with 64-bit offsets, allowing to represent
-/// extremely large data values.
-internal struct LargeBinary : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static LargeBinary GetRootAsLargeBinary(ByteBuffer _bb) { return GetRootAsLargeBinary(_bb, new LargeBinary()); }
-  public static LargeBinary GetRootAsLargeBinary(ByteBuffer _bb, LargeBinary obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public LargeBinary __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartLargeBinary(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<LargeBinary> EndLargeBinary(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<LargeBinary>(o);
-  }
-}
-
-
-static internal class LargeBinaryVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/LargeList.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/LargeList.cs
deleted file mode 100644
index 4bd0961..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/LargeList.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Same as List, but with 64-bit offsets, allowing to represent
-/// extremely large data values.
-internal struct LargeList : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static LargeList GetRootAsLargeList(ByteBuffer _bb) { return GetRootAsLargeList(_bb, new LargeList()); }
-  public static LargeList GetRootAsLargeList(ByteBuffer _bb, LargeList obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public LargeList __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartLargeList(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<LargeList> EndLargeList(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<LargeList>(o);
-  }
-}
-
-
-static internal class LargeListVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/LargeUtf8.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/LargeUtf8.cs
deleted file mode 100644
index 21c8c9d..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/LargeUtf8.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Same as Utf8, but with 64-bit offsets, allowing to represent
-/// extremely large data values.
-internal struct LargeUtf8 : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static LargeUtf8 GetRootAsLargeUtf8(ByteBuffer _bb) { return GetRootAsLargeUtf8(_bb, new LargeUtf8()); }
-  public static LargeUtf8 GetRootAsLargeUtf8(ByteBuffer _bb, LargeUtf8 obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public LargeUtf8 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartLargeUtf8(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<LargeUtf8> EndLargeUtf8(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<LargeUtf8>(o);
-  }
-}
-
-
-static internal class LargeUtf8Verify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/List.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/List.cs
deleted file mode 100644
index 37ffee6..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/List.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-internal struct List : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static List GetRootAsList(ByteBuffer _bb) { return GetRootAsList(_bb, new List()); }
-  public static List GetRootAsList(ByteBuffer _bb, List obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public List __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartList(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<List> EndList(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<List>(o);
-  }
-}
-
-
-static internal class ListVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Null.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Null.cs
deleted file mode 100644
index 82902f3..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Null.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// These are stored in the flatbuffer in the Type union below
-internal struct Null : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Null GetRootAsNull(ByteBuffer _bb) { return GetRootAsNull(_bb, new Null()); }
-  public static Null GetRootAsNull(ByteBuffer _bb, Null obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Null __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartNull(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<Null> EndNull(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Null>(o);
-  }
-}
-
-
-static internal class NullVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Struct_.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Struct_.cs
deleted file mode 100644
index a8f29e3..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Struct_.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// A Struct_ in the flatbuffer metadata is the same as an Arrow Struct
-/// (according to the physical memory layout). We used Struct_ here as
-/// Struct is a reserved word in Flatbuffers
-internal struct Struct_ : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Struct_ GetRootAsStruct_(ByteBuffer _bb) { return GetRootAsStruct_(_bb, new Struct_()); }
-  public static Struct_ GetRootAsStruct_(ByteBuffer _bb, Struct_ obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Struct_ __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartStruct_(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<Struct_> EndStruct_(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Struct_>(o);
-  }
-}
-
-
-static internal class Struct_Verify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Time.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Time.cs
deleted file mode 100644
index 4cb3302..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Time.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Time is either a 32-bit or 64-bit signed integer type representing an
-/// elapsed time since midnight, stored in either of four units: seconds,
-/// milliseconds, microseconds or nanoseconds.
-///
-/// The integer `bitWidth` depends on the `unit` and must be one of the following:
-/// * SECOND and MILLISECOND: 32 bits
-/// * MICROSECOND and NANOSECOND: 64 bits
-///
-/// The allowed values are between 0 (inclusive) and 86400 (=24*60*60) seconds
-/// (exclusive), adjusted for the time unit (for example, up to 86400000
-/// exclusive for the MILLISECOND unit).
-/// This definition doesn't allow for leap seconds. Time values from
-/// measurements with leap seconds will need to be corrected when ingesting
-/// into Arrow (for example by replacing the value 86400 with 86399).
-internal struct Time : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Time GetRootAsTime(ByteBuffer _bb) { return GetRootAsTime(_bb, new Time()); }
-  public static Time GetRootAsTime(ByteBuffer _bb, Time obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Time __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public TimeUnit Unit { get { int o = __p.__offset(4); return o != 0 ? (TimeUnit)__p.bb.GetShort(o + __p.bb_pos) : TimeUnit.MILLISECOND; } }
-  public int BitWidth { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)32; } }
-
-  public static Offset<Time> CreateTime(FlatBufferBuilder builder,
-      TimeUnit unit = TimeUnit.MILLISECOND,
-      int bitWidth = 32) {
-    builder.StartTable(2);
-    Time.AddBitWidth(builder, bitWidth);
-    Time.AddUnit(builder, unit);
-    return Time.EndTime(builder);
-  }
-
-  public static void StartTime(FlatBufferBuilder builder) { builder.StartTable(2); }
-  public static void AddUnit(FlatBufferBuilder builder, TimeUnit unit) { builder.AddShort(0, (short)unit, 1); }
-  public static void AddBitWidth(FlatBufferBuilder builder, int bitWidth) { builder.AddInt(1, bitWidth, 32); }
-  public static Offset<Time> EndTime(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Time>(o);
-  }
-}
-
-
-static internal class TimeVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Unit*/, 2 /*TimeUnit*/, 2, false)
-      && verifier.VerifyField(tablePos, 6 /*BitWidth*/, 4 /*int*/, 4, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Timestamp.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Timestamp.cs
deleted file mode 100644
index e7b2ac3..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Timestamp.cs
+++ /dev/null
@@ -1,176 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Timestamp is a 64-bit signed integer representing an elapsed time since a
-/// fixed epoch, stored in either of four units: seconds, milliseconds,
-/// microseconds or nanoseconds, and is optionally annotated with a timezone.
-///
-/// Timestamp values do not include any leap seconds (in other words, all
-/// days are considered 86400 seconds long).
-///
-/// Timestamps with a non-empty timezone
-/// ------------------------------------
-///
-/// If a Timestamp column has a non-empty timezone value, its epoch is
-/// 1970-01-01 00:00:00 (January 1st 1970, midnight) in the *UTC* timezone
-/// (the Unix epoch), regardless of the Timestamp's own timezone.
-///
-/// Therefore, timestamp values with a non-empty timezone correspond to
-/// physical points in time together with some additional information about
-/// how the data was obtained and/or how to display it (the timezone).
-///
-///   For example, the timestamp value 0 with the timezone string "Europe/Paris"
-///   corresponds to "January 1st 1970, 00h00" in the UTC timezone, but the
-///   application may prefer to display it as "January 1st 1970, 01h00" in
-///   the Europe/Paris timezone (which is the same physical point in time).
-///
-/// One consequence is that timestamp values with a non-empty timezone
-/// can be compared and ordered directly, since they all share the same
-/// well-known point of reference (the Unix epoch).
-///
-/// Timestamps with an unset / empty timezone
-/// -----------------------------------------
-///
-/// If a Timestamp column has no timezone value, its epoch is
-/// 1970-01-01 00:00:00 (January 1st 1970, midnight) in an *unknown* timezone.
-///
-/// Therefore, timestamp values without a timezone cannot be meaningfully
-/// interpreted as physical points in time, but only as calendar / clock
-/// indications ("wall clock time") in an unspecified timezone.
-///
-///   For example, the timestamp value 0 with an empty timezone string
-///   corresponds to "January 1st 1970, 00h00" in an unknown timezone: there
-///   is not enough information to interpret it as a well-defined physical
-///   point in time.
-///
-/// One consequence is that timestamp values without a timezone cannot
-/// be reliably compared or ordered, since they may have different points of
-/// reference.  In particular, it is *not* possible to interpret an unset
-/// or empty timezone as the same as "UTC".
-///
-/// Conversion between timezones
-/// ----------------------------
-///
-/// If a Timestamp column has a non-empty timezone, changing the timezone
-/// to a different non-empty value is a metadata-only operation:
-/// the timestamp values need not change as their point of reference remains
-/// the same (the Unix epoch).
-///
-/// However, if a Timestamp column has no timezone value, changing it to a
-/// non-empty value requires to think about the desired semantics.
-/// One possibility is to assume that the original timestamp values are
-/// relative to the epoch of the timezone being set; timestamp values should
-/// then adjusted to the Unix epoch (for example, changing the timezone from
-/// empty to "Europe/Paris" would require converting the timestamp values
-/// from "Europe/Paris" to "UTC", which seems counter-intuitive but is
-/// nevertheless correct).
-///
-/// Guidelines for encoding data from external libraries
-/// ----------------------------------------------------
-///
-/// Date & time libraries often have multiple different data types for temporal
-/// data. In order to ease interoperability between different implementations the
-/// Arrow project has some recommendations for encoding these types into a Timestamp
-/// column.
-///
-/// An "instant" represents a physical point in time that has no relevant timezone
-/// (for example, astronomical data). To encode an instant, use a Timestamp with
-/// the timezone string set to "UTC", and make sure the Timestamp values
-/// are relative to the UTC epoch (January 1st 1970, midnight).
-///
-/// A "zoned date-time" represents a physical point in time annotated with an
-/// informative timezone (for example, the timezone in which the data was
-/// recorded).  To encode a zoned date-time, use a Timestamp with the timezone
-/// string set to the name of the timezone, and make sure the Timestamp values
-/// are relative to the UTC epoch (January 1st 1970, midnight).
-///
-///  (There is some ambiguity between an instant and a zoned date-time with the
-///   UTC timezone.  Both of these are stored the same in Arrow.  Typically,
-///   this distinction does not matter.  If it does, then an application should
-///   use custom metadata or an extension type to distinguish between the two cases.)
-///
-/// An "offset date-time" represents a physical point in time combined with an
-/// explicit offset from UTC.  To encode an offset date-time, use a Timestamp
-/// with the timezone string set to the numeric timezone offset string
-/// (e.g. "+03:00"), and make sure the Timestamp values are relative to
-/// the UTC epoch (January 1st 1970, midnight).
-///
-/// A "naive date-time" (also called "local date-time" in some libraries)
-/// represents a wall clock time combined with a calendar date, but with
-/// no indication of how to map this information to a physical point in time.
-/// Naive date-times must be handled with care because of this missing
-/// information, and also because daylight saving time (DST) may make
-/// some values ambiguous or nonexistent. A naive date-time may be
-/// stored as a struct with Date and Time fields. However, it may also be
-/// encoded into a Timestamp column with an empty timezone. The timestamp
-/// values should be computed "as if" the timezone of the date-time values
-/// was UTC; for example, the naive date-time "January 1st 1970, 00h00" would
-/// be encoded as timestamp value 0.
-internal struct Timestamp : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Timestamp GetRootAsTimestamp(ByteBuffer _bb) { return GetRootAsTimestamp(_bb, new Timestamp()); }
-  public static Timestamp GetRootAsTimestamp(ByteBuffer _bb, Timestamp obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Timestamp __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public TimeUnit Unit { get { int o = __p.__offset(4); return o != 0 ? (TimeUnit)__p.bb.GetShort(o + __p.bb_pos) : TimeUnit.SECOND; } }
-  /// The timezone is an optional string indicating the name of a timezone,
-  /// one of:
-  ///
-  /// * As used in the Olson timezone database (the "tz database" or
-  ///   "tzdata"), such as "America/New_York".
-  /// * An absolute timezone offset of the form "+XX:XX" or "-XX:XX",
-  ///   such as "+07:30".
-  ///
-  /// Whether a timezone string is present indicates different semantics about
-  /// the data (see above).
-  public string Timezone { get { int o = __p.__offset(6); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
-#if ENABLE_SPAN_T
-  public Span<byte> GetTimezoneBytes() { return __p.__vector_as_span<byte>(6, 1); }
-#else
-  public ArraySegment<byte>? GetTimezoneBytes() { return __p.__vector_as_arraysegment(6); }
-#endif
-  public byte[] GetTimezoneArray() { return __p.__vector_as_array<byte>(6); }
-
-  public static Offset<Timestamp> CreateTimestamp(FlatBufferBuilder builder,
-      TimeUnit unit = TimeUnit.SECOND,
-      StringOffset timezoneOffset = default(StringOffset)) {
-    builder.StartTable(2);
-    Timestamp.AddTimezone(builder, timezoneOffset);
-    Timestamp.AddUnit(builder, unit);
-    return Timestamp.EndTimestamp(builder);
-  }
-
-  public static void StartTimestamp(FlatBufferBuilder builder) { builder.StartTable(2); }
-  public static void AddUnit(FlatBufferBuilder builder, TimeUnit unit) { builder.AddShort(0, (short)unit, 0); }
-  public static void AddTimezone(FlatBufferBuilder builder, StringOffset timezoneOffset) { builder.AddOffset(1, timezoneOffset.Value, 0); }
-  public static Offset<Timestamp> EndTimestamp(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Timestamp>(o);
-  }
-}
-
-
-static internal class TimestampVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Unit*/, 2 /*TimeUnit*/, 2, false)
-      && verifier.VerifyString(tablePos, 6 /*Timezone*/, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Union.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Union.cs
deleted file mode 100644
index 9657071..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Union.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// A union is a complex type with children in Field
-/// By default ids in the type vector refer to the offsets in the children
-/// optionally typeIds provides an indirection between the child offset and the type id
-/// for each child `typeIds[offset]` is the id used in the type vector
-internal struct Union : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Union GetRootAsUnion(ByteBuffer _bb) { return GetRootAsUnion(_bb, new Union()); }
-  public static Union GetRootAsUnion(ByteBuffer _bb, Union obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Union __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-  public UnionMode Mode { get { int o = __p.__offset(4); return o != 0 ? (UnionMode)__p.bb.GetShort(o + __p.bb_pos) : UnionMode.Sparse; } }
-  public int TypeIds(int j) { int o = __p.__offset(6); return o != 0 ? __p.bb.GetInt(__p.__vector(o) + j * 4) : (int)0; }
-  public int TypeIdsLength { get { int o = __p.__offset(6); return o != 0 ? __p.__vector_len(o) : 0; } }
-#if ENABLE_SPAN_T
-  public Span<int> GetTypeIdsBytes() { return __p.__vector_as_span<int>(6, 4); }
-#else
-  public ArraySegment<byte>? GetTypeIdsBytes() { return __p.__vector_as_arraysegment(6); }
-#endif
-  public int[] GetTypeIdsArray() { return __p.__vector_as_array<int>(6); }
-
-  public static Offset<Union> CreateUnion(FlatBufferBuilder builder,
-      UnionMode mode = UnionMode.Sparse,
-      VectorOffset typeIdsOffset = default(VectorOffset)) {
-    builder.StartTable(2);
-    Union.AddTypeIds(builder, typeIdsOffset);
-    Union.AddMode(builder, mode);
-    return Union.EndUnion(builder);
-  }
-
-  public static void StartUnion(FlatBufferBuilder builder) { builder.StartTable(2); }
-  public static void AddMode(FlatBufferBuilder builder, UnionMode mode) { builder.AddShort(0, (short)mode, 0); }
-  public static void AddTypeIds(FlatBufferBuilder builder, VectorOffset typeIdsOffset) { builder.AddOffset(1, typeIdsOffset.Value, 0); }
-  public static VectorOffset CreateTypeIdsVector(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddInt(data[i]); return builder.EndVector(); }
-  public static VectorOffset CreateTypeIdsVectorBlock(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateTypeIdsVectorBlock(FlatBufferBuilder builder, ArraySegment<int> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
-  public static VectorOffset CreateTypeIdsVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<int>(dataPtr, sizeInBytes); return builder.EndVector(); }
-  public static void StartTypeIdsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
-  public static Offset<Union> EndUnion(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Union>(o);
-  }
-}
-
-
-static internal class UnionVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyField(tablePos, 4 /*Mode*/, 2 /*UnionMode*/, 2, false)
-      && verifier.VerifyVectorOfData(tablePos, 6 /*TypeIds*/, 4 /*int*/, false)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Types/Utf8.cs b/csharp/src/Apache.Arrow/Flatbuf/Types/Utf8.cs
deleted file mode 100644
index 23c0fb4..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Types/Utf8.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Unicode with UTF-8 encoding
-internal struct Utf8 : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Utf8 GetRootAsUtf8(ByteBuffer _bb) { return GetRootAsUtf8(_bb, new Utf8()); }
-  public static Utf8 GetRootAsUtf8(ByteBuffer _bb, Utf8 obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Utf8 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartUtf8(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<Utf8> EndUtf8(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Utf8>(o);
-  }
-}
-
-
-static internal class Utf8Verify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Flatbuf/Utf8View.cs b/csharp/src/Apache.Arrow/Flatbuf/Utf8View.cs
deleted file mode 100644
index e85c537..0000000
--- a/csharp/src/Apache.Arrow/Flatbuf/Utf8View.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// <auto-generated>
-//  automatically generated by the FlatBuffers compiler, do not modify
-// </auto-generated>
-
-namespace Apache.Arrow.Flatbuf
-{
-
-using global::System;
-using global::System.Collections.Generic;
-using global::Google.FlatBuffers;
-
-/// Logically the same as Utf8, but the internal representation uses a view
-/// struct that contains the string length and either the string's entire data
-/// inline (for small strings) or an inlined prefix, an index of another buffer,
-/// and an offset pointing to a slice in that buffer (for non-small strings).
-///
-/// Since it uses a variable number of data buffers, each Field with this type
-/// must have a corresponding entry in `variadicBufferCounts`.
-internal struct Utf8View : IFlatbufferObject
-{
-  private Table __p;
-  public ByteBuffer ByteBuffer { get { return __p.bb; } }
-  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_9(); }
-  public static Utf8View GetRootAsUtf8View(ByteBuffer _bb) { return GetRootAsUtf8View(_bb, new Utf8View()); }
-  public static Utf8View GetRootAsUtf8View(ByteBuffer _bb, Utf8View obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
-  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
-  public Utf8View __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
-
-
-  public static void StartUtf8View(FlatBufferBuilder builder) { builder.StartTable(0); }
-  public static Offset<Utf8View> EndUtf8View(FlatBufferBuilder builder) {
-    int o = builder.EndTable();
-    return new Offset<Utf8View>(o);
-  }
-}
-
-
-static internal class Utf8ViewVerify
-{
-  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
-  {
-    return verifier.VerifyTableStart(tablePos)
-      && verifier.VerifyTableEnd(tablePos);
-  }
-}
-
-}
diff --git a/csharp/src/Apache.Arrow/Interfaces/IArrowArray.cs b/csharp/src/Apache.Arrow/Interfaces/IArrowArray.cs
deleted file mode 100644
index 9bcee36..0000000
--- a/csharp/src/Apache.Arrow/Interfaces/IArrowArray.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow
-{
-    public interface IArrowArray : IDisposable
-    {
-        bool IsNull(int index);
-
-        bool IsValid(int index);
-
-        int Length { get; }
-
-        int Offset { get; }
-
-        int NullCount { get; }
-
-        ArrayData Data { get; }
-
-        void Accept(IArrowArrayVisitor visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Interfaces/IArrowArrayBuilder.cs b/csharp/src/Apache.Arrow/Interfaces/IArrowArrayBuilder.cs
deleted file mode 100644
index b18ff45..0000000
--- a/csharp/src/Apache.Arrow/Interfaces/IArrowArrayBuilder.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Arrow
-{
-    public interface IArrowArrayBuilder
-    {
-        int Length { get; }
-    }
-
-    public interface IArrowArrayBuilder<out TArray> : IArrowArrayBuilder
-        where TArray : IArrowArray
-    {
-        TArray Build(MemoryAllocator allocator);
-    }
-
-    public interface IArrowArrayBuilder<out TArray, out TBuilder> : IArrowArrayBuilder<TArray>
-        where TArray : IArrowArray
-        where TBuilder : IArrowArrayBuilder<TArray>
-    {
-        TBuilder Reserve(int capacity);
-        TBuilder Resize(int length);
-        TBuilder Clear();
-        TBuilder AppendNull();
-    }
-
-
-    public interface IArrowArrayBuilder<T, out TArray, out TBuilder> : IArrowArrayBuilder<TArray, TBuilder>
-        where TArray : IArrowArray
-        where TBuilder : IArrowArrayBuilder<TArray>
-    {
-        TBuilder Append(T value);
-        TBuilder Append(ReadOnlySpan<T> span);
-        TBuilder AppendRange(IEnumerable<T> values);
-        TBuilder Swap(int i, int j);
-        TBuilder Set(int index, T value);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Interfaces/IArrowArrayVisitor.cs b/csharp/src/Apache.Arrow/Interfaces/IArrowArrayVisitor.cs
deleted file mode 100644
index c93bbb4..0000000
--- a/csharp/src/Apache.Arrow/Interfaces/IArrowArrayVisitor.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow
-{
-    // NOTE: Acyclic Visitor Pattern
-
-    public interface IArrowArrayVisitor
-    {
-        void Visit(IArrowArray array);
-    }
-
-    public interface IArrowArrayVisitor<T>: IArrowArrayVisitor
-        where T: IArrowArray
-    {
-        void Visit(T array);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Interfaces/IArrowRecord.cs b/csharp/src/Apache.Arrow/Interfaces/IArrowRecord.cs
deleted file mode 100644
index 126d214..0000000
--- a/csharp/src/Apache.Arrow/Interfaces/IArrowRecord.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Collections.Generic;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public interface IArrowRecord : IArrowArray
-    {
-        IRecordType Schema { get; }
-        int ColumnCount { get; }
-
-        IArrowArray Column(string columnName, IEqualityComparer<string> comparer = default);
-        IArrowArray Column(int columnIndex);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowFileConstants.cs b/csharp/src/Apache.Arrow/Ipc/ArrowFileConstants.cs
deleted file mode 100644
index 6b308d6..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ArrowFileConstants.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Text;
-
-namespace Apache.Arrow.Ipc
-{
-    internal static class ArrowFileConstants
-    {
-        public static readonly byte[] Magic = Encoding.UTF8.GetBytes("ARROW1");
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowFileReader.cs b/csharp/src/Apache.Arrow/Ipc/ArrowFileReader.cs
deleted file mode 100644
index 935a1e7..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ArrowFileReader.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.Ipc
-{
-    /// <summary>
-    /// Implements an <see cref="ArrowStreamReader"/> that can read Arrow files.
-    /// </summary>
-    public class ArrowFileReader : ArrowStreamReader
-    {
-        private ArrowFileReaderImplementation Implementation =>
-            (ArrowFileReaderImplementation)_implementation;
-
-        public bool IsFileValid => Implementation.IsFileValid;
-
-        public ArrowFileReader(Stream stream)
-            : this(stream, leaveOpen: false)
-        {
-        }
-
-        public ArrowFileReader(Stream stream, ICompressionCodecFactory compressionCodecFactory)
-            : this(stream, allocator: null, compressionCodecFactory, leaveOpen: false)
-        {
-        }
-
-        public ArrowFileReader(Stream stream, MemoryAllocator allocator)
-            : this(stream, allocator, leaveOpen: false)
-        {
-        }
-
-        public ArrowFileReader(Stream stream, MemoryAllocator allocator, ICompressionCodecFactory compressionCodecFactory)
-            : this(stream, allocator, compressionCodecFactory, leaveOpen: false)
-        {
-        }
-
-        public ArrowFileReader(Stream stream, bool leaveOpen)
-            : this(stream, allocator: null, compressionCodecFactory: null, leaveOpen)
-        {
-        }
-
-        public ArrowFileReader(Stream stream, MemoryAllocator allocator, bool leaveOpen)
-            : this(stream, allocator, compressionCodecFactory: null, leaveOpen)
-        {
-        }
-
-        public ArrowFileReader(Stream stream, MemoryAllocator allocator, ICompressionCodecFactory compressionCodecFactory, bool leaveOpen)
-            : base(new ArrowFileReaderImplementation(stream, allocator, compressionCodecFactory, leaveOpen))
-        {
-        }
-
-        public static ArrowFileReader FromFile(string filename)
-        {
-            var stream = new FileStream(filename, FileMode.Open, FileAccess.Read);
-            return new ArrowFileReader(stream);
-        }
-
-        public ValueTask<int> RecordBatchCountAsync()
-        {
-            return Implementation.RecordBatchCountAsync();
-        }
-
-        public ValueTask<RecordBatch> ReadRecordBatchAsync(int index, CancellationToken cancellationToken = default)
-        {
-            return Implementation.ReadRecordBatchAsync(index, cancellationToken);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowFileReaderImplementation.cs b/csharp/src/Apache.Arrow/Ipc/ArrowFileReaderImplementation.cs
deleted file mode 100644
index 4b7c5f9..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ArrowFileReaderImplementation.cs
+++ /dev/null
@@ -1,342 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using System;
-using System.Buffers;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.Ipc
-{
-    internal sealed class ArrowFileReaderImplementation : ArrowStreamReaderImplementation
-    {
-        public bool IsFileValid { get; private set; }
-
-        /// <summary>
-        /// When using GetNextRecordBatch this value 
-        /// is to remember what index is next
-        /// </summary>
-        private int _recordBatchIndex;
-
-        private ArrowFooter _footer;
-
-        private bool HasReadDictionaries => HasReadSchema && DictionaryMemo.LoadedDictionaryCount >= _footer.DictionaryCount;
-
-        public ArrowFileReaderImplementation(Stream stream, MemoryAllocator allocator, ICompressionCodecFactory compressionCodecFactory, bool leaveOpen)
-            : base(stream, allocator, compressionCodecFactory, leaveOpen)
-        {
-        }
-
-        public async ValueTask<int> RecordBatchCountAsync(CancellationToken cancellationToken = default)
-        {
-            if (!HasReadSchema)
-            {
-                await ReadSchemaAsync(cancellationToken).ConfigureAwait(false);
-            }
-
-            return _footer.RecordBatchCount;
-        }
-
-        public override async ValueTask ReadSchemaAsync(CancellationToken cancellationToken = default)
-        {
-            if (HasReadSchema)
-            {
-                return;
-            }
-
-            await ValidateFileAsync(cancellationToken).ConfigureAwait(false);
-
-            int footerLength = 0;
-            using (ArrayPool<byte>.Shared.RentReturn(4, out Memory<byte> buffer))
-            {
-                BaseStream.Position = GetFooterLengthPosition();
-
-                int bytesRead = await BaseStream.ReadFullBufferAsync(buffer, cancellationToken).ConfigureAwait(false);
-                EnsureFullRead(buffer, bytesRead);
-
-                footerLength = ReadFooterLength(buffer);
-            }
-
-            using (ArrayPool<byte>.Shared.RentReturn(footerLength, out Memory<byte> buffer))
-            {
-                long footerStartPosition = GetFooterLengthPosition() - footerLength;
-
-                BaseStream.Position = footerStartPosition;
-
-                int bytesRead = await BaseStream.ReadFullBufferAsync(buffer, cancellationToken).ConfigureAwait(false);
-                EnsureFullRead(buffer, bytesRead);
-
-                ReadSchema(buffer);
-            }
-        }
-
-        public override void ReadSchema()
-        {
-            if (HasReadSchema)
-            {
-                return;
-            }
-
-            ValidateFile();
-
-            int footerLength = 0;
-            using (ArrayPool<byte>.Shared.RentReturn(4, out Memory<byte> buffer))
-            {
-                BaseStream.Position = GetFooterLengthPosition();
-
-                int bytesRead = BaseStream.ReadFullBuffer(buffer);
-                EnsureFullRead(buffer, bytesRead);
-
-                footerLength = ReadFooterLength(buffer);
-            }
-
-            using (ArrayPool<byte>.Shared.RentReturn(footerLength, out Memory<byte> buffer))
-            {
-                long footerStartPosition = GetFooterLengthPosition() - footerLength;
-
-                BaseStream.Position = footerStartPosition;
-
-                int bytesRead = BaseStream.ReadFullBuffer(buffer);
-                EnsureFullRead(buffer, bytesRead);
-
-                ReadSchema(buffer);
-            }
-        }
-
-        private long GetFooterLengthPosition()
-        {
-            return BaseStream.Length - ArrowFileConstants.Magic.Length - 4;
-        }
-
-        private static int ReadFooterLength(Memory<byte> buffer)
-        {
-            int footerLength = BitUtility.ReadInt32(buffer);
-
-            if (footerLength <= 0)
-                throw new InvalidDataException(
-                    $"Footer length has invalid size <{footerLength}>");
-
-            return footerLength;
-        }
-
-        private void ReadSchema(Memory<byte> buffer)
-        {
-            // Deserialize the footer from the footer flatbuffer
-            _footer = new ArrowFooter(Flatbuf.Footer.GetRootAsFooter(CreateByteBuffer(buffer)), ref _dictionaryMemo);
-
-            _schema = _footer.Schema;
-        }
-
-        public async ValueTask<RecordBatch> ReadRecordBatchAsync(int index, CancellationToken cancellationToken)
-        {
-            await ReadSchemaAsync().ConfigureAwait(false);
-            await ReadDictionariesAsync(cancellationToken).ConfigureAwait(false);
-
-            if (index >= _footer.RecordBatchCount)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            Block block = _footer.GetRecordBatchBlock(index);
-
-            BaseStream.Position = block.Offset;
-
-            return await ReadRecordBatchAsync(cancellationToken).ConfigureAwait(false);
-        }
-
-        public RecordBatch ReadRecordBatch(int index)
-        {
-            ReadSchema();
-            ReadDictionaries();
-
-            if (index >= _footer.RecordBatchCount)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            Block block = _footer.GetRecordBatchBlock(index);
-
-            BaseStream.Position = block.Offset;
-
-            return ReadRecordBatch();
-        }
-
-        public override async ValueTask<RecordBatch> ReadNextRecordBatchAsync(CancellationToken cancellationToken)
-        {
-            await ReadSchemaAsync().ConfigureAwait(false);
-            await ReadDictionariesAsync(cancellationToken).ConfigureAwait(false);
-
-            if (_recordBatchIndex >= _footer.RecordBatchCount)
-            {
-                return null;
-            }
-
-            RecordBatch result = await ReadRecordBatchAsync(_recordBatchIndex, cancellationToken).ConfigureAwait(false);
-            _recordBatchIndex++;
-
-            return result;
-        }
-
-        public override RecordBatch ReadNextRecordBatch()
-        {
-            ReadSchema();
-            ReadDictionaries();
-
-            if (_recordBatchIndex >= _footer.RecordBatchCount)
-            {
-                return null;
-            }
-
-            RecordBatch result = ReadRecordBatch(_recordBatchIndex);
-            _recordBatchIndex++;
-
-            return result;
-        }
-
-        private async ValueTask ReadDictionariesAsync(CancellationToken cancellationToken = default)
-        {
-            if (HasReadDictionaries)
-            {
-                return;
-            }
-
-            foreach (Block block in _footer.Dictionaries)
-            {
-                BaseStream.Position = block.Offset;
-                await ReadMessageAsync(cancellationToken);
-            }
-        }
-
-        private void ReadDictionaries()
-        {
-            if (HasReadDictionaries)
-            {
-                return;
-            }
-
-            foreach (Block block in _footer.Dictionaries)
-            {
-                BaseStream.Position = block.Offset;
-                ReadMessage();
-            }
-        }
-
-        /// <summary>
-        /// Check if file format is valid. If it's valid don't run the validation again.
-        /// </summary>
-        private async ValueTask ValidateFileAsync(CancellationToken cancellationToken = default)
-        {
-            if (IsFileValid)
-            {
-                return;
-            }
-
-            await ValidateMagicAsync(cancellationToken).ConfigureAwait(false);
-
-            IsFileValid = true;
-        }
-
-        /// <summary>
-        /// Check if file format is valid. If it's valid don't run the validation again.
-        /// </summary>
-        private void ValidateFile()
-        {
-            if (IsFileValid)
-            {
-                return;
-            }
-
-            ValidateMagic();
-
-            IsFileValid = true;
-        }
-
-        private async ValueTask ValidateMagicAsync(CancellationToken cancellationToken = default)
-        {
-            long startingPosition = BaseStream.Position;
-            int magicLength = ArrowFileConstants.Magic.Length;
-
-            try
-            {
-                using (ArrayPool<byte>.Shared.RentReturn(magicLength, out Memory<byte> buffer))
-                {
-                    // Seek to the beginning of the stream
-                    BaseStream.Position = 0;
-
-                    // Read beginning of stream
-                    await BaseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
-
-                    VerifyMagic(buffer);
-
-                    // Move stream position to magic-length bytes away from the end of the stream
-                    BaseStream.Position = BaseStream.Length - magicLength;
-
-                    // Read the end of the stream
-                    await BaseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
-
-                    VerifyMagic(buffer);
-                }
-            }
-            finally
-            {
-                BaseStream.Position = startingPosition;
-            }
-        }
-
-        private void ValidateMagic()
-        {
-            long startingPosition = BaseStream.Position;
-            int magicLength = ArrowFileConstants.Magic.Length;
-
-            try
-            {
-                using (ArrayPool<byte>.Shared.RentReturn(magicLength, out Memory<byte> buffer))
-                {
-                    // Seek to the beginning of the stream
-                    BaseStream.Position = 0;
-
-                    // Read beginning of stream
-                    BaseStream.Read(buffer);
-
-                    VerifyMagic(buffer);
-
-                    // Move stream position to magic-length bytes away from the end of the stream
-                    BaseStream.Position = BaseStream.Length - magicLength;
-
-                    // Read the end of the stream
-                    BaseStream.Read(buffer);
-
-                    VerifyMagic(buffer);
-                }
-            }
-            finally
-            {
-                BaseStream.Position = startingPosition;
-            }
-        }
-
-        private void VerifyMagic(Memory<byte> buffer)
-        {
-            if (!ArrowFileConstants.Magic.AsSpan().SequenceEqual(buffer.Span))
-            {
-                throw new InvalidDataException(
-                    $"Invalid magic at offset <{BaseStream.Position}>");
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowFileWriter.cs b/csharp/src/Apache.Arrow/Ipc/ArrowFileWriter.cs
deleted file mode 100644
index a643012..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ArrowFileWriter.cs
+++ /dev/null
@@ -1,323 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers.Binary;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Memory;
-
-namespace Apache.Arrow.Ipc
-{
-    public class ArrowFileWriter : ArrowStreamWriter
-    {
-        private long _currentRecordBatchOffset = -1;
-        private long _currentDictionaryOffset = -1;
-
-        private List<Block> DictionaryBlocks { get; set; }
-        private List<Block> RecordBatchBlocks { get; }
-
-        public ArrowFileWriter(Stream stream, Schema schema)
-            : this(stream, schema, leaveOpen: false)
-        {
-        }
-
-        public ArrowFileWriter(Stream stream, Schema schema, bool leaveOpen)
-            : this(stream, schema, leaveOpen, options: null, allocator: null)
-        {
-        }
-
-        public ArrowFileWriter(Stream stream, Schema schema, bool leaveOpen, IpcOptions options)
-            : this(stream, schema, leaveOpen, options, allocator: null)
-        {
-        }
-
-        public ArrowFileWriter(Stream stream, Schema schema, bool leaveOpen, IpcOptions options, MemoryAllocator allocator)
-            : base(stream, schema, leaveOpen, options, allocator)
-        {
-            if (!stream.CanWrite)
-            {
-                throw new ArgumentException("stream must be writable", nameof(stream));
-            }
-
-            // TODO: Remove seek requirement
-
-            if (!stream.CanSeek)
-            {
-                throw new ArgumentException("stream must be seekable", nameof(stream));
-            }
-
-            RecordBatchBlocks = new List<Block>();
-        }
-
-        public override void WriteRecordBatch(RecordBatch recordBatch)
-        {
-            // TODO: Compare record batch schema
-
-            WriteStart();
-
-            WriteRecordBatchInternal(recordBatch);
-        }
-
-        public override async Task WriteRecordBatchAsync(RecordBatch recordBatch, CancellationToken cancellationToken = default)
-        {
-            // TODO: Compare record batch schema
-
-            await WriteStartAsync(cancellationToken).ConfigureAwait(false);
-
-            cancellationToken.ThrowIfCancellationRequested();
-
-            await WriteRecordBatchInternalAsync(recordBatch, cancellationToken)
-                .ConfigureAwait(false);
-        }
-
-        private protected override void StartingWritingRecordBatch()
-        {
-            _currentRecordBatchOffset = BaseStream.Position;
-        }
-
-        private protected override void FinishedWritingRecordBatch(long bodyLength, long metadataLength)
-        {
-            // Record batches only appear after a Schema is written, so the record batch offsets must
-            // always be greater than 0.
-            Debug.Assert(_currentRecordBatchOffset > 0, "_currentRecordBatchOffset must be positive.");
-
-            int metadataLengthInt = checked((int)metadataLength);
-
-            Debug.Assert(BitUtility.IsMultipleOf8(_currentRecordBatchOffset));
-            Debug.Assert(BitUtility.IsMultipleOf8(metadataLengthInt));
-            Debug.Assert(BitUtility.IsMultipleOf8(bodyLength));
-
-            var block = new Block(
-                offset: _currentRecordBatchOffset,
-                length: bodyLength,
-                metadataLength: metadataLengthInt);
-
-            RecordBatchBlocks.Add(block);
-
-            _currentRecordBatchOffset = -1;
-        }
-
-        private protected override void StartingWritingDictionary()
-        {
-            if (DictionaryBlocks == null) { DictionaryBlocks = new List<Block>(); }
-            _currentDictionaryOffset = BaseStream.Position;
-        }
-
-        private protected override void FinishedWritingDictionary(long bodyLength, long metadataLength)
-        {
-            // Dictionaries only appear after a Schema is written, so the dictionary offsets must
-            // always be greater than 0.
-            Debug.Assert(_currentDictionaryOffset > 0, "_currentDictionaryOffset must be positive.");
-
-            int metadataLengthInt = checked((int)metadataLength);
-
-            Debug.Assert(BitUtility.IsMultipleOf8(_currentDictionaryOffset));
-            Debug.Assert(BitUtility.IsMultipleOf8(metadataLengthInt));
-            Debug.Assert(BitUtility.IsMultipleOf8(bodyLength));
-
-            var block = new Block(
-                offset: _currentDictionaryOffset,
-                length: bodyLength,
-                metadataLength: metadataLengthInt);
-
-            DictionaryBlocks.Add(block);
-
-            _currentDictionaryOffset = -1;
-        }
-
-        private protected override void WriteEndInternal()
-        {
-            base.WriteEndInternal();
-
-            WriteFooter(Schema);
-        }
-
-        private protected override async ValueTask WriteEndInternalAsync(CancellationToken cancellationToken)
-        {
-            await base.WriteEndInternalAsync(cancellationToken);
-
-            await WriteFooterAsync(Schema, cancellationToken);
-        }
-
-        private protected override void WriteStartInternal()
-        {
-            // Write magic number and empty padding up to the 8-byte boundary
-
-            WriteMagic();
-            WritePadding(CalculatePadding(ArrowFileConstants.Magic.Length));
-        }
-
-        private protected async override ValueTask WriteStartInternalAsync(CancellationToken cancellationToken)
-        {
-            // Write magic number and empty padding up to the 8-byte boundary
-
-            await WriteMagicAsync(cancellationToken).ConfigureAwait(false);
-            await WritePaddingAsync(CalculatePadding(ArrowFileConstants.Magic.Length))
-                .ConfigureAwait(false);
-        }
-
-        private void WriteFooter(Schema schema)
-        {
-            Builder.Clear();
-
-            long offset = BaseStream.Position;
-
-            // Serialize the schema
-
-            Google.FlatBuffers.Offset<Flatbuf.Schema> schemaOffset = SerializeSchema(schema);
-
-            // Serialize all record batches
-
-            Flatbuf.Footer.StartRecordBatchesVector(Builder, RecordBatchBlocks.Count);
-
-            // flatbuffer struct vectors have to be created in reverse order
-            for (int i = RecordBatchBlocks.Count - 1; i >= 0; i--)
-            {
-                Block recordBatch = RecordBatchBlocks[i];
-                Flatbuf.Block.CreateBlock(
-                    Builder, recordBatch.Offset, recordBatch.MetadataLength, recordBatch.BodyLength);
-            }
-
-            Google.FlatBuffers.VectorOffset recordBatchesVectorOffset = Builder.EndVector();
-
-            // Serialize all dictionaries
-
-            int dictionaryCount = DictionaryBlocks?.Count ?? 0;
-            Flatbuf.Footer.StartDictionariesVector(Builder, dictionaryCount);
-
-            for (int i = dictionaryCount - 1; i >= 0; i--)
-            {
-                Block dictionary = DictionaryBlocks[i];
-                Flatbuf.Block.CreateBlock(
-                    Builder, dictionary.Offset, dictionary.MetadataLength, dictionary.BodyLength);
-            }
-
-            Google.FlatBuffers.VectorOffset dictionaryBatchesOffset = Builder.EndVector();
-
-            // Serialize and write the footer flatbuffer
-
-            Google.FlatBuffers.Offset<Flatbuf.Footer> footerOffset = Flatbuf.Footer.CreateFooter(Builder, CurrentMetadataVersion,
-                schemaOffset, dictionaryBatchesOffset, recordBatchesVectorOffset);
-
-            Builder.Finish(footerOffset.Value);
-
-            WriteFlatBuffer();
-
-            // Write footer length
-
-            using (Buffers.RentReturn(4, out Memory<byte> buffer))
-            {
-                int footerLength;
-                checked
-                {
-                    footerLength = (int)(BaseStream.Position - offset);
-                }
-
-                BinaryPrimitives.WriteInt32LittleEndian(buffer.Span, footerLength);
-
-                BaseStream.Write(buffer);
-            }
-
-            // Write magic
-
-            WriteMagic();
-        }
-
-        private async Task WriteFooterAsync(Schema schema, CancellationToken cancellationToken)
-        {
-            Builder.Clear();
-
-            long offset = BaseStream.Position;
-
-            // Serialize the schema
-
-            Google.FlatBuffers.Offset<Flatbuf.Schema> schemaOffset = SerializeSchema(schema);
-
-            // Serialize all record batches
-
-            Flatbuf.Footer.StartRecordBatchesVector(Builder, RecordBatchBlocks.Count);
-
-            // flatbuffer struct vectors have to be created in reverse order
-            for (int i = RecordBatchBlocks.Count - 1; i >= 0; i--)
-            {
-                Block recordBatch = RecordBatchBlocks[i];
-                Flatbuf.Block.CreateBlock(
-                    Builder, recordBatch.Offset, recordBatch.MetadataLength, recordBatch.BodyLength);
-            }
-
-            Google.FlatBuffers.VectorOffset recordBatchesVectorOffset = Builder.EndVector();
-
-            // Serialize all dictionaries
-
-            int dictionaryCount = DictionaryBlocks?.Count ?? 0;
-            Flatbuf.Footer.StartDictionariesVector(Builder, dictionaryCount);
-
-            for (int i = dictionaryCount - 1; i >= 0; i--)
-            {
-                Block dictionary = DictionaryBlocks[i];
-                Flatbuf.Block.CreateBlock(
-                    Builder, dictionary.Offset, dictionary.MetadataLength, dictionary.BodyLength);
-            }
-
-            Google.FlatBuffers.VectorOffset dictionaryBatchesOffset = Builder.EndVector();
-
-            // Serialize and write the footer flatbuffer
-
-            Google.FlatBuffers.Offset<Flatbuf.Footer> footerOffset = Flatbuf.Footer.CreateFooter(Builder, CurrentMetadataVersion,
-                schemaOffset, dictionaryBatchesOffset, recordBatchesVectorOffset);
-
-            Builder.Finish(footerOffset.Value);
-
-            cancellationToken.ThrowIfCancellationRequested();
-
-            await WriteFlatBufferAsync(cancellationToken).ConfigureAwait(false);
-
-            // Write footer length
-
-            cancellationToken.ThrowIfCancellationRequested();
-
-            using (Buffers.RentReturn(4, out Memory<byte> buffer))
-            {
-                int footerLength;
-                checked
-                {
-                    footerLength = (int)(BaseStream.Position - offset);
-                }
-
-                BinaryPrimitives.WriteInt32LittleEndian(buffer.Span, footerLength);
-
-                await BaseStream.WriteAsync(buffer, cancellationToken).ConfigureAwait(false);
-            }
-
-            // Write magic
-
-            await WriteMagicAsync(cancellationToken).ConfigureAwait(false);
-        }
-
-        private void WriteMagic()
-        {
-            BaseStream.Write(ArrowFileConstants.Magic);
-        }
-
-        private ValueTask WriteMagicAsync(CancellationToken cancellationToken)
-        {
-            return BaseStream.WriteAsync(ArrowFileConstants.Magic, cancellationToken);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowFooter.cs b/csharp/src/Apache.Arrow/Ipc/ArrowFooter.cs
deleted file mode 100644
index 600624e..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ArrowFooter.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-
-namespace Apache.Arrow.Ipc
-{
-    internal class ArrowFooter
-    {
-        public Schema Schema { get; }
-        private readonly List<Block> _dictionaries;
-        private readonly List<Block> _recordBatches;
-
-        public IReadOnlyList<Block> Dictionaries => _dictionaries;
-        public IReadOnlyList<Block> RecordBatches => _recordBatches;
-
-        public Block GetRecordBatchBlock(int i) => _recordBatches[i];
-
-        public Block GetDictionaryBlock(int i) => _dictionaries[i];
-
-        public int RecordBatchCount => _recordBatches.Count;
-        public int DictionaryCount => _dictionaries.Count;
-
-        public ArrowFooter(Schema schema, IEnumerable<Block> dictionaries, IEnumerable<Block> recordBatches)
-        {
-            Schema = schema;
-
-            _dictionaries = dictionaries.ToList();
-            _recordBatches = recordBatches.ToList();
-
-#if DEBUG
-            for (int i = 0; i < _dictionaries.Count; i++)
-            {
-                Block block = _dictionaries[i];
-                Debug.Assert(BitUtility.IsMultipleOf8(block.Offset));
-                Debug.Assert(BitUtility.IsMultipleOf8(block.MetadataLength));
-                Debug.Assert(BitUtility.IsMultipleOf8(block.BodyLength));
-            }
-
-            for (int i = 0; i < _recordBatches.Count; i++)
-            {
-                Block block = _recordBatches[i];
-                Debug.Assert(BitUtility.IsMultipleOf8(block.Offset));
-                Debug.Assert(BitUtility.IsMultipleOf8(block.MetadataLength));
-                Debug.Assert(BitUtility.IsMultipleOf8(block.BodyLength));
-            }
-#endif
-        }
-
-        public ArrowFooter(Flatbuf.Footer footer, ref DictionaryMemo dictionaryMemo)
-            : this(Ipc.MessageSerializer.GetSchema(footer.Schema.GetValueOrDefault(), ref dictionaryMemo), GetDictionaries(footer),
-                GetRecordBatches(footer))
-        { }
-
-        private static IEnumerable<Block> GetDictionaries(Flatbuf.Footer footer)
-        {
-            for (int i = 0; i < footer.DictionariesLength; i++)
-            {
-                Flatbuf.Block? block = footer.Dictionaries(i);
-
-                if (block.HasValue)
-                {
-                    yield return new Block(block.Value);
-                }
-            }
-        }
-
-        private static IEnumerable<Block> GetRecordBatches(Flatbuf.Footer footer)
-        {
-            for (int i = 0; i < footer.RecordBatchesLength; i++)
-            {
-                Flatbuf.Block? block = footer.RecordBatches(i);
-
-                if (block.HasValue)
-                {
-                    yield return new Block(block.Value);
-                }
-            }
-        }
-
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowMemoryReaderImplementation.cs b/csharp/src/Apache.Arrow/Ipc/ArrowMemoryReaderImplementation.cs
deleted file mode 100644
index 842c568..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ArrowMemoryReaderImplementation.cs
+++ /dev/null
@@ -1,131 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Flatbuf;
-using Google.FlatBuffers;
-using System;
-using System.Buffers.Binary;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.Ipc
-{
-    internal sealed class ArrowMemoryReaderImplementation : ArrowReaderImplementation
-    {
-        private readonly ReadOnlyMemory<byte> _buffer;
-        private int _bufferPosition;
-
-        public ArrowMemoryReaderImplementation(ReadOnlyMemory<byte> buffer, ICompressionCodecFactory compressionCodecFactory) : base(null, compressionCodecFactory)
-        {
-            _buffer = buffer;
-        }
-
-        public override ValueTask ReadSchemaAsync(CancellationToken cancellationToken)
-        {
-            cancellationToken.ThrowIfCancellationRequested();
-            ReadSchema();
-            return default;
-        }
-
-        public override ValueTask<RecordBatch> ReadNextRecordBatchAsync(CancellationToken cancellationToken)
-        {
-            cancellationToken.ThrowIfCancellationRequested();
-            return new ValueTask<RecordBatch>(ReadNextRecordBatch());
-        }
-
-        public override RecordBatch ReadNextRecordBatch()
-        {
-            ReadSchema();
-
-            RecordBatch batch = null;
-            while (batch == null)
-            {
-                if (_buffer.Length <= _bufferPosition + sizeof(int))
-                {
-                    // reached the end
-                    return null;
-                }
-
-                // Get Length of record batch for message header.
-                int messageLength = BinaryPrimitives.ReadInt32LittleEndian(_buffer.Span.Slice(_bufferPosition));
-                _bufferPosition += sizeof(int);
-
-                if (messageLength == 0)
-                {
-                    //reached the end
-                    return null;
-                }
-                else if (messageLength == MessageSerializer.IpcContinuationToken)
-                {
-                    // ARROW-6313, if the first 4 bytes are continuation message, read the next 4 for the length
-                    if (_buffer.Length <= _bufferPosition + sizeof(int))
-                    {
-                        throw new InvalidDataException("Corrupted IPC message. Received a continuation token at the end of the message.");
-                    }
-
-                    messageLength = BinaryPrimitives.ReadInt32LittleEndian(_buffer.Span.Slice(_bufferPosition));
-                    _bufferPosition += sizeof(int);
-
-                    if (messageLength == 0)
-                    {
-                        //reached the end
-                        return null;
-                    }
-                }
-
-                Message message = Message.GetRootAsMessage(
-                    CreateByteBuffer(_buffer.Slice(_bufferPosition, messageLength)));
-                _bufferPosition += messageLength;
-
-                int bodyLength = (int)message.BodyLength;
-                ByteBuffer bodybb = CreateByteBuffer(_buffer.Slice(_bufferPosition, bodyLength));
-                _bufferPosition += bodyLength;
-
-                batch = CreateArrowObjectFromMessage(message, bodybb, memoryOwner: null);
-            }
-
-            return batch;
-        }
-
-        public override void ReadSchema()
-        {
-            if (HasReadSchema)
-            {
-                return;
-            }
-
-            // Figure out length of schema
-            int schemaMessageLength = BinaryPrimitives.ReadInt32LittleEndian(_buffer.Span.Slice(_bufferPosition));
-            _bufferPosition += sizeof(int);
-
-            if (schemaMessageLength == MessageSerializer.IpcContinuationToken)
-            {
-                // ARROW-6313, if the first 4 bytes are continuation message, read the next 4 for the length
-                if (_buffer.Length <= _bufferPosition + sizeof(int))
-                {
-                    throw new InvalidDataException("Corrupted IPC message. Received a continuation token at the end of the message.");
-                }
-
-                schemaMessageLength = BinaryPrimitives.ReadInt32LittleEndian(_buffer.Span.Slice(_bufferPosition));
-                _bufferPosition += sizeof(int);
-            }
-
-            ByteBuffer schemaBuffer = CreateByteBuffer(_buffer.Slice(_bufferPosition));
-            _schema = MessageSerializer.GetSchema(ReadMessage<Flatbuf.Schema>(schemaBuffer), ref _dictionaryMemo);
-            _bufferPosition += schemaMessageLength;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowReaderImplementation.cs b/csharp/src/Apache.Arrow/Ipc/ArrowReaderImplementation.cs
deleted file mode 100644
index 7e76667..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ArrowReaderImplementation.cs
+++ /dev/null
@@ -1,401 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flatbuf;
-using Apache.Arrow.Types;
-using Apache.Arrow.Memory;
-using Google.FlatBuffers;
-using Type = System.Type;
-
-namespace Apache.Arrow.Ipc
-{
-    internal abstract class ArrowReaderImplementation : IDisposable
-    {
-        public Schema Schema
-        {
-            get
-            {
-                if (!HasReadSchema)
-                {
-                    ReadSchema();
-                }
-                return _schema;
-            }
-        }
-
-        protected internal bool HasReadSchema => _schema != null;
-
-        private protected DictionaryMemo _dictionaryMemo;
-        private protected DictionaryMemo DictionaryMemo => _dictionaryMemo ??= new DictionaryMemo();
-        private protected readonly MemoryAllocator _allocator;
-        private readonly ICompressionCodecFactory _compressionCodecFactory;
-        private protected Schema _schema;
-
-        private protected ArrowReaderImplementation() : this(null, null)
-        { }
-
-        private protected ArrowReaderImplementation(MemoryAllocator allocator, ICompressionCodecFactory compressionCodecFactory)
-        {
-            _allocator = allocator ?? MemoryAllocator.Default.Value;
-            _compressionCodecFactory = compressionCodecFactory;
-        }
-
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-        }
-
-        public abstract ValueTask ReadSchemaAsync(CancellationToken cancellationToken);
-        public abstract void ReadSchema();
-
-        public abstract ValueTask<RecordBatch> ReadNextRecordBatchAsync(CancellationToken cancellationToken);
-        public abstract RecordBatch ReadNextRecordBatch();
-
-        internal static T ReadMessage<T>(ByteBuffer bb)
-            where T : struct, IFlatbufferObject
-        {
-            Type returnType = typeof(T);
-            Flatbuf.Message msg = Flatbuf.Message.GetRootAsMessage(bb);
-
-            if (MatchEnum(msg.HeaderType, returnType))
-            {
-                return msg.Header<T>().Value;
-            }
-            else
-            {
-                throw new Exception($"Requested type '{returnType.Name}' " +
-                                    $"did not match type found at offset => '{msg.HeaderType}'");
-            }
-        }
-
-        private static bool MatchEnum(Flatbuf.MessageHeader messageHeader, Type flatBuffType)
-        {
-            switch (messageHeader)
-            {
-                case Flatbuf.MessageHeader.RecordBatch:
-                    return flatBuffType == typeof(Flatbuf.RecordBatch);
-                case Flatbuf.MessageHeader.DictionaryBatch:
-                    return flatBuffType == typeof(Flatbuf.DictionaryBatch);
-                case Flatbuf.MessageHeader.Schema:
-                    return flatBuffType == typeof(Flatbuf.Schema);
-                case Flatbuf.MessageHeader.Tensor:
-                    return flatBuffType == typeof(Flatbuf.Tensor);
-                case Flatbuf.MessageHeader.NONE:
-                    throw new ArgumentException("MessageHeader NONE has no matching flatbuf types", nameof(messageHeader));
-                default:
-                    throw new ArgumentException($"Unexpected MessageHeader value", nameof(messageHeader));
-            }
-        }
-
-        /// <summary>
-        /// Create a record batch or dictionary batch from Flatbuf.Message.
-        /// </summary>
-        /// <remarks>
-        /// This method adds data to _dictionaryMemo and returns null when the message type is DictionaryBatch.
-        /// </remarks>>
-        /// <returns>
-        /// The record batch when the message type is RecordBatch.
-        /// Null when the message type is not RecordBatch.
-        /// </returns>
-        protected RecordBatch CreateArrowObjectFromMessage(
-            Flatbuf.Message message, ByteBuffer bodyByteBuffer, IMemoryOwner<byte> memoryOwner)
-        {
-            switch (message.HeaderType)
-            {
-                case Flatbuf.MessageHeader.Schema:
-                    // TODO: Read schema and verify equality?
-                    break;
-                case Flatbuf.MessageHeader.DictionaryBatch:
-                    Flatbuf.DictionaryBatch dictionaryBatch = message.Header<Flatbuf.DictionaryBatch>().Value;
-                    ReadDictionaryBatch(message.Version, dictionaryBatch, bodyByteBuffer, memoryOwner);
-                    break;
-                case Flatbuf.MessageHeader.RecordBatch:
-                    Flatbuf.RecordBatch rb = message.Header<Flatbuf.RecordBatch>().Value;
-                    List<IArrowArray> arrays = BuildArrays(message.Version, Schema, bodyByteBuffer, rb);
-                    return new RecordBatch(Schema, memoryOwner, arrays, (int)rb.Length);
-                default:
-                    // NOTE: Skip unsupported message type
-                    Debug.WriteLine($"Skipping unsupported message type '{message.HeaderType}'");
-                    break;
-            }
-
-            return null;
-        }
-
-        internal static ByteBuffer CreateByteBuffer(ReadOnlyMemory<byte> buffer)
-        {
-            return new ByteBuffer(new ReadOnlyMemoryBufferAllocator(buffer), 0);
-        }
-
-        private void ReadDictionaryBatch(
-            MetadataVersion version,
-            Flatbuf.DictionaryBatch dictionaryBatch,
-            ByteBuffer bodyByteBuffer,
-            IMemoryOwner<byte> memoryOwner)
-        {
-            long id = dictionaryBatch.Id;
-            IArrowType valueType = DictionaryMemo.GetDictionaryType(id);
-            Flatbuf.RecordBatch? recordBatch = dictionaryBatch.Data;
-
-            if (!recordBatch.HasValue)
-            {
-                throw new InvalidDataException("Dictionary must contain RecordBatch");
-            }
-
-            Field valueField = new Field("dummy", valueType, true);
-            var schema = new Schema(new[] { valueField }, default);
-            IList<IArrowArray> arrays = BuildArrays(version, schema, bodyByteBuffer, recordBatch.Value);
-
-            if (arrays.Count != 1)
-            {
-                throw new InvalidDataException("Dictionary record batch must contain only one field");
-            }
-
-            if (dictionaryBatch.IsDelta)
-            {
-                DictionaryMemo.AddDeltaDictionary(id, arrays[0], _allocator);
-            }
-            else
-            {
-                DictionaryMemo.AddOrReplaceDictionary(id, arrays[0]);
-            }
-        }
-
-        private List<IArrowArray> BuildArrays(
-            MetadataVersion version,
-            Schema schema,
-            ByteBuffer messageBuffer,
-            Flatbuf.RecordBatch recordBatchMessage)
-        {
-            var arrays = new List<IArrowArray>(recordBatchMessage.NodesLength);
-
-            if (recordBatchMessage.NodesLength == 0)
-            {
-                return arrays;
-            }
-
-            using var bufferCreator = GetBufferCreator(recordBatchMessage.Compression);
-            var recordBatchEnumerator = new RecordBatchEnumerator(in recordBatchMessage);
-            int schemaFieldIndex = 0;
-            do
-            {
-                Field field = schema.GetFieldByIndex(schemaFieldIndex++);
-                Flatbuf.FieldNode fieldNode = recordBatchEnumerator.CurrentNode;
-
-                ArrayData arrayData = LoadField(version, ref recordBatchEnumerator, field, in fieldNode, messageBuffer, bufferCreator);
-
-                arrays.Add(ArrowArrayFactory.BuildArray(arrayData));
-            } while (recordBatchEnumerator.MoveNextNode());
-
-            return arrays;
-        }
-
-        private IBufferCreator GetBufferCreator(BodyCompression? compression)
-        {
-            if (!compression.HasValue)
-            {
-                return NoOpBufferCreator.Instance;
-            }
-
-            var method = compression.Value.Method;
-            if (method != BodyCompressionMethod.BUFFER)
-            {
-                throw new NotImplementedException($"Compression method {method} is not supported");
-            }
-
-            var codec = compression.Value.Codec;
-            if (_compressionCodecFactory == null)
-            {
-                throw new Exception(
-                    $"Body is compressed with codec {codec} but no {nameof(ICompressionCodecFactory)} has been configured to decompress buffers");
-            }
-            var decompressor = codec switch
-            {
-                Apache.Arrow.Flatbuf.CompressionType.LZ4_FRAME => _compressionCodecFactory.CreateCodec(CompressionCodecType.Lz4Frame),
-                Apache.Arrow.Flatbuf.CompressionType.ZSTD => _compressionCodecFactory.CreateCodec(CompressionCodecType.Zstd),
-                _ => throw new NotImplementedException($"Compression codec {codec} is not supported")
-            };
-            return new DecompressingBufferCreator(decompressor, _allocator);
-        }
-
-        private ArrayData LoadField(
-            MetadataVersion version,
-            ref RecordBatchEnumerator recordBatchEnumerator,
-            Field field,
-            in Flatbuf.FieldNode fieldNode,
-            ByteBuffer bodyData,
-            IBufferCreator bufferCreator)
-        {
-
-            int fieldLength = (int)fieldNode.Length;
-            int fieldNullCount = (int)fieldNode.NullCount;
-
-            if (fieldLength < 0)
-            {
-                throw new InvalidDataException("Field length must be >= 0"); // TODO:Localize exception message
-            }
-
-            if (fieldNullCount < 0)
-            {
-                throw new InvalidDataException("Null count must be >= 0"); // TODO:Localize exception message
-            }
-
-            int buffers;
-            switch (field.DataType.TypeId)
-            {
-                case ArrowTypeId.Null:
-                    return new ArrayData(field.DataType, fieldLength, fieldNullCount, 0, System.Array.Empty<ArrowBuffer>());
-                case ArrowTypeId.Union:
-                    if (version < MetadataVersion.V5)
-                    {
-                        if (fieldNullCount > 0)
-                        {
-                            if (recordBatchEnumerator.CurrentBuffer.Length > 0)
-                            {
-                                // With older metadata we can get a validity bitmap. Fixing up union data is hard,
-                                // so we will just quit.
-                                throw new NotSupportedException("Cannot read pre-1.0.0 Union array with top-level validity bitmap");
-                            }
-                        }
-                        recordBatchEnumerator.MoveNextBuffer();
-                    }
-                    buffers = ((UnionType)field.DataType).Mode == Types.UnionMode.Dense ? 2 : 1;
-                    break;
-                case ArrowTypeId.Struct:
-                case ArrowTypeId.FixedSizeList:
-                    buffers = 1;
-                    break;
-                case ArrowTypeId.String:
-                case ArrowTypeId.Binary:
-                case ArrowTypeId.LargeString:
-                case ArrowTypeId.LargeBinary:
-                case ArrowTypeId.ListView:
-                    buffers = 3;
-                    break;
-                case ArrowTypeId.StringView:
-                case ArrowTypeId.BinaryView:
-                    buffers = checked((int)(2 + recordBatchEnumerator.CurrentVariadicCount));
-                    recordBatchEnumerator.MoveNextVariadicCount();
-                    break;
-                default:
-                    buffers = 2;
-                    break;
-            }
-
-            ArrowBuffer[] arrowBuff = new ArrowBuffer[buffers];
-            for (int i = 0; i < buffers; i++)
-            {
-                arrowBuff[i] = BuildArrowBuffer(bodyData, recordBatchEnumerator.CurrentBuffer, bufferCreator);
-                recordBatchEnumerator.MoveNextBuffer();
-            }
-
-            ArrayData[] children = GetChildren(version, ref recordBatchEnumerator, field, bodyData, bufferCreator);
-
-            IArrowArray dictionary = null;
-            if (field.DataType.TypeId == ArrowTypeId.Dictionary)
-            {
-                long id = DictionaryMemo.GetId(field);
-                dictionary = DictionaryMemo.GetDictionary(id);
-            }
-
-            return new ArrayData(field.DataType, fieldLength, fieldNullCount, 0, arrowBuff, children, dictionary?.Data);
-        }
-
-        private ArrayData[] GetChildren(
-            MetadataVersion version,
-            ref RecordBatchEnumerator recordBatchEnumerator,
-            Field field,
-            ByteBuffer bodyData,
-            IBufferCreator bufferCreator)
-        {
-            if (!(field.DataType is NestedType type)) return null;
-
-            int childrenCount = type.Fields.Count;
-            var children = new ArrayData[childrenCount];
-            for (int index = 0; index < childrenCount; index++)
-            {
-                recordBatchEnumerator.MoveNextNode();
-                Flatbuf.FieldNode childFieldNode = recordBatchEnumerator.CurrentNode;
-
-                Field childField = type.Fields[index];
-                children[index] = LoadField(version, ref recordBatchEnumerator, childField, in childFieldNode, bodyData, bufferCreator);
-            }
-            return children;
-        }
-
-        private ArrowBuffer BuildArrowBuffer(ByteBuffer bodyData, Flatbuf.Buffer buffer, IBufferCreator bufferCreator)
-        {
-            if (buffer.Length <= 0)
-            {
-                return ArrowBuffer.Empty;
-            }
-
-            int offset = (int)buffer.Offset;
-            int length = (int)buffer.Length;
-
-            var data = bodyData.ToReadOnlyMemory(offset, length);
-            return bufferCreator.CreateBuffer(data);
-        }
-    }
-
-    internal struct RecordBatchEnumerator
-    {
-        private Flatbuf.RecordBatch RecordBatch { get; }
-        internal int CurrentBufferIndex { get; private set; }
-        internal int CurrentNodeIndex { get; private set; }
-        internal int CurrentVariadicCountIndex { get; private set; }
-
-        internal Flatbuf.Buffer CurrentBuffer => RecordBatch.Buffers(CurrentBufferIndex).GetValueOrDefault();
-
-        internal Flatbuf.FieldNode CurrentNode => RecordBatch.Nodes(CurrentNodeIndex).GetValueOrDefault();
-
-        internal long CurrentVariadicCount => RecordBatch.VariadicBufferCounts(CurrentVariadicCountIndex);
-
-        internal bool MoveNextBuffer()
-        {
-            return ++CurrentBufferIndex < RecordBatch.BuffersLength;
-        }
-
-        internal bool MoveNextNode()
-        {
-            return ++CurrentNodeIndex < RecordBatch.NodesLength;
-        }
-
-        internal bool MoveNextVariadicCount()
-        {
-            return ++CurrentVariadicCountIndex < RecordBatch.VariadicBufferCountsLength;
-        }
-
-        internal RecordBatchEnumerator(in Flatbuf.RecordBatch recordBatch)
-        {
-            RecordBatch = recordBatch;
-            CurrentBufferIndex = 0;
-            CurrentNodeIndex = 0;
-            CurrentVariadicCountIndex = 0;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowStreamReader.cs b/csharp/src/Apache.Arrow/Ipc/ArrowStreamReader.cs
deleted file mode 100644
index e129da3..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ArrowStreamReader.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using System;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.Ipc
-{
-    /// <summary>
-    /// Represents a reader that can read Arrow streams.
-    /// </summary>
-    public class ArrowStreamReader : IArrowReader, IArrowArrayStream, IDisposable
-    {
-        private protected readonly ArrowReaderImplementation _implementation;
-
-        /// <summary>
-        /// May block if the schema hasn't yet been read. To avoid blocking, use GetSchemaAsync.
-        /// </summary>
-        public Schema Schema => _implementation.Schema;
-
-        public ArrowStreamReader(Stream stream)
-            : this(stream, allocator: null, compressionCodecFactory: null, leaveOpen: false)
-        {
-        }
-
-        public ArrowStreamReader(Stream stream, MemoryAllocator allocator)
-            : this(stream, allocator, compressionCodecFactory: null, leaveOpen: false)
-        {
-        }
-
-        public ArrowStreamReader(Stream stream, ICompressionCodecFactory compressionCodecFactory)
-            : this(stream, allocator: null, compressionCodecFactory, leaveOpen: false)
-        {
-        }
-
-        public ArrowStreamReader(Stream stream, bool leaveOpen)
-            : this(stream, allocator: null, compressionCodecFactory: null, leaveOpen)
-        {
-        }
-
-        public ArrowStreamReader(Stream stream, MemoryAllocator allocator, bool leaveOpen)
-            : this(stream, allocator, compressionCodecFactory: null, leaveOpen)
-        {
-        }
-
-        public ArrowStreamReader(Stream stream, ICompressionCodecFactory compressionCodecFactory, bool leaveOpen)
-            : this(stream, allocator: null, compressionCodecFactory, leaveOpen)
-        {
-        }
-
-        public ArrowStreamReader(Stream stream, MemoryAllocator allocator, ICompressionCodecFactory compressionCodecFactory, bool leaveOpen)
-        {
-            if (stream == null)
-                throw new ArgumentNullException(nameof(stream));
-
-            _implementation = new ArrowStreamReaderImplementation(stream, allocator, compressionCodecFactory, leaveOpen);
-        }
-
-        public ArrowStreamReader(ReadOnlyMemory<byte> buffer)
-        {
-            _implementation = new ArrowMemoryReaderImplementation(buffer, compressionCodecFactory: null);
-        }
-
-        public ArrowStreamReader(ReadOnlyMemory<byte> buffer, ICompressionCodecFactory compressionCodecFactory)
-        {
-            _implementation = new ArrowMemoryReaderImplementation(buffer, compressionCodecFactory);
-        }
-
-        private protected ArrowStreamReader(ArrowReaderImplementation implementation)
-        {
-            _implementation = implementation;
-        }
-
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                _implementation.Dispose();
-            }
-        }
-
-        public async ValueTask<Schema> GetSchema(CancellationToken cancellationToken = default)
-        {
-            if (!_implementation.HasReadSchema)
-            {
-                await _implementation.ReadSchemaAsync(cancellationToken);
-            }
-            return _implementation.Schema;
-        }
-
-        public ValueTask<RecordBatch> ReadNextRecordBatchAsync(CancellationToken cancellationToken = default)
-        {
-            return _implementation.ReadNextRecordBatchAsync(cancellationToken);
-        }
-
-        public RecordBatch ReadNextRecordBatch()
-        {
-            return _implementation.ReadNextRecordBatch();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowStreamReaderImplementation.cs b/csharp/src/Apache.Arrow/Ipc/ArrowStreamReaderImplementation.cs
deleted file mode 100644
index 23a14d8..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ArrowStreamReaderImplementation.cs
+++ /dev/null
@@ -1,313 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using System;
-using System.Buffers;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.Ipc
-{
-    internal class ArrowStreamReaderImplementation : ArrowReaderImplementation
-    {
-        public Stream BaseStream { get; }
-        private readonly bool _leaveOpen;
-
-        public ArrowStreamReaderImplementation(Stream stream, MemoryAllocator allocator, ICompressionCodecFactory compressionCodecFactory, bool leaveOpen) : base(allocator, compressionCodecFactory)
-        {
-            BaseStream = stream;
-            _leaveOpen = leaveOpen;
-        }
-
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing && !_leaveOpen)
-            {
-                BaseStream.Dispose();
-            }
-        }
-
-        public override async ValueTask<RecordBatch> ReadNextRecordBatchAsync(CancellationToken cancellationToken)
-        {
-            // TODO: Loop until a record batch is read.
-            cancellationToken.ThrowIfCancellationRequested();
-            return await ReadRecordBatchAsync(cancellationToken).ConfigureAwait(false);
-        }
-
-        public override RecordBatch ReadNextRecordBatch()
-        {
-            return ReadRecordBatch();
-        }
-
-        protected async ValueTask<RecordBatch> ReadRecordBatchAsync(CancellationToken cancellationToken = default)
-        {
-            await ReadSchemaAsync().ConfigureAwait(false);
-
-            ReadResult result = default;
-            do
-            {
-                result = await ReadMessageAsync(cancellationToken).ConfigureAwait(false);
-            } while (result.Batch == null && result.MessageLength > 0);
-
-            return result.Batch;
-        }
-
-        protected async ValueTask<ReadResult> ReadMessageAsync(CancellationToken cancellationToken)
-        {
-            int messageLength = await ReadMessageLengthAsync(throwOnFullRead: false, returnOnEmptyStream: false, cancellationToken)
-                .ConfigureAwait(false);
-
-            if (messageLength == 0)
-            {
-                // reached end
-                return default;
-            }
-
-            RecordBatch result = null;
-            using (ArrayPool<byte>.Shared.RentReturn(messageLength, out Memory<byte> messageBuff))
-            {
-                int bytesRead = await BaseStream.ReadFullBufferAsync(messageBuff, cancellationToken)
-                    .ConfigureAwait(false);
-                EnsureFullRead(messageBuff, bytesRead);
-
-                Flatbuf.Message message = Flatbuf.Message.GetRootAsMessage(CreateByteBuffer(messageBuff));
-
-                int bodyLength = checked((int)message.BodyLength);
-
-                IMemoryOwner<byte> bodyBuffOwner = _allocator.Allocate(bodyLength);
-                Memory<byte> bodyBuff = bodyBuffOwner.Memory.Slice(0, bodyLength);
-                bytesRead = await BaseStream.ReadFullBufferAsync(bodyBuff, cancellationToken)
-                    .ConfigureAwait(false);
-                EnsureFullRead(bodyBuff, bytesRead);
-
-                Google.FlatBuffers.ByteBuffer bodybb = CreateByteBuffer(bodyBuff);
-                result = CreateArrowObjectFromMessage(message, bodybb, bodyBuffOwner);
-            }
-
-            return new ReadResult(messageLength, result);
-        }
-
-        protected RecordBatch ReadRecordBatch()
-        {
-            ReadSchema();
-
-            ReadResult result = default;
-            do
-            {
-                result = ReadMessage();
-            } while (result.Batch == null && result.MessageLength > 0);
-
-            return result.Batch;
-        }
-
-        protected ReadResult ReadMessage()
-        {
-            int messageLength = ReadMessageLength(throwOnFullRead: false, returnOnEmptyStream: false);
-            if (messageLength == 0)
-            {
-                // reached end
-                return default;
-            }
-
-            RecordBatch result = null;
-            using (ArrayPool<byte>.Shared.RentReturn(messageLength, out Memory<byte> messageBuff))
-            {
-                int bytesRead = BaseStream.ReadFullBuffer(messageBuff);
-                EnsureFullRead(messageBuff, bytesRead);
-
-                Flatbuf.Message message = Flatbuf.Message.GetRootAsMessage(CreateByteBuffer(messageBuff));
-
-                if (message.BodyLength > int.MaxValue)
-                {
-                    throw new OverflowException(
-                        $"Arrow IPC message body length ({message.BodyLength}) is larger than " +
-                        $"the maximum supported message size ({int.MaxValue})");
-                }
-                int bodyLength = (int)message.BodyLength;
-
-                IMemoryOwner<byte> bodyBuffOwner = _allocator.Allocate(bodyLength);
-                Memory<byte> bodyBuff = bodyBuffOwner.Memory.Slice(0, bodyLength);
-                bytesRead = BaseStream.ReadFullBuffer(bodyBuff);
-                EnsureFullRead(bodyBuff, bytesRead);
-
-                Google.FlatBuffers.ByteBuffer bodybb = CreateByteBuffer(bodyBuff);
-                result = CreateArrowObjectFromMessage(message, bodybb, bodyBuffOwner);
-            }
-
-            return new ReadResult(messageLength, result);
-        }
-
-        public override async ValueTask ReadSchemaAsync(CancellationToken cancellationToken = default)
-        {
-            if (HasReadSchema)
-            {
-                return;
-            }
-
-            // Figure out length of schema
-            int schemaMessageLength = await ReadMessageLengthAsync(throwOnFullRead: true, returnOnEmptyStream: true, cancellationToken)
-                .ConfigureAwait(false);
-            if (schemaMessageLength == 0)
-            {
-                return;
-            }
-
-            using (ArrayPool<byte>.Shared.RentReturn(schemaMessageLength, out Memory<byte> buff))
-            {
-                // Read in schema
-                int bytesRead = await BaseStream.ReadFullBufferAsync(buff, cancellationToken).ConfigureAwait(false);
-                EnsureFullRead(buff, bytesRead);
-
-                Google.FlatBuffers.ByteBuffer schemabb = CreateByteBuffer(buff);
-                _schema = MessageSerializer.GetSchema(ReadMessage<Flatbuf.Schema>(schemabb), ref _dictionaryMemo);
-            }
-        }
-
-        public override void ReadSchema()
-        {
-            if (HasReadSchema)
-            {
-                return;
-            }
-
-            // Figure out length of schema
-            int schemaMessageLength = ReadMessageLength(throwOnFullRead: true, returnOnEmptyStream: true);
-            if (schemaMessageLength == 0)
-            {
-                return;
-            }
-
-            using (ArrayPool<byte>.Shared.RentReturn(schemaMessageLength, out Memory<byte> buff))
-            {
-                int bytesRead = BaseStream.ReadFullBuffer(buff);
-                EnsureFullRead(buff, bytesRead);
-
-                Google.FlatBuffers.ByteBuffer schemabb = CreateByteBuffer(buff);
-                _schema = MessageSerializer.GetSchema(ReadMessage<Flatbuf.Schema>(schemabb), ref _dictionaryMemo);
-            }
-        }
-
-        private async ValueTask<int> ReadMessageLengthAsync(bool throwOnFullRead, bool returnOnEmptyStream, CancellationToken cancellationToken = default)
-        {
-            int messageLength = 0;
-            using (ArrayPool<byte>.Shared.RentReturn(4, out Memory<byte> lengthBuffer))
-            {
-                int bytesRead = await BaseStream.ReadFullBufferAsync(lengthBuffer, cancellationToken)
-                    .ConfigureAwait(false);
-                if (bytesRead == 0 && returnOnEmptyStream)
-                {
-                    return 0;
-                }
-                if (throwOnFullRead)
-                {
-                    EnsureFullRead(lengthBuffer, bytesRead);
-                }
-                else if (bytesRead != 4)
-                {
-                    return 0;
-                }
-
-                messageLength = BitUtility.ReadInt32(lengthBuffer);
-
-                // ARROW-6313, if the first 4 bytes are continuation message, read the next 4 for the length
-                if (messageLength == MessageSerializer.IpcContinuationToken)
-                {
-                    bytesRead = await BaseStream.ReadFullBufferAsync(lengthBuffer, cancellationToken)
-                        .ConfigureAwait(false);
-                    if (throwOnFullRead)
-                    {
-                        EnsureFullRead(lengthBuffer, bytesRead);
-                    }
-                    else if (bytesRead != 4)
-                    {
-                        return 0;
-                    }
-
-                    messageLength = BitUtility.ReadInt32(lengthBuffer);
-                }
-            };
-
-            return messageLength;
-        }
-
-        private int ReadMessageLength(bool throwOnFullRead, bool returnOnEmptyStream)
-        {
-            int messageLength = 0;
-            using (ArrayPool<byte>.Shared.RentReturn(4, out Memory<byte> lengthBuffer))
-            {
-                int bytesRead = BaseStream.ReadFullBuffer(lengthBuffer);
-                if (bytesRead == 0 && returnOnEmptyStream)
-                {
-                    return 0;
-                }
-                if (throwOnFullRead)
-                {
-                    EnsureFullRead(lengthBuffer, bytesRead);
-                }
-                else if (bytesRead != 4)
-                {
-                    return 0;
-                }
-
-                messageLength = BitUtility.ReadInt32(lengthBuffer);
-
-                // ARROW-6313, if the first 4 bytes are continuation message, read the next 4 for the length
-                if (messageLength == MessageSerializer.IpcContinuationToken)
-                {
-                    bytesRead = BaseStream.ReadFullBuffer(lengthBuffer);
-                    if (throwOnFullRead)
-                    {
-                        EnsureFullRead(lengthBuffer, bytesRead);
-                    }
-                    else if (bytesRead != 4)
-                    {
-                        return 0;
-                    }
-
-                    messageLength = BitUtility.ReadInt32(lengthBuffer);
-                }
-            }
-
-            return messageLength;
-        }
-
-        /// <summary>
-        /// Ensures the number of bytes read matches the buffer length
-        /// and throws an exception it if doesn't. This ensures we have read
-        /// a full buffer from the stream.
-        /// </summary>
-        internal static void EnsureFullRead(Memory<byte> buffer, int bytesRead)
-        {
-            if (bytesRead != buffer.Length)
-            {
-                throw new InvalidOperationException("Unexpectedly reached the end of the stream before a full buffer was read.");
-            }
-        }
-
-        internal struct ReadResult
-        {
-            public readonly int MessageLength;
-            public readonly RecordBatch Batch;
-
-            public ReadResult(int messageLength, RecordBatch batch)
-            {
-                MessageLength = messageLength;
-                Batch = batch;
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowStreamWriter.cs b/csharp/src/Apache.Arrow/Ipc/ArrowStreamWriter.cs
deleted file mode 100644
index f317093..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ArrowStreamWriter.cs
+++ /dev/null
@@ -1,1417 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.Buffers.Binary;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Arrays;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-using Google.FlatBuffers;
-
-namespace Apache.Arrow.Ipc
-{
-    public class ArrowStreamWriter : IDisposable
-    {
-        private class ArrowRecordBatchFlatBufferBuilder :
-            IArrowArrayVisitor<Int8Array>,
-            IArrowArrayVisitor<Int16Array>,
-            IArrowArrayVisitor<Int32Array>,
-            IArrowArrayVisitor<Int64Array>,
-            IArrowArrayVisitor<UInt8Array>,
-            IArrowArrayVisitor<UInt16Array>,
-            IArrowArrayVisitor<UInt32Array>,
-            IArrowArrayVisitor<UInt64Array>,
-#if NET5_0_OR_GREATER
-            IArrowArrayVisitor<HalfFloatArray>,
-#endif
-            IArrowArrayVisitor<FloatArray>,
-            IArrowArrayVisitor<DoubleArray>,
-            IArrowArrayVisitor<BooleanArray>,
-            IArrowArrayVisitor<TimestampArray>,
-            IArrowArrayVisitor<Date32Array>,
-            IArrowArrayVisitor<Date64Array>,
-            IArrowArrayVisitor<Time32Array>,
-            IArrowArrayVisitor<Time64Array>,
-            IArrowArrayVisitor<DurationArray>,
-            IArrowArrayVisitor<YearMonthIntervalArray>,
-            IArrowArrayVisitor<DayTimeIntervalArray>,
-            IArrowArrayVisitor<MonthDayNanosecondIntervalArray>,
-            IArrowArrayVisitor<ListArray>,
-            IArrowArrayVisitor<ListViewArray>,
-            IArrowArrayVisitor<LargeListArray>,
-            IArrowArrayVisitor<FixedSizeListArray>,
-            IArrowArrayVisitor<StringArray>,
-            IArrowArrayVisitor<StringViewArray>,
-            IArrowArrayVisitor<LargeStringArray>,
-            IArrowArrayVisitor<BinaryArray>,
-            IArrowArrayVisitor<BinaryViewArray>,
-            IArrowArrayVisitor<LargeBinaryArray>,
-            IArrowArrayVisitor<FixedSizeBinaryArray>,
-            IArrowArrayVisitor<StructArray>,
-            IArrowArrayVisitor<UnionArray>,
-            IArrowArrayVisitor<Decimal32Array>,
-            IArrowArrayVisitor<Decimal64Array>,
-            IArrowArrayVisitor<Decimal128Array>,
-            IArrowArrayVisitor<Decimal256Array>,
-            IArrowArrayVisitor<DictionaryArray>,
-            IArrowArrayVisitor<NullArray>
-        {
-            public readonly struct FieldNode
-            {
-                public readonly int Length;
-                public readonly int NullCount;
-
-                public FieldNode(int length, int nullCount)
-                {
-                    Length = length;
-                    NullCount = nullCount;
-                }
-            }
-
-            public readonly struct Buffer : IDisposable
-            {
-                public readonly ReadOnlyMemory<byte> DataBuffer;
-                public readonly int Offset;
-                private readonly IDisposable _owner;
-
-                public Buffer(ReadOnlyMemory<byte> buffer, int offset, IDisposable owner)
-                {
-                    DataBuffer = buffer;
-                    Offset = offset;
-                    _owner = owner;
-                }
-                public void Dispose() => _owner?.Dispose();
-            }
-
-            private readonly List<FieldNode> _fieldNodes;
-            private readonly List<Buffer> _buffers;
-            private readonly ICompressionCodec _compressionCodec;
-            private readonly MemoryAllocator _allocator;
-            private readonly MemoryStream _fallbackCompressionStream;
-            public IReadOnlyList<FieldNode> FieldNodes => _fieldNodes;
-            public IReadOnlyList<Buffer> Buffers => _buffers;
-
-            public List<long> VariadicCounts { get; private set; }
-            public int TotalLength { get; private set; }
-
-            public ArrowRecordBatchFlatBufferBuilder(
-                ICompressionCodec compressionCodec, MemoryAllocator allocator, MemoryStream fallbackCompressionStream)
-            {
-                _compressionCodec = compressionCodec;
-                _allocator = allocator;
-                _fallbackCompressionStream = fallbackCompressionStream;
-                _fieldNodes = new List<FieldNode>();
-                _buffers = new List<Buffer>();
-                TotalLength = 0;
-            }
-
-            public void VisitArray(IArrowArray array)
-            {
-                _fieldNodes.Add(new FieldNode(array.Length, array.NullCount));
-
-                array.Accept(this);
-            }
-
-            public void Visit(Int8Array array) => VisitPrimitiveArray(array);
-            public void Visit(Int16Array array) => VisitPrimitiveArray(array);
-            public void Visit(Int32Array array) => VisitPrimitiveArray(array);
-            public void Visit(Int64Array array) => VisitPrimitiveArray(array);
-            public void Visit(UInt8Array array) => VisitPrimitiveArray(array);
-            public void Visit(UInt16Array array) => VisitPrimitiveArray(array);
-            public void Visit(UInt32Array array) => VisitPrimitiveArray(array);
-            public void Visit(UInt64Array array) => VisitPrimitiveArray(array);
-#if NET5_0_OR_GREATER
-            public void Visit(HalfFloatArray array) => VisitPrimitiveArray(array);
-#endif
-            public void Visit(FloatArray array) => VisitPrimitiveArray(array);
-            public void Visit(DoubleArray array) => VisitPrimitiveArray(array);
-            public void Visit(TimestampArray array) => VisitPrimitiveArray(array);
-            public void Visit(Date32Array array) => VisitPrimitiveArray(array);
-            public void Visit(Date64Array array) => VisitPrimitiveArray(array);
-            public void Visit(Time32Array array) => VisitPrimitiveArray(array);
-            public void Visit(Time64Array array) => VisitPrimitiveArray(array);
-            public void Visit(DurationArray array) => VisitPrimitiveArray(array);
-            public void Visit(YearMonthIntervalArray array) => VisitPrimitiveArray(array);
-            public void Visit(DayTimeIntervalArray array) => VisitPrimitiveArray(array);
-            public void Visit(MonthDayNanosecondIntervalArray array) => VisitPrimitiveArray(array);
-
-            private void VisitPrimitiveArray<T>(PrimitiveArray<T> array)
-                where T : struct, IEquatable<T>
-            {
-                _buffers.Add(CreateBitmapBuffer(array.NullBitmapBuffer, array.Offset, array.Length, false));
-                _buffers.Add(CreateSlicedBuffer<T>(array.ValueBuffer, array.Offset, array.Length, false));
-            }
-
-            public void Visit(BooleanArray array)
-            {
-                _buffers.Add(CreateBitmapBuffer(array.NullBitmapBuffer, array.Offset, array.Length, false));
-                _buffers.Add(CreateBitmapBuffer(array.ValueBuffer, array.Offset, array.Length, false));
-            }
-
-            public void Visit(ListArray array)
-            {
-                _buffers.Add(CreateBitmapBuffer(array.NullBitmapBuffer, array.Offset, array.Length, false));
-                _buffers.Add(CreateBuffer(GetZeroBasedValueOffsets(array.ValueOffsetsBuffer, array.Offset, array.Length), true));
-
-                int valuesOffset = 0;
-                int valuesLength = 0;
-                if (array.Length > 0)
-                {
-                    valuesOffset = array.ValueOffsets[0];
-                    valuesLength = array.ValueOffsets[array.Length] - valuesOffset;
-                }
-
-                var values = array.Values;
-                if (valuesOffset > 0 || valuesLength < values.Length)
-                {
-                    values = ArrowArrayFactory.Slice(values, valuesOffset, valuesLength);
-                }
-
-                VisitArray(values);
-            }
-
-            public void Visit(ListViewArray array)
-            {
-                var (valueOffsetsBuffer, minOffset, maxEnd) = GetZeroBasedListViewOffsets(array);
-
-                _buffers.Add(CreateBitmapBuffer(array.NullBitmapBuffer, array.Offset, array.Length, false));
-                _buffers.Add(CreateBuffer(valueOffsetsBuffer, true));
-                _buffers.Add(CreateSlicedBuffer<int>(array.SizesBuffer, array.Offset, array.Length, false));
-
-                IArrowArray values = array.Values;
-                if (minOffset != 0 || values.Length != maxEnd)
-                {
-                    values = ArrowArrayFactory.Slice(values, minOffset, maxEnd - minOffset);
-                }
-
-                VisitArray(values);
-            }
-
-            public void Visit(LargeListArray array)
-            {
-                _buffers.Add(CreateBitmapBuffer(array.NullBitmapBuffer, array.Offset, array.Length, false));
-                _buffers.Add(CreateBuffer(GetZeroBasedLongValueOffsets(array.ValueOffsetsBuffer, array.Offset, array.Length), true));
-
-                int valuesOffset = 0;
-                int valuesLength = 0;
-                if (array.Length > 0)
-                {
-                    valuesOffset = checked((int)array.ValueOffsets[0]);
-                    valuesLength = checked((int)array.ValueOffsets[array.Length] - valuesOffset);
-                }
-
-                var values = array.Values;
-                if (valuesOffset > 0 || valuesLength < values.Length)
-                {
-                    values = ArrowArrayFactory.Slice(values, valuesOffset, valuesLength);
-                }
-
-                VisitArray(values);
-            }
-
-            public void Visit(FixedSizeListArray array)
-            {
-                _buffers.Add(CreateBitmapBuffer(array.NullBitmapBuffer, array.Offset, array.Length, false));
-
-                var listSize = ((FixedSizeListType)array.Data.DataType).ListSize;
-                var valuesSlice =
-                    ArrowArrayFactory.Slice(array.Values, array.Offset * listSize, array.Length * listSize);
-
-                VisitArray(valuesSlice);
-            }
-
-            public void Visit(StringArray array) => Visit(array as BinaryArray);
-
-            public void Visit(StringViewArray array) => Visit(array as BinaryViewArray);
-
-            public void Visit(LargeStringArray array) => Visit(array as LargeBinaryArray);
-
-            public void Visit(BinaryArray array)
-            {
-                _buffers.Add(CreateBitmapBuffer(array.NullBitmapBuffer, array.Offset, array.Length, false));
-                _buffers.Add(CreateBuffer(GetZeroBasedValueOffsets(array.ValueOffsetsBuffer, array.Offset, array.Length), true));
-
-                int valuesOffset = 0;
-                int valuesLength = 0;
-                if (array.Length > 0)
-                {
-                    valuesOffset = array.ValueOffsets[0];
-                    valuesLength = array.ValueOffsets[array.Length] - valuesOffset;
-                }
-
-                _buffers.Add(CreateSlicedBuffer<byte>(array.ValueBuffer, valuesOffset, valuesLength, false));
-            }
-
-            public void Visit(BinaryViewArray array)
-            {
-                _buffers.Add(CreateBitmapBuffer(array.NullBitmapBuffer, array.Offset, array.Length, false));
-                _buffers.Add(CreateSlicedBuffer<Scalars.BinaryView>(array.ViewsBuffer, array.Offset, array.Length, false));
-                for (int i = 0; i < array.DataBufferCount; i++)
-                {
-                    _buffers.Add(CreateBuffer(array.DataBuffer(i), false));
-                }
-                VariadicCounts = VariadicCounts ?? new List<long>();
-                VariadicCounts.Add(array.DataBufferCount);
-            }
-
-            public void Visit(LargeBinaryArray array)
-            {
-                _buffers.Add(CreateBitmapBuffer(array.NullBitmapBuffer, array.Offset, array.Length, false));
-                _buffers.Add(CreateBuffer(GetZeroBasedLongValueOffsets(array.ValueOffsetsBuffer, array.Offset, array.Length), true));
-
-                int valuesOffset = 0;
-                int valuesLength = 0;
-                if (array.Length > 0)
-                {
-                    valuesOffset = checked((int)array.ValueOffsets[0]);
-                    valuesLength = checked((int)array.ValueOffsets[array.Length]) - valuesOffset;
-                }
-
-                _buffers.Add(CreateSlicedBuffer<byte>(array.ValueBuffer, valuesOffset, valuesLength, false));
-            }
-
-            public void Visit(FixedSizeBinaryArray array)
-            {
-                var itemSize = ((FixedSizeBinaryType)array.Data.DataType).ByteWidth;
-                _buffers.Add(CreateBitmapBuffer(array.NullBitmapBuffer, array.Offset, array.Length, false));
-                _buffers.Add(CreateSlicedBuffer(array.ValueBuffer, itemSize, array.Offset, array.Length, false));
-            }
-
-            public void Visit(Decimal32Array array) => Visit(array as FixedSizeBinaryArray);
-
-            public void Visit(Decimal64Array array) => Visit(array as FixedSizeBinaryArray);
-
-            public void Visit(Decimal128Array array) => Visit(array as FixedSizeBinaryArray);
-
-            public void Visit(Decimal256Array array) => Visit(array as FixedSizeBinaryArray);
-
-            public void Visit(StructArray array)
-            {
-                _buffers.Add(CreateBitmapBuffer(array.NullBitmapBuffer, array.Offset, array.Length, false));
-
-                for (int i = 0; i < array.Fields.Count; i++)
-                {
-                    // Fields property accessor handles slicing field arrays if required
-                    VisitArray(array.Fields[i]);
-                }
-            }
-
-            public void Visit(UnionArray array)
-            {
-                _buffers.Add(CreateSlicedBuffer<byte>(array.TypeBuffer, array.Offset, array.Length, false));
-
-                ArrowBuffer? offsets = (array as DenseUnionArray)?.ValueOffsetBuffer;
-                if (offsets != null)
-                {
-                    _buffers.Add(CreateSlicedBuffer<int>(offsets.Value, array.Offset, array.Length, false));
-                }
-
-                for (int i = 0; i < array.Fields.Count; i++)
-                {
-                    // Fields property accessor handles slicing field arrays for sparse union arrays if required
-                    VisitArray(array.Fields[i]);
-                }
-            }
-
-            public void Visit(DictionaryArray array)
-            {
-                // Dictionary is serialized separately in Dictionary serialization.
-                // We are only interested in indices at this context.
-
-                array.Indices.Accept(this);
-            }
-
-            public void Visit(NullArray array)
-            {
-                // There are no buffers for a NullArray
-            }
-
-            private ArrowBuffer GetZeroBasedValueOffsets(ArrowBuffer valueOffsetsBuffer, int arrayOffset, int arrayLength)
-            {
-                var requiredBytes = CalculatePaddedBufferLength(sizeof(int) * (arrayLength + 1));
-
-                if (arrayOffset != 0)
-                {
-                    // Array has been sliced, so we need to shift and adjust the offsets
-                    var originalOffsets = valueOffsetsBuffer.Span.CastTo<int>().Slice(arrayOffset, arrayLength + 1);
-                    int firstOffset = arrayLength > 0 ? originalOffsets[0] : 0;
-
-                    var newValueOffsetsBuffer = _allocator.Allocate(requiredBytes);
-                    var newValueOffsets = newValueOffsetsBuffer.Memory.Span.CastTo<int>();
-
-                    for (int i = 0; i < arrayLength + 1; ++i)
-                    {
-                        newValueOffsets[i] = originalOffsets[i] - firstOffset;
-                    }
-
-                    return new ArrowBuffer(newValueOffsetsBuffer);
-                }
-                else if (valueOffsetsBuffer.Length > requiredBytes)
-                {
-                    // Array may have been sliced but the offset is zero,
-                    // so we can truncate the existing offsets
-                    return new ArrowBuffer(valueOffsetsBuffer.Memory.Slice(0, requiredBytes));
-                }
-                else
-                {
-                    // Use the full buffer, but create a copy that is externally owned
-                    return new ArrowBuffer(valueOffsetsBuffer.Memory);
-                }
-            }
-
-            private ArrowBuffer GetZeroBasedLongValueOffsets(ArrowBuffer valueOffsetsBuffer, int arrayOffset, int arrayLength)
-            {
-                var requiredBytes = CalculatePaddedBufferLength(checked(sizeof(long) * (arrayLength + 1)));
-
-                if (arrayOffset != 0)
-                {
-                    // Array has been sliced, so we need to shift and adjust the offsets
-                    var originalOffsets = valueOffsetsBuffer.Span.CastTo<long>().Slice(arrayOffset, arrayLength + 1);
-                    var firstOffset = arrayLength > 0 ? originalOffsets[0] : 0L;
-
-                    var newValueOffsetsBuffer = _allocator.Allocate(requiredBytes);
-                    var newValueOffsets = newValueOffsetsBuffer.Memory.Span.CastTo<long>();
-
-                    for (int i = 0; i < arrayLength + 1; ++i)
-                    {
-                        newValueOffsets[i] = originalOffsets[i] - firstOffset;
-                    }
-                    return new ArrowBuffer(newValueOffsetsBuffer);
-                }
-                else if (valueOffsetsBuffer.Length > requiredBytes)
-                {
-                    // Array may have been sliced but the offset is zero,
-                    // so we can truncate the existing offsets
-                    return new ArrowBuffer(valueOffsetsBuffer.Memory.Slice(0, requiredBytes));
-                }
-                else
-                {
-                    // Use the full buffer, create new buffer that is externally owned
-                    return new ArrowBuffer(valueOffsetsBuffer.Memory);
-                }
-            }
-
-            private (ArrowBuffer Buffer, int minOffset, int maxEnd) GetZeroBasedListViewOffsets(ListViewArray array)
-            {
-                if (array.Length == 0)
-                {
-                    return (ArrowBuffer.Empty, 0, 0);
-                }
-
-                var offsets = array.ValueOffsets;
-                var sizes = array.Sizes;
-
-                int minOffset = offsets[0];
-                int maxEnd = offsets[array.Length - 1] + sizes[array.Length - 1];
-
-                // Min possible offset is zero, and max possible end is the values length.
-                // If these match the first offset and last end we don't need to do anything further,
-                // but otherwise we need to iterate over each index in case the offsets aren't ordered.
-                if (minOffset != 0 || maxEnd != array.Values.Length)
-                {
-                    for (int i = 0; i < array.Length; ++i)
-                    {
-                        minOffset = Math.Min(minOffset, offsets[i]);
-                        maxEnd = Math.Max(maxEnd, offsets[i] + sizes[i]);
-                    }
-                }
-
-                var requiredBytes = CalculatePaddedBufferLength(sizeof(int) * array.Length);
-
-                if (minOffset == 0)
-                {
-                    // No need to adjust the offsets, but we may need to slice the offsets buffer.
-                    ArrowBuffer buffer;
-                    if (array.Offset != 0 || array.ValueOffsetsBuffer.Length > requiredBytes)
-                    {
-                        var byteOffset = sizeof(int) * array.Offset;
-                        var sliceLength = Math.Min(requiredBytes, array.ValueOffsetsBuffer.Length - byteOffset);
-                        buffer = new ArrowBuffer(array.ValueOffsetsBuffer.Memory.Slice(byteOffset, sliceLength));
-                    }
-                    else
-                    {
-                        // create a copy that's externally owned
-                        buffer = new ArrowBuffer(array.ValueOffsetsBuffer.Memory);
-                    }
-
-                    return (buffer, minOffset, maxEnd);
-                }
-
-                // Compute shifted offsets
-                var newOffsetsBuffer = _allocator.Allocate(requiredBytes);
-                var newOffsets = newOffsetsBuffer.Memory.Span.CastTo<int>();
-                for (int i = 0; i < array.Length; ++i)
-                {
-                    newOffsets[i] = offsets[i] - minOffset;
-                }
-
-                return (new ArrowBuffer(newOffsetsBuffer), minOffset, maxEnd);
-            }
-
-            private Buffer CreateBitmapBuffer(ArrowBuffer buffer, int offset, int length, bool locallyOwned)
-            {
-                if (buffer.IsEmpty)
-                {
-                    return CreateBuffer(buffer, locallyOwned);
-                }
-
-                var paddedLength = CalculatePaddedBufferLength(BitUtility.ByteCount(length));
-                if (offset % 8 == 0)
-                {
-                    var byteOffset = offset / 8;
-                    var sliceLength = Math.Min(paddedLength, buffer.Length - byteOffset);
-
-                    return CreateBuffer(buffer.Memory.Slice(byteOffset, sliceLength), locallyOwned ? buffer : null);
-                }
-                else
-                {
-                    // Need to copy bitmap so the first bit is aligned with the first byte
-                    var memoryOwner = _allocator.Allocate(paddedLength);
-                    var outputSpan = memoryOwner.Memory.Span;
-                    var inputSpan = buffer.Span;
-                    for (var i = 0; i < length; ++i)
-                    {
-                        BitUtility.SetBit(outputSpan, i, BitUtility.GetBit(inputSpan, offset + i));
-                    }
-
-                    return CreateBuffer(memoryOwner);
-                }
-            }
-
-            private Buffer CreateSlicedBuffer<T>(ArrowBuffer buffer, int offset, int length, bool owned)
-                where T : struct
-            {
-                return CreateSlicedBuffer(buffer, Unsafe.SizeOf<T>(), offset, length, owned);
-            }
-
-            private Buffer CreateSlicedBuffer(ArrowBuffer buffer, int itemSize, int offset, int length, bool owned)
-            {
-                var byteLength = length * itemSize;
-                var paddedLength = CalculatePaddedBufferLength(byteLength);
-                if (offset != 0 || paddedLength < buffer.Length)
-                {
-                    var byteOffset = offset * itemSize;
-                    var sliceLength = Math.Min(paddedLength, buffer.Length - byteOffset);
-                    return CreateBuffer(buffer.Memory.Slice(byteOffset, sliceLength),
-                        owned ? buffer : null);
-                }
-
-                return CreateBuffer(buffer, owned);
-            }
-
-            private Buffer CreateBuffer(ArrowBuffer buffer, bool locallyOwned)
-            {
-                if (locallyOwned)
-                {
-                    // this buffer is locally owned, we can dispose it
-                    return CreateBuffer(buffer.Memory, buffer);
-                }
-                return CreateBuffer(buffer.Memory, null);
-            }
-
-            private Buffer CreateBuffer(IMemoryOwner<byte>  bufferOwner)
-            {
-                return CreateBuffer(bufferOwner.Memory, bufferOwner);
-            }
-
-            private Buffer CreateBuffer(ReadOnlyMemory<byte> buffer, IDisposable localBufferOwner)
-            {
-                int offset = TotalLength;
-                const int UncompressedLengthSize = 8;
-
-                ReadOnlyMemory<byte> bufferToWrite;
-                IMemoryOwner<byte> bufferOwner=null;
-                if (_compressionCodec == null)
-                {
-                    bufferToWrite = buffer;
-                }
-                else if (buffer.Length == 0)
-                {
-                    // Write zero length and skip compression
-                    bufferOwner = _allocator.Allocate(UncompressedLengthSize);
-                    BinaryPrimitives.WriteInt64LittleEndian(bufferOwner.Memory.Span, 0);
-                    bufferToWrite = bufferOwner.Memory.Slice(0, UncompressedLengthSize);
-                    // the local source buffer owner can be disposed, its memory is no longer needed
-                    localBufferOwner?.Dispose();
-                }
-                else
-                {
-                    // See format/Message.fbs, and the BUFFER BodyCompressionMethod for documentation on how
-                    // compressed buffers are stored.
-                    int newBufferLength = UncompressedLengthSize + buffer.Length;
-                    bufferOwner = _allocator.Allocate(newBufferLength);
-
-                    if(TryCompress(buffer, bufferOwner.Memory.Slice(UncompressedLengthSize, buffer.Length), out int bytesWritten))
-                    {
-                        // Write the uncompressed length to the start of the buffer
-                        BinaryPrimitives.WriteInt64LittleEndian(bufferOwner.Memory.Span, buffer.Length);
-                        bufferToWrite = bufferOwner.Memory.Slice(0, bytesWritten+UncompressedLengthSize);
-                    }
-                    else
-                    {
-                        // TryCompress failed, because the buffer is too small.
-                        // If the compressed buffer is larger than the uncompressed buffer, use the uncompressed
-                        // buffer instead, and indicate this by setting the uncompressed length to -1
-                        BinaryPrimitives.WriteInt64LittleEndian(bufferOwner.Memory.Span, -1);
-                        buffer.CopyTo(bufferOwner.Memory.Slice(UncompressedLengthSize));
-                        bufferToWrite = bufferOwner.Memory.Slice(0, newBufferLength);
-                    }
-                    // the local source buffer owner can be disposed, its memory was copied
-                    localBufferOwner?.Dispose();
-                }
-
-                int paddedLength = checked((int)BitUtility.RoundUpToMultipleOf8(bufferToWrite.Length));
-                TotalLength += paddedLength;
-                // if the buffer is owned locally or allocated in the method, we can dispose it after writing the buffer to the stream
-                return new Buffer(bufferToWrite, offset, (IDisposable)bufferOwner ?? localBufferOwner);
-            }
-
-            private bool TryCompress(ReadOnlyMemory<byte> source, Memory<byte> destination, out int bytesWritten)
-            {
-                if(_compressionCodec is ITryCompressionCodec tryCompressionCodec)
-                    return tryCompressionCodec.TryCompress(source, destination, out bytesWritten);
-                // Fallback to using a memory stream for compression
-                _fallbackCompressionStream.Seek(0, SeekOrigin.Begin);
-                _fallbackCompressionStream.SetLength(0);
-                _compressionCodec.Compress(source, _fallbackCompressionStream);
-                if (_fallbackCompressionStream.Length >= destination.Length)
-                {
-                    bytesWritten = 0;
-                    return false;
-                }
-                _fallbackCompressionStream.Seek(0, SeekOrigin.Begin);
-                bytesWritten = _fallbackCompressionStream.ReadFullBuffer(destination);
-                return true;
-            }
-
-            public void Visit(IArrowArray array)
-            {
-                throw new NotImplementedException();
-            }
-        }
-
-        protected Stream BaseStream { get; }
-
-        protected ArrayPool<byte> Buffers { get; }
-
-        private protected FlatBufferBuilder Builder { get; }
-
-        protected bool HasWrittenSchema { get; set; }
-
-        private bool HasWrittenDictionaryBatch { get; set; }
-
-        private bool HasWrittenStart { get; set; }
-
-        private bool HasWrittenEnd { get; set; }
-
-        protected Schema Schema { get; }
-
-        private readonly bool _leaveOpen;
-        private readonly IpcOptions _options;
-        private readonly MemoryAllocator _allocator;
-        // Fallback for compression codec, not implementing TryCompress.
-        // Reuse a single memory stream for writing compressed
-        private readonly MemoryStream _fallbackCompressionStream = new MemoryStream();
-
-        private protected const Flatbuf.MetadataVersion CurrentMetadataVersion = Flatbuf.MetadataVersion.V5;
-
-        private static readonly byte[] s_padding = new byte[64];
-
-        private readonly ArrowTypeFlatbufferBuilder _fieldTypeBuilder;
-
-        private DictionaryMemo _dictionaryMemo;
-        private DictionaryMemo DictionaryMemo => _dictionaryMemo ??= new DictionaryMemo();
-
-        public ArrowStreamWriter(Stream baseStream, Schema schema)
-            : this(baseStream, schema, leaveOpen: false)
-        {
-        }
-
-        public ArrowStreamWriter(Stream baseStream, Schema schema, bool leaveOpen)
-            : this(baseStream, schema, leaveOpen, options: null, allocator: null)
-        {
-        }
-
-        public ArrowStreamWriter(Stream baseStream, Schema schema, bool leaveOpen, IpcOptions options)
-            : this(baseStream, schema, leaveOpen, options, allocator: null)
-        {
-        }
-
-        public ArrowStreamWriter(Stream baseStream, Schema schema, bool leaveOpen, IpcOptions options, MemoryAllocator allocator)
-        {
-            BaseStream = baseStream ?? throw new ArgumentNullException(nameof(baseStream));
-            Schema = schema ?? throw new ArgumentNullException(nameof(schema));
-            _leaveOpen = leaveOpen;
-            _allocator = allocator ?? MemoryAllocator.Default.Value;
-
-            Buffers = ArrayPool<byte>.Create();
-            Builder = new FlatBufferBuilder(1024);
-            HasWrittenSchema = false;
-
-            _fieldTypeBuilder = new ArrowTypeFlatbufferBuilder(Builder);
-            _options = options ?? IpcOptions.Default;
-
-            if (_options.CompressionCodec.HasValue && _options.CompressionCodecFactory == null)
-            {
-                throw new ArgumentException(
-                    $"A {nameof(_options.CompressionCodecFactory)} must be provided when a {nameof(_options.CompressionCodec)} is specified",
-                    nameof(options));
-            }
-        }
-
-        private Offset<Flatbuf.BodyCompression> GetBodyCompression()
-        {
-            if (_options.CompressionCodec == null)
-            {
-                return default;
-            }
-
-            var compressionType = _options.CompressionCodec.Value switch
-            {
-                CompressionCodecType.Lz4Frame => Flatbuf.CompressionType.LZ4_FRAME,
-                CompressionCodecType.Zstd => Flatbuf.CompressionType.ZSTD,
-                _ => throw new ArgumentOutOfRangeException()
-            };
-            return Flatbuf.BodyCompression.CreateBodyCompression(
-                Builder, compressionType, Flatbuf.BodyCompressionMethod.BUFFER);
-        }
-
-        private protected void WriteRecordBatchInternal(RecordBatch recordBatch)
-        {
-            // TODO: Truncate buffers with extraneous padding / unused capacity
-
-            if (!HasWrittenSchema)
-            {
-                WriteSchema(Schema);
-                HasWrittenSchema = true;
-            }
-
-            if (!HasWrittenDictionaryBatch)
-            {
-                DictionaryCollector.Collect(recordBatch, ref _dictionaryMemo);
-                WriteDictionaries(_dictionaryMemo);
-                HasWrittenDictionaryBatch = true;
-            }
-
-            (ArrowRecordBatchFlatBufferBuilder recordBatchBuilder, VectorOffset fieldNodesVectorOffset, VectorOffset variadicCountsOffset) =
-                PrepareWritingRecordBatch(recordBatch);
-
-            VectorOffset buffersVectorOffset = Builder.EndVector();
-
-            // Serialize record batch
-
-            StartingWritingRecordBatch();
-
-            Offset<Flatbuf.RecordBatch> recordBatchOffset = Flatbuf.RecordBatch.CreateRecordBatch(Builder, recordBatch.Length,
-                fieldNodesVectorOffset,
-                buffersVectorOffset,
-                GetBodyCompression(),
-                variadicCountsOffset);
-
-            long metadataLength = WriteMessage(Flatbuf.MessageHeader.RecordBatch,
-                recordBatchOffset, recordBatchBuilder.TotalLength);
-
-            long bufferLength = WriteBufferData(recordBatchBuilder.Buffers);
-
-            FinishedWritingRecordBatch(bufferLength, metadataLength);
-        }
-
-        private protected async Task WriteRecordBatchInternalAsync(RecordBatch recordBatch,
-            CancellationToken cancellationToken = default)
-        {
-            if (!HasWrittenSchema)
-            {
-                await WriteSchemaAsync(Schema, cancellationToken).ConfigureAwait(false);
-                HasWrittenSchema = true;
-            }
-
-            if (!HasWrittenDictionaryBatch)
-            {
-                DictionaryCollector.Collect(recordBatch, ref _dictionaryMemo);
-                await WriteDictionariesAsync(_dictionaryMemo, cancellationToken).ConfigureAwait(false);
-                HasWrittenDictionaryBatch = true;
-            }
-
-            (ArrowRecordBatchFlatBufferBuilder recordBatchBuilder, VectorOffset fieldNodesVectorOffset, VectorOffset variadicCountsOffset) =
-                PrepareWritingRecordBatch(recordBatch);
-
-            VectorOffset buffersVectorOffset = Builder.EndVector();
-
-            // Serialize record batch
-
-            StartingWritingRecordBatch();
-
-            Offset<Flatbuf.RecordBatch> recordBatchOffset = Flatbuf.RecordBatch.CreateRecordBatch(Builder, recordBatch.Length,
-                fieldNodesVectorOffset,
-                buffersVectorOffset,
-                GetBodyCompression(),
-                variadicCountsOffset);
-
-            long metadataLength = await WriteMessageAsync(Flatbuf.MessageHeader.RecordBatch,
-                recordBatchOffset, recordBatchBuilder.TotalLength,
-                cancellationToken).ConfigureAwait(false);
-
-            long bufferLength = await WriteBufferDataAsync(recordBatchBuilder.Buffers, cancellationToken).ConfigureAwait(false);
-
-            FinishedWritingRecordBatch(bufferLength, metadataLength);
-        }
-
-        private long WriteBufferData(IReadOnlyList<ArrowRecordBatchFlatBufferBuilder.Buffer> buffers)
-        {
-            long bodyLength = 0;
-
-            for (int i = 0; i < buffers.Count; i++)
-            {
-                using var buffer = buffers[i]; // Dispose the buffer after writing
-                ReadOnlyMemory<byte> dataBuffer = buffer.DataBuffer;
-                if (dataBuffer.IsEmpty)
-                    continue;
-                BaseStream.Write(dataBuffer);
-                int paddedLength = checked((int)BitUtility.RoundUpToMultipleOf8(dataBuffer.Length));
-                int padding = paddedLength - dataBuffer.Length;
-                if (padding > 0)
-                {
-                    WritePadding(padding);
-                }
-                bodyLength += paddedLength;
-            }
-
-            // Write padding so the record batch message body length is a multiple of 8 bytes
-
-            int bodyPaddingLength = CalculatePadding(bodyLength);
-
-            WritePadding(bodyPaddingLength);
-
-            return bodyLength + bodyPaddingLength;
-        }
-
-        private async ValueTask<long> WriteBufferDataAsync(IReadOnlyList<ArrowRecordBatchFlatBufferBuilder.Buffer> buffers, CancellationToken cancellationToken = default)
-        {
-            long bodyLength = 0;
-
-            for (int i = 0; i < buffers.Count; i++)
-            {
-                using var buffer = buffers[i]; // Dispose the buffer after writing
-                ReadOnlyMemory<byte> dataBuffer = buffer.DataBuffer;
-                if (dataBuffer.IsEmpty)
-                    continue;
-
-                await BaseStream.WriteAsync(dataBuffer, cancellationToken).ConfigureAwait(false);
-
-                int paddedLength = checked((int)BitUtility.RoundUpToMultipleOf8(dataBuffer.Length));
-                int padding = paddedLength - dataBuffer.Length;
-                if (padding > 0)
-                {
-                    await WritePaddingAsync(padding).ConfigureAwait(false);
-                }
-
-                bodyLength += paddedLength;
-            }
-
-            // Write padding so the record batch message body length is a multiple of 8 bytes
-
-            int bodyPaddingLength = CalculatePadding(bodyLength);
-
-            await WritePaddingAsync(bodyPaddingLength).ConfigureAwait(false);
-
-            return bodyLength + bodyPaddingLength;
-        }
-
-        private Tuple<ArrowRecordBatchFlatBufferBuilder, VectorOffset, VectorOffset> PrepareWritingRecordBatch(RecordBatch recordBatch)
-        {
-            return PrepareWritingRecordBatch(recordBatch.Schema.FieldsList, recordBatch.ArrayList);
-        }
-
-        private Tuple<ArrowRecordBatchFlatBufferBuilder, VectorOffset, VectorOffset> PrepareWritingRecordBatch(IReadOnlyList<Field> fields, IReadOnlyList<IArrowArray> arrays)
-        {
-            Builder.Clear();
-
-            // CompressionCodec can be disposed after all data is visited by the builder,
-            // and doesn't need to be alive for the full lifetime of the ArrowRecordBatchFlatBufferBuilder
-            using var compressionCodec = _options.CompressionCodec.HasValue
-                ? _options.CompressionCodecFactory.CreateCodec(_options.CompressionCodec.Value, _options.CompressionLevel)
-                : null;
-
-            var recordBatchBuilder = new ArrowRecordBatchFlatBufferBuilder(compressionCodec, _allocator, _fallbackCompressionStream);
-
-            // Visit all arrays recursively
-            for (int i = 0; i < fields.Count; i++)
-            {
-                IArrowArray fieldArray = arrays[i];
-                recordBatchBuilder.VisitArray(fieldArray);
-            }
-
-            // Serialize field nodes
-            IReadOnlyList<ArrowRecordBatchFlatBufferBuilder.FieldNode> fieldNodes = recordBatchBuilder.FieldNodes;
-            Flatbuf.RecordBatch.StartNodesVector(Builder, fieldNodes.Count);
-
-            // flatbuffer struct vectors have to be created in reverse order
-            for (int i = fieldNodes.Count - 1; i >= 0; i--)
-            {
-                Flatbuf.FieldNode.CreateFieldNode(Builder, fieldNodes[i].Length, fieldNodes[i].NullCount);
-            }
-
-            VectorOffset fieldNodesVectorOffset = Builder.EndVector();
-
-            VectorOffset variadicCountOffset = default;
-            if (recordBatchBuilder.VariadicCounts != null)
-            {
-                variadicCountOffset = Flatbuf.RecordBatch.CreateVariadicCountsVectorBlock(Builder, recordBatchBuilder.VariadicCounts.ToArray());
-            }
-
-            // Serialize buffers
-            IReadOnlyList<ArrowRecordBatchFlatBufferBuilder.Buffer> buffers = recordBatchBuilder.Buffers;
-            Flatbuf.RecordBatch.StartBuffersVector(Builder, buffers.Count);
-
-            // flatbuffer struct vectors have to be created in reverse order
-            for (int i = buffers.Count - 1; i >= 0; i--)
-            {
-                Flatbuf.Buffer.CreateBuffer(Builder,
-                    buffers[i].Offset, buffers[i].DataBuffer.Length);
-            }
-
-            return Tuple.Create(recordBatchBuilder, fieldNodesVectorOffset, variadicCountOffset);
-        }
-
-        private protected virtual void StartingWritingDictionary()
-        {
-        }
-
-        private protected virtual void FinishedWritingDictionary(long bodyLength, long metadataLength)
-        {
-        }
-
-        private protected void WriteDictionaries(DictionaryMemo dictionaryMemo)
-        {
-            int fieldCount = dictionaryMemo?.DictionaryCount ?? 0;
-            for (int i = 0; i < fieldCount; i++)
-            {
-                WriteDictionary(i, dictionaryMemo.GetDictionaryType(i), dictionaryMemo.GetDictionary(i));
-            }
-        }
-
-        private protected void WriteDictionary(long id, IArrowType valueType, IArrowArray dictionary)
-        {
-            StartingWritingDictionary();
-
-            (ArrowRecordBatchFlatBufferBuilder recordBatchBuilder, Offset<Flatbuf.DictionaryBatch> dictionaryBatchOffset) =
-                CreateDictionaryBatchOffset(id, valueType, dictionary);
-
-            long metadataLength = WriteMessage(Flatbuf.MessageHeader.DictionaryBatch,
-                dictionaryBatchOffset, recordBatchBuilder.TotalLength);
-
-            long bufferLength = WriteBufferData(recordBatchBuilder.Buffers);
-
-            FinishedWritingDictionary(bufferLength, metadataLength);
-        }
-
-        private protected async Task WriteDictionariesAsync(DictionaryMemo dictionaryMemo, CancellationToken cancellationToken)
-        {
-            int fieldCount = dictionaryMemo?.DictionaryCount ?? 0;
-            for (int i = 0; i < fieldCount; i++)
-            {
-                await WriteDictionaryAsync(i, dictionaryMemo.GetDictionaryType(i), dictionaryMemo.GetDictionary(i), cancellationToken).ConfigureAwait(false);
-            }
-        }
-
-        private protected async Task WriteDictionaryAsync(long id, IArrowType valueType, IArrowArray dictionary, CancellationToken cancellationToken)
-        {
-            StartingWritingDictionary();
-
-            (ArrowRecordBatchFlatBufferBuilder recordBatchBuilder, Offset<Flatbuf.DictionaryBatch> dictionaryBatchOffset) =
-                CreateDictionaryBatchOffset(id, valueType, dictionary);
-
-            long metadataLength = await WriteMessageAsync(Flatbuf.MessageHeader.DictionaryBatch,
-                dictionaryBatchOffset, recordBatchBuilder.TotalLength, cancellationToken).ConfigureAwait(false);
-
-            long bufferLength = await WriteBufferDataAsync(recordBatchBuilder.Buffers, cancellationToken).ConfigureAwait(false);
-
-            FinishedWritingDictionary(bufferLength, metadataLength);
-        }
-
-        private Tuple<ArrowRecordBatchFlatBufferBuilder, Offset<Flatbuf.DictionaryBatch>> CreateDictionaryBatchOffset(long id, IArrowType valueType, IArrowArray dictionary)
-        {
-            Field dictionaryField = new Field("dummy", valueType, false);
-
-            var fields = new Field[] { dictionaryField };
-
-            var arrays = new List<IArrowArray> { dictionary };
-
-            (ArrowRecordBatchFlatBufferBuilder recordBatchBuilder, VectorOffset fieldNodesVectorOffset, VectorOffset variadicCountsOffset) =
-                PrepareWritingRecordBatch(fields, arrays);
-
-            VectorOffset buffersVectorOffset = Builder.EndVector();
-
-            // Serialize record batch
-            Offset<Flatbuf.RecordBatch> recordBatchOffset = Flatbuf.RecordBatch.CreateRecordBatch(Builder, dictionary.Length,
-                fieldNodesVectorOffset,
-                buffersVectorOffset,
-                GetBodyCompression(),
-                variadicCountsOffset);
-
-            // TODO: Support delta.
-            Offset<Flatbuf.DictionaryBatch> dictionaryBatchOffset = Flatbuf.DictionaryBatch.CreateDictionaryBatch(Builder, id, recordBatchOffset, false);
-            return Tuple.Create(recordBatchBuilder, dictionaryBatchOffset);
-        }
-
-        private protected virtual void WriteStartInternal()
-        {
-            if (!HasWrittenSchema)
-            {
-                WriteSchema(Schema);
-                HasWrittenSchema = true;
-            }
-        }
-
-        private protected async virtual ValueTask WriteStartInternalAsync(CancellationToken cancellationToken)
-        {
-            if (!HasWrittenSchema)
-            {
-                await WriteSchemaAsync(Schema, cancellationToken).ConfigureAwait(false);
-                HasWrittenSchema = true;
-            }
-        }
-
-        private protected virtual void WriteEndInternal()
-        {
-            WriteIpcMessageLength(length: 0);
-        }
-
-        private protected virtual ValueTask WriteEndInternalAsync(CancellationToken cancellationToken)
-        {
-            return WriteIpcMessageLengthAsync(length: 0, cancellationToken);
-        }
-
-        private protected virtual void StartingWritingRecordBatch()
-        {
-        }
-
-        private protected virtual void FinishedWritingRecordBatch(long bodyLength, long metadataLength)
-        {
-        }
-
-        public virtual void WriteRecordBatch(RecordBatch recordBatch)
-        {
-            WriteRecordBatchInternal(recordBatch);
-        }
-
-        public virtual Task WriteRecordBatchAsync(RecordBatch recordBatch, CancellationToken cancellationToken = default)
-        {
-            return WriteRecordBatchInternalAsync(recordBatch, cancellationToken);
-        }
-
-        public void WriteStart()
-        {
-            if (!HasWrittenStart)
-            {
-                WriteStartInternal();
-                HasWrittenStart = true;
-            }
-        }
-
-        public async Task WriteStartAsync(CancellationToken cancellationToken = default)
-        {
-            if (!HasWrittenStart)
-            {
-                await WriteStartInternalAsync(cancellationToken);
-                HasWrittenStart = true;
-            }
-        }
-
-        public void WriteEnd()
-        {
-            if (!HasWrittenEnd)
-            {
-                WriteEndInternal();
-                HasWrittenEnd = true;
-            }
-        }
-
-        public async Task WriteEndAsync(CancellationToken cancellationToken = default)
-        {
-            if (!HasWrittenEnd)
-            {
-                await WriteEndInternalAsync(cancellationToken);
-                HasWrittenEnd = true;
-            }
-        }
-
-        private protected Offset<Flatbuf.Schema> SerializeSchema(Schema schema)
-        {
-            // Build metadata
-            VectorOffset metadataVectorOffset = default;
-            if (schema.HasMetadata)
-            {
-                Offset<Flatbuf.KeyValue>[] metadataOffsets = GetMetadataOffsets(schema.Metadata);
-                metadataVectorOffset = Flatbuf.Schema.CreateCustomMetadataVector(Builder, metadataOffsets);
-            }
-
-            // Build fields
-            var fieldOffsets = new Offset<Flatbuf.Field>[schema.FieldsList.Count];
-            for (int i = 0; i < fieldOffsets.Length; i++)
-            {
-                Field field = schema.GetFieldByIndex(i);
-                StringOffset fieldNameOffset = Builder.CreateString(field.Name);
-                ArrowTypeFlatbufferBuilder.FieldType fieldType = _fieldTypeBuilder.BuildFieldType(field);
-
-                VectorOffset fieldChildrenVectorOffset = GetChildrenFieldOffset(field);
-                VectorOffset fieldMetadataVectorOffset = GetFieldMetadataOffset(field);
-                Offset<Flatbuf.DictionaryEncoding> dictionaryOffset = GetDictionaryOffset(field);
-
-                fieldOffsets[i] = Flatbuf.Field.CreateField(Builder,
-                    fieldNameOffset, field.IsNullable, fieldType.Type, fieldType.Offset,
-                    dictionaryOffset, fieldChildrenVectorOffset, fieldMetadataVectorOffset);
-            }
-
-            VectorOffset fieldsVectorOffset = Flatbuf.Schema.CreateFieldsVector(Builder, fieldOffsets);
-
-            // Build schema
-
-            Flatbuf.Endianness endianness = BitConverter.IsLittleEndian ? Flatbuf.Endianness.Little : Flatbuf.Endianness.Big;
-
-            return Flatbuf.Schema.CreateSchema(
-                Builder, endianness, fieldsVectorOffset, metadataVectorOffset);
-        }
-
-        private VectorOffset GetChildrenFieldOffset(Field field)
-        {
-            IArrowType targetDataType = field.DataType is DictionaryType dictionaryType ?
-                dictionaryType.ValueType :
-                field.DataType;
-
-            if (!(targetDataType is NestedType type))
-            {
-                return default;
-            }
-
-            int childrenCount = type.Fields.Count;
-            var children = new Offset<Flatbuf.Field>[childrenCount];
-
-            for (int i = 0; i < childrenCount; i++)
-            {
-                Field childField = type.Fields[i];
-                StringOffset childFieldNameOffset = Builder.CreateString(childField.Name);
-                ArrowTypeFlatbufferBuilder.FieldType childFieldType = _fieldTypeBuilder.BuildFieldType(childField);
-
-                VectorOffset childFieldChildrenVectorOffset = GetChildrenFieldOffset(childField);
-                VectorOffset childFieldMetadataVectorOffset = GetFieldMetadataOffset(childField);
-                Offset<Flatbuf.DictionaryEncoding> dictionaryOffset = GetDictionaryOffset(childField);
-
-                children[i] = Flatbuf.Field.CreateField(Builder,
-                    childFieldNameOffset, childField.IsNullable, childFieldType.Type, childFieldType.Offset,
-                    dictionaryOffset, childFieldChildrenVectorOffset, childFieldMetadataVectorOffset);
-            }
-
-            return Builder.CreateVectorOfTables(children);
-        }
-
-        private VectorOffset GetFieldMetadataOffset(Field field)
-        {
-            if (!field.HasMetadata)
-            {
-                return default;
-            }
-
-            Offset<Flatbuf.KeyValue>[] metadataOffsets = GetMetadataOffsets(field.Metadata);
-            return Flatbuf.Field.CreateCustomMetadataVector(Builder, metadataOffsets);
-        }
-
-        private Offset<Flatbuf.DictionaryEncoding> GetDictionaryOffset(Field field)
-        {
-            if (field.DataType.TypeId != ArrowTypeId.Dictionary)
-            {
-                return default;
-            }
-
-            long id = DictionaryMemo.GetOrAssignId(field);
-            var dicType = field.DataType as DictionaryType;
-            var indexType = dicType.IndexType as NumberType;
-
-            Offset<Flatbuf.Int> indexOffset = Flatbuf.Int.CreateInt(Builder, indexType.BitWidth, indexType.IsSigned);
-            return Flatbuf.DictionaryEncoding.CreateDictionaryEncoding(Builder, id, indexOffset, dicType.Ordered);
-        }
-
-        private Offset<Flatbuf.KeyValue>[] GetMetadataOffsets(IReadOnlyDictionary<string, string> metadata)
-        {
-            Debug.Assert(metadata != null);
-            Debug.Assert(metadata.Count > 0);
-
-            Offset<Flatbuf.KeyValue>[] metadataOffsets = new Offset<Flatbuf.KeyValue>[metadata.Count];
-            int index = 0;
-            foreach (KeyValuePair<string, string> metadatum in metadata)
-            {
-                StringOffset keyOffset = Builder.CreateString(metadatum.Key);
-                StringOffset valueOffset = Builder.CreateString(metadatum.Value);
-
-                metadataOffsets[index++] = Flatbuf.KeyValue.CreateKeyValue(Builder, keyOffset, valueOffset);
-            }
-
-            return metadataOffsets;
-        }
-
-        private Offset<Flatbuf.Schema> WriteSchema(Schema schema)
-        {
-            Builder.Clear();
-
-            // Build schema
-
-            Offset<Flatbuf.Schema> schemaOffset = SerializeSchema(schema);
-
-            // Build message
-
-            WriteMessage(Flatbuf.MessageHeader.Schema, schemaOffset, 0);
-
-            return schemaOffset;
-        }
-
-        private async ValueTask<Offset<Flatbuf.Schema>> WriteSchemaAsync(Schema schema, CancellationToken cancellationToken)
-        {
-            Builder.Clear();
-
-            // Build schema
-
-            Offset<Flatbuf.Schema> schemaOffset = SerializeSchema(schema);
-
-            // Build message
-
-            await WriteMessageAsync(Flatbuf.MessageHeader.Schema, schemaOffset, 0, cancellationToken)
-                .ConfigureAwait(false);
-
-            return schemaOffset;
-        }
-
-        /// <summary>
-        /// Writes the message to the <see cref="BaseStream"/>.
-        /// </summary>
-        /// <returns>
-        /// The number of bytes written to the stream.
-        /// </returns>
-        private protected long WriteMessage<T>(
-            Flatbuf.MessageHeader headerType, Offset<T> headerOffset, int bodyLength)
-            where T : struct
-        {
-            Offset<Flatbuf.Message> messageOffset = Flatbuf.Message.CreateMessage(
-                Builder, CurrentMetadataVersion, headerType, headerOffset.Value,
-                bodyLength);
-
-            Builder.Finish(messageOffset.Value);
-
-            ReadOnlyMemory<byte> messageData = Builder.DataBuffer.ToReadOnlyMemory(Builder.DataBuffer.Position, Builder.Offset);
-            int messagePaddingLength = CalculatePadding(_options.SizeOfIpcLength + messageData.Length);
-
-            WriteIpcMessageLength(messageData.Length + messagePaddingLength);
-
-            BaseStream.Write(messageData);
-            WritePadding(messagePaddingLength);
-
-            checked
-            {
-                return _options.SizeOfIpcLength + messageData.Length + messagePaddingLength;
-            }
-        }
-
-        /// <summary>
-        /// Writes the message to the <see cref="BaseStream"/>.
-        /// </summary>
-        /// <returns>
-        /// The number of bytes written to the stream.
-        /// </returns>
-        private protected virtual async ValueTask<long> WriteMessageAsync<T>(
-            Flatbuf.MessageHeader headerType, Offset<T> headerOffset, int bodyLength,
-            CancellationToken cancellationToken)
-            where T : struct
-        {
-            Offset<Flatbuf.Message> messageOffset = Flatbuf.Message.CreateMessage(
-                Builder, CurrentMetadataVersion, headerType, headerOffset.Value,
-                bodyLength);
-
-            Builder.Finish(messageOffset.Value);
-
-            ReadOnlyMemory<byte> messageData = Builder.DataBuffer.ToReadOnlyMemory(Builder.DataBuffer.Position, Builder.Offset);
-            int messagePaddingLength = CalculatePadding(_options.SizeOfIpcLength + messageData.Length);
-
-            await WriteIpcMessageLengthAsync(messageData.Length + messagePaddingLength, cancellationToken)
-                .ConfigureAwait(false);
-
-            await BaseStream.WriteAsync(messageData, cancellationToken).ConfigureAwait(false);
-            await WritePaddingAsync(messagePaddingLength).ConfigureAwait(false);
-
-            checked
-            {
-                return _options.SizeOfIpcLength + messageData.Length + messagePaddingLength;
-            }
-        }
-
-        private protected void WriteFlatBuffer()
-        {
-            ReadOnlyMemory<byte> segment = Builder.DataBuffer.ToReadOnlyMemory(Builder.DataBuffer.Position, Builder.Offset);
-
-            BaseStream.Write(segment);
-        }
-
-        private protected async ValueTask WriteFlatBufferAsync(CancellationToken cancellationToken = default)
-        {
-            ReadOnlyMemory<byte> segment = Builder.DataBuffer.ToReadOnlyMemory(Builder.DataBuffer.Position, Builder.Offset);
-
-            await BaseStream.WriteAsync(segment, cancellationToken).ConfigureAwait(false);
-        }
-
-        private void WriteIpcMessageLength(int length)
-        {
-            using (Buffers.RentReturn(_options.SizeOfIpcLength, out Memory<byte> buffer))
-            {
-                Memory<byte> currentBufferPosition = buffer;
-                if (!_options.WriteLegacyIpcFormat)
-                {
-                    BinaryPrimitives.WriteInt32LittleEndian(
-                        currentBufferPosition.Span, MessageSerializer.IpcContinuationToken);
-                    currentBufferPosition = currentBufferPosition.Slice(sizeof(int));
-                }
-
-                BinaryPrimitives.WriteInt32LittleEndian(currentBufferPosition.Span, length);
-                BaseStream.Write(buffer);
-            }
-        }
-
-        private async ValueTask WriteIpcMessageLengthAsync(int length, CancellationToken cancellationToken)
-        {
-            using (Buffers.RentReturn(_options.SizeOfIpcLength, out Memory<byte> buffer))
-            {
-                Memory<byte> currentBufferPosition = buffer;
-                if (!_options.WriteLegacyIpcFormat)
-                {
-                    BinaryPrimitives.WriteInt32LittleEndian(
-                        currentBufferPosition.Span, MessageSerializer.IpcContinuationToken);
-                    currentBufferPosition = currentBufferPosition.Slice(sizeof(int));
-                }
-
-                BinaryPrimitives.WriteInt32LittleEndian(currentBufferPosition.Span, length);
-                await BaseStream.WriteAsync(buffer, cancellationToken).ConfigureAwait(false);
-            }
-        }
-
-        protected int CalculatePadding(long offset, int alignment = 8)
-        {
-            long result = BitUtility.RoundUpToMultiplePowerOfTwo(offset, alignment) - offset;
-            checked
-            {
-                return (int)result;
-            }
-        }
-
-        private static int CalculatePaddedBufferLength(int length)
-        {
-            long result = BitUtility.RoundUpToMultiplePowerOfTwo(length, MemoryAllocator.DefaultAlignment);
-            checked
-            {
-                return (int)result;
-            }
-        }
-
-        private protected void WritePadding(int length)
-        {
-            if (length > 0)
-            {
-                BaseStream.Write(s_padding.AsMemory(0, Math.Min(s_padding.Length, length)));
-            }
-        }
-
-        private protected ValueTask WritePaddingAsync(int length)
-        {
-            if (length > 0)
-            {
-                return BaseStream.WriteAsync(s_padding.AsMemory(0, Math.Min(s_padding.Length, length)));
-            }
-
-            return default;
-        }
-
-        public virtual void Dispose()
-        {
-            if (!_leaveOpen)
-            {
-                BaseStream.Dispose();
-            }
-            _fallbackCompressionStream.Dispose();
-        }
-    }
-
-    internal static class DictionaryCollector
-    {
-        internal static void Collect(RecordBatch recordBatch, ref DictionaryMemo dictionaryMemo)
-        {
-            Schema schema = recordBatch.Schema;
-            for (int i = 0; i < schema.FieldsList.Count; i++)
-            {
-                Field field = schema.GetFieldByIndex(i);
-                IArrowArray array = recordBatch.Column(i);
-
-                CollectDictionary(field, array.Data, ref dictionaryMemo);
-            }
-        }
-
-        private static void CollectDictionary(Field field, ArrayData arrayData, ref DictionaryMemo dictionaryMemo)
-        {
-            if (field.DataType is DictionaryType dictionaryType)
-            {
-                if (arrayData.Dictionary == null)
-                {
-                    throw new ArgumentException($"{nameof(arrayData.Dictionary)} must not be null");
-                }
-                arrayData.Dictionary.EnsureDataType(dictionaryType.ValueType.TypeId);
-
-                IArrowArray dictionary = ArrowArrayFactory.BuildArray(arrayData.Dictionary);
-                WalkChildren(dictionary.Data, ref dictionaryMemo);
-
-                dictionaryMemo ??= new DictionaryMemo();
-                long id = dictionaryMemo.GetOrAssignId(field);
-
-                dictionaryMemo.AddOrReplaceDictionary(id, dictionary);
-            }
-            else
-            {
-                WalkChildren(arrayData, ref dictionaryMemo);
-            }
-        }
-
-        private static void WalkChildren(ArrayData arrayData, ref DictionaryMemo dictionaryMemo)
-        {
-            ArrayData[] children = arrayData.Children;
-
-            if (children == null)
-            {
-                return;
-            }
-
-            if (arrayData.DataType is NestedType nestedType)
-            {
-                for (int i = 0; i < nestedType.Fields.Count; i++)
-                {
-                    Field childField = nestedType.Fields[i];
-                    ArrayData child = children[i];
-
-                    CollectDictionary(childField, child, ref dictionaryMemo);
-                }
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ArrowTypeFlatbufferBuilder.cs b/csharp/src/Apache.Arrow/Ipc/ArrowTypeFlatbufferBuilder.cs
deleted file mode 100644
index d1fb921..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ArrowTypeFlatbufferBuilder.cs
+++ /dev/null
@@ -1,412 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Flatbuf;
-using Apache.Arrow.Types;
-using Google.FlatBuffers;
-using DateUnit = Apache.Arrow.Flatbuf.DateUnit;
-using TimeUnit = Apache.Arrow.Types.TimeUnit;
-
-namespace Apache.Arrow.Ipc
-{
-    internal class ArrowTypeFlatbufferBuilder
-    {
-        public struct FieldType
-        {
-            public readonly Flatbuf.Type Type;
-            public readonly int Offset;
-
-            public static FieldType Build<T>(Flatbuf.Type type, Offset<T> offset)
-                where T : struct =>
-                new FieldType(type, offset.Value);
-
-            public FieldType(Flatbuf.Type type, int offset)
-            {
-                Type = type;
-                Offset = offset;
-            }
-        }
-
-        class TypeVisitor :
-            IArrowTypeVisitor<BooleanType>,
-            IArrowTypeVisitor<Int8Type>,
-            IArrowTypeVisitor<Int16Type>,
-            IArrowTypeVisitor<Int32Type>,
-            IArrowTypeVisitor<Int64Type>,
-            IArrowTypeVisitor<UInt8Type>,
-            IArrowTypeVisitor<UInt16Type>,
-            IArrowTypeVisitor<UInt32Type>,
-            IArrowTypeVisitor<UInt64Type>,
-#if NET5_0_OR_GREATER
-            IArrowTypeVisitor<HalfFloatType>,
-#endif
-            IArrowTypeVisitor<FloatType>,
-            IArrowTypeVisitor<DoubleType>,
-            IArrowTypeVisitor<StringType>,
-            IArrowTypeVisitor<StringViewType>,
-            IArrowTypeVisitor<LargeStringType>,
-            IArrowTypeVisitor<Date32Type>,
-            IArrowTypeVisitor<Date64Type>,
-            IArrowTypeVisitor<Time32Type>,
-            IArrowTypeVisitor<Time64Type>,
-            IArrowTypeVisitor<DurationType>,
-            IArrowTypeVisitor<IntervalType>,
-            IArrowTypeVisitor<BinaryType>,
-            IArrowTypeVisitor<BinaryViewType>,
-            IArrowTypeVisitor<LargeBinaryType>,
-            IArrowTypeVisitor<TimestampType>,
-            IArrowTypeVisitor<ListType>,
-            IArrowTypeVisitor<ListViewType>,
-            IArrowTypeVisitor<LargeListType>,
-            IArrowTypeVisitor<FixedSizeListType>,
-            IArrowTypeVisitor<UnionType>,
-            IArrowTypeVisitor<StructType>,
-            IArrowTypeVisitor<Decimal32Type>,
-            IArrowTypeVisitor<Decimal64Type>,
-            IArrowTypeVisitor<Decimal128Type>,
-            IArrowTypeVisitor<Decimal256Type>,
-            IArrowTypeVisitor<DictionaryType>,
-            IArrowTypeVisitor<FixedSizeBinaryType>,
-            IArrowTypeVisitor<MapType>,
-            IArrowTypeVisitor<NullType>
-        {
-            private FlatBufferBuilder Builder { get; }
-
-            public FieldType Result { get; private set; }
-
-            public TypeVisitor(FlatBufferBuilder builder)
-            {
-                Builder = builder;
-            }
-
-            public void Visit(Int8Type type) => CreateIntType(type);
-            public void Visit(Int16Type type) => CreateIntType(type);
-            public void Visit(Int32Type type) => CreateIntType(type);
-            public void Visit(Int64Type type) => CreateIntType(type);
-            public void Visit(UInt8Type type) => CreateIntType(type);
-            public void Visit(UInt16Type type) => CreateIntType(type);
-            public void Visit(UInt32Type type) => CreateIntType(type);
-            public void Visit(UInt64Type type) => CreateIntType(type);
-
-            public void Visit(BooleanType type)
-            {
-                Flatbuf.Bool.StartBool(Builder);
-                Result = FieldType.Build(
-                    Flatbuf.Type.Bool,
-                    Flatbuf.Bool.EndBool(Builder));
-            }
-
-            public void Visit(BinaryType type)
-            {
-                Flatbuf.Binary.StartBinary(Builder);
-                Result = FieldType.Build(
-                    Flatbuf.Type.Binary,
-                    Flatbuf.Binary.EndBinary(Builder));
-            }
-
-            public void Visit(BinaryViewType type)
-            {
-                Flatbuf.BinaryView.StartBinaryView(Builder);
-                Offset<BinaryView> offset = Flatbuf.BinaryView.EndBinaryView(Builder);
-                Result = FieldType.Build(
-                    Flatbuf.Type.BinaryView, offset);
-            }
-
-            public void Visit(LargeBinaryType type)
-            {
-                Flatbuf.LargeBinary.StartLargeBinary(Builder);
-                Offset<LargeBinary> offset = Flatbuf.LargeBinary.EndLargeBinary(Builder);
-                Result = FieldType.Build(
-                    Flatbuf.Type.LargeBinary, offset);
-            }
-
-            public void Visit(ListType type)
-            {
-                Flatbuf.List.StartList(Builder);
-                Result = FieldType.Build(
-                    Flatbuf.Type.List,
-                    Flatbuf.List.EndList(Builder));
-            }
-
-            public void Visit(ListViewType type)
-            {
-                Flatbuf.ListView.StartListView(Builder);
-                Result = FieldType.Build(
-                    Flatbuf.Type.ListView,
-                    Flatbuf.ListView.EndListView(Builder));
-            }
-
-            public void Visit(LargeListType type)
-            {
-                Flatbuf.LargeList.StartLargeList(Builder);
-                Result = FieldType.Build(
-                    Flatbuf.Type.LargeList,
-                    Flatbuf.LargeList.EndLargeList(Builder));
-            }
-
-            public void Visit(FixedSizeListType type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.FixedSizeList,
-                    Flatbuf.FixedSizeList.CreateFixedSizeList(Builder, type.ListSize));
-            }
-
-            public void Visit(UnionType type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Union,
-                    Flatbuf.Union.CreateUnion(Builder, ToFlatBuffer(type.Mode), Flatbuf.Union.CreateTypeIdsVector(Builder, type.TypeIds)));
-            }
-
-            public void Visit(StringType type)
-            {
-                Flatbuf.Utf8.StartUtf8(Builder);
-                Offset<Utf8> offset = Flatbuf.Utf8.EndUtf8(Builder);
-                Result = FieldType.Build(
-                    Flatbuf.Type.Utf8, offset);
-            }
-
-            public void Visit(StringViewType type)
-            {
-                Flatbuf.Utf8View.StartUtf8View(Builder);
-                Offset<Utf8View> offset = Flatbuf.Utf8View.EndUtf8View(Builder);
-                Result = FieldType.Build(
-                    Flatbuf.Type.Utf8View, offset);
-            }
-
-            public void Visit(LargeStringType type)
-            {
-                Flatbuf.LargeUtf8.StartLargeUtf8(Builder);
-                Offset<LargeUtf8> offset = Flatbuf.LargeUtf8.EndLargeUtf8(Builder);
-                Result = FieldType.Build(
-                    Flatbuf.Type.LargeUtf8, offset);
-            }
-
-            public void Visit(TimestampType type)
-            {
-                StringOffset timezoneStringOffset = default;
-
-                if (!string.IsNullOrWhiteSpace(type.Timezone))
-                    timezoneStringOffset = Builder.CreateString(type.Timezone);
-
-                Result = FieldType.Build(
-                    Flatbuf.Type.Timestamp,
-                    Flatbuf.Timestamp.CreateTimestamp(Builder, ToFlatBuffer(type.Unit), timezoneStringOffset));
-            }
-
-            public void Visit(Date32Type type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Date,
-                    Flatbuf.Date.CreateDate(Builder, DateUnit.DAY));
-            }
-
-            public void Visit(Date64Type type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Date,
-                    Flatbuf.Date.CreateDate(Builder));
-            }
-
-            public void Visit(Time32Type type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Time,
-                    Flatbuf.Time.CreateTime(Builder, ToFlatBuffer(type.Unit)));
-            }
-
-#if NET5_0_OR_GREATER
-            public void Visit(HalfFloatType type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.FloatingPoint,
-                    Flatbuf.FloatingPoint.CreateFloatingPoint(Builder, Precision.HALF));
-            }
-#endif
-
-            public void Visit(FloatType type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.FloatingPoint,
-                    Flatbuf.FloatingPoint.CreateFloatingPoint(Builder, Precision.SINGLE));
-            }
-
-            public void Visit(DoubleType type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.FloatingPoint,
-                    Flatbuf.FloatingPoint.CreateFloatingPoint(Builder, Precision.DOUBLE));
-            }
-
-            public void Visit(Time64Type type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Time,
-                    Flatbuf.Time.CreateTime(Builder, ToFlatBuffer(type.Unit), 64));
-            }
-
-            public void Visit(DurationType type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Duration,
-                    Flatbuf.Duration.CreateDuration(Builder, ToFlatBuffer(type.Unit)));
-            }
-
-            public void Visit(IntervalType type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Interval,
-                    Flatbuf.Interval.CreateInterval(Builder, ToFlatBuffer(type.Unit)));
-            }
-
-            public void Visit(StructType type)
-            {
-                Flatbuf.Struct_.StartStruct_(Builder);
-                Result = FieldType.Build(Flatbuf.Type.Struct_, Flatbuf.Struct_.EndStruct_(Builder));
-            }
-
-            public void Visit(Decimal32Type type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Decimal,
-                    Flatbuf.Decimal.CreateDecimal(Builder, type.Precision, type.Scale, type.BitWidth));
-            }
-
-            public void Visit(Decimal64Type type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Decimal,
-                    Flatbuf.Decimal.CreateDecimal(Builder, type.Precision, type.Scale, type.BitWidth));
-            }
-
-            public void Visit(Decimal128Type type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Decimal,
-                    Flatbuf.Decimal.CreateDecimal(Builder, type.Precision, type.Scale, type.BitWidth));
-            }
-
-            public void Visit(Decimal256Type type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Decimal,
-                    Flatbuf.Decimal.CreateDecimal(Builder, type.Precision, type.Scale, type.BitWidth));
-            }
-
-            private void CreateIntType(NumberType type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Int,
-                    Flatbuf.Int.CreateInt(Builder, type.BitWidth, type.IsSigned));
-            }
-
-            public void Visit(DictionaryType type)
-            {
-                // In this library, the dictionary "type" is a logical construct. Here we
-                // pass through to the value type, as we've already captured the index
-                // type in the DictionaryEncoding metadata in the parent field
-                type.ValueType.Accept(this);
-            }
-            
-            public void Visit(FixedSizeBinaryType type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.FixedSizeBinary,
-                    Flatbuf.FixedSizeBinary.CreateFixedSizeBinary(Builder, type.ByteWidth));
-            }
-
-            public void Visit(MapType type)
-            {
-                Result = FieldType.Build(
-                    Flatbuf.Type.Map,
-                    Flatbuf.Map.CreateMap(Builder, type.KeySorted));
-            }
-
-            public void Visit(NullType type)
-            {
-                Flatbuf.Null.StartNull(Builder);
-                Result = FieldType.Build(
-                    Flatbuf.Type.Null,
-                    Flatbuf.Null.EndNull(Builder));
-            }
-
-            public void Visit(IArrowType type)
-            {
-                throw new NotImplementedException($"Cannot visit type {type}");
-            }
-        }
-
-        private readonly TypeVisitor _visitor;
-
-        public ArrowTypeFlatbufferBuilder(FlatBufferBuilder builder)
-        {
-            _visitor = new TypeVisitor(builder);
-        }
-
-        public FieldType BuildFieldType(Field field)
-        {
-            field.DataType.Accept(_visitor);
-            return _visitor.Result;
-        }
-
-        private static Flatbuf.TimeUnit ToFlatBuffer(TimeUnit unit)
-        {
-            Flatbuf.TimeUnit result;
-
-            switch (unit)
-            {
-                case TimeUnit.Microsecond:
-                    result = Flatbuf.TimeUnit.MICROSECOND;
-                    break;
-                case TimeUnit.Millisecond:
-                    result = Flatbuf.TimeUnit.MILLISECOND;
-                    break;
-                case TimeUnit.Nanosecond:
-                    result = Flatbuf.TimeUnit.NANOSECOND;
-                    break;
-                case TimeUnit.Second:
-                    result = Flatbuf.TimeUnit.SECOND;
-                    break;
-                default:
-                    throw new ArgumentException(nameof(unit),
-                        $"unsupported timestamp unit <{unit}>");
-            }
-
-            return result;
-        }
-
-        private static Flatbuf.UnionMode ToFlatBuffer(Types.UnionMode mode)
-        {
-            return mode switch
-            {
-                Types.UnionMode.Dense => Flatbuf.UnionMode.Dense,
-                Types.UnionMode.Sparse => Flatbuf.UnionMode.Sparse,
-                _ => throw new ArgumentException($"unsupported union mode <{mode}>", nameof(mode)),
-            };
-        }
-
-        private static Flatbuf.IntervalUnit ToFlatBuffer(Types.IntervalUnit unit)
-        {
-            return unit switch
-            {
-                Types.IntervalUnit.YearMonth => Flatbuf.IntervalUnit.YEAR_MONTH,
-                Types.IntervalUnit.DayTime => Flatbuf.IntervalUnit.DAY_TIME,
-                Types.IntervalUnit.MonthDayNanosecond => Flatbuf.IntervalUnit.MONTH_DAY_NANO,
-                _ => throw new ArgumentException($"unsupported interval unit <{unit}>", nameof(unit))
-            };
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/Block.cs b/csharp/src/Apache.Arrow/Ipc/Block.cs
deleted file mode 100644
index 4aaa3b4..0000000
--- a/csharp/src/Apache.Arrow/Ipc/Block.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Ipc
-{
-    internal readonly struct Block
-    {
-        public readonly long Offset;
-        public readonly long BodyLength;
-        public readonly int MetadataLength;
-
-        public Block(long offset, long length, int metadataLength)
-        {
-            Offset = offset;
-            BodyLength = length;
-            MetadataLength = metadataLength;
-        }
-
-        public Block(Flatbuf.Block block)
-        {
-            Offset = block.Offset;
-            BodyLength = block.BodyLength;
-            MetadataLength = block.MetaDataLength;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/CompressionCodecType.cs b/csharp/src/Apache.Arrow/Ipc/CompressionCodecType.cs
deleted file mode 100644
index 6e8ecaa..0000000
--- a/csharp/src/Apache.Arrow/Ipc/CompressionCodecType.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Ipc
-{
-    public enum CompressionCodecType
-    {
-        Lz4Frame,
-        Zstd,
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/DecompressingBufferCreator.cs b/csharp/src/Apache.Arrow/Ipc/DecompressingBufferCreator.cs
deleted file mode 100644
index dd8654a..0000000
--- a/csharp/src/Apache.Arrow/Ipc/DecompressingBufferCreator.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers.Binary;
-using Apache.Arrow.Memory;
-
-namespace Apache.Arrow.Ipc
-{
-    /// <summary>
-    /// Creates Arrow buffers from compressed data
-    /// </summary>
-    internal sealed class DecompressingBufferCreator : IBufferCreator
-    {
-        private readonly ICompressionCodec _compressionCodec;
-        private readonly MemoryAllocator _allocator;
-
-        public DecompressingBufferCreator(ICompressionCodec compressionCodec, MemoryAllocator allocator)
-        {
-            _compressionCodec = compressionCodec;
-            _allocator = allocator;
-        }
-
-        public ArrowBuffer CreateBuffer(ReadOnlyMemory<byte> source)
-        {
-            // See the BodyCompressionMethod enum in format/Message.fbs
-            // for documentation on the Buffer compression method used here.
-
-            if (source.Length < 8)
-            {
-                throw new Exception($"Invalid compressed data buffer size ({source.Length}), expected at least 8 bytes");
-            }
-
-            // First 8 bytes give the uncompressed data length
-            var uncompressedLength = BinaryPrimitives.ReadInt64LittleEndian(source.Span.Slice(0, 8));
-            if (uncompressedLength == -1)
-            {
-                // The buffer is not actually compressed
-                return new ArrowBuffer(source.Slice(8));
-            }
-
-            var outputData = _allocator.Allocate(Convert.ToInt32(uncompressedLength));
-            var decompressedLength = _compressionCodec.Decompress(source.Slice(8), outputData.Memory);
-            if (decompressedLength != uncompressedLength)
-            {
-                throw new Exception($"Expected to decompress {uncompressedLength} bytes, but got {decompressedLength} bytes");
-            }
-
-            return new ArrowBuffer(outputData);
-        }
-
-        public void Dispose()
-        {
-            _compressionCodec.Dispose();
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/DictionaryMemo.cs b/csharp/src/Apache.Arrow/Ipc/DictionaryMemo.cs
deleted file mode 100644
index b107cc6..0000000
--- a/csharp/src/Apache.Arrow/Ipc/DictionaryMemo.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow.Ipc
-{
-    class DictionaryMemo
-    {
-        private readonly Dictionary<long, IArrowArray> _idToDictionary;
-        private readonly Dictionary<long, IArrowType> _idToValueType;
-        private readonly Dictionary<Field, long> _fieldToId;
-
-        public DictionaryMemo()
-        {
-            _idToDictionary = new Dictionary<long, IArrowArray>();
-            _idToValueType = new Dictionary<long, IArrowType>();
-            _fieldToId = new Dictionary<Field, long>();
-        }
-
-        public int DictionaryCount => _fieldToId.Count;
-        public int LoadedDictionaryCount => _idToDictionary.Count;
-
-        public IArrowType GetDictionaryType(long id)
-        {
-            if (!_idToValueType.TryGetValue(id, out IArrowType type))
-            {
-                throw new ArgumentException($"Dictionary with id {id} not found");
-            }
-            return type;
-        }
-
-        public IArrowArray GetDictionary(long id)
-        {
-            if (!_idToDictionary.TryGetValue(id, out IArrowArray dictionary))
-            {
-                throw new ArgumentException($"Dictionary with id {id} not found");
-            }
-            return dictionary;
-        }
-
-        public void AddField(long id, Field field)
-        {
-            if (_fieldToId.ContainsKey(field))
-            {
-                throw new ArgumentException($"Field {field.Name} is already in Memo");
-            }
-
-            if (field.DataType.TypeId != ArrowTypeId.Dictionary)
-            {
-                throw new ArgumentException($"Field type is not DictionaryType: Name={field.Name}, {field.DataType.Name}");
-            }
-
-            IArrowType valueType = ((DictionaryType)field.DataType).ValueType;
-
-            if (_idToValueType.TryGetValue(id, out IArrowType valueTypeInDic))
-            {
-                if (valueType != valueTypeInDic)
-                {
-                    throw new ArgumentException($"Field type {field.DataType.Name} does not match the existing type {valueTypeInDic})");
-                }
-            }
-            else
-            {
-                _idToValueType.Add(id, valueType);
-            }
-
-            _fieldToId.Add(field, id);
-        }
-
-        public long GetId(Field field)
-        {
-            if (!_fieldToId.TryGetValue(field, out long id))
-            {
-                throw new ArgumentException($"Field with name {field.Name} not found");
-            }
-            return id;
-        }
-
-        public long GetOrAssignId(Field field)
-        {
-            if (!_fieldToId.TryGetValue(field, out long id))
-            {
-                id = _fieldToId.Count;
-                AddField(id, field);
-            }
-            return id;
-        }
-
-        public void AddOrReplaceDictionary(long id, IArrowArray dictionary)
-        {
-            _idToDictionary[id] = dictionary;
-        }
-
-        public void AddDeltaDictionary(long id, IArrowArray deltaDictionary, MemoryAllocator allocator = default)
-        {
-            IArrowArray currentDictionary = _idToDictionary[id];
-            IArrowArray dictionary = ArrowArrayConcatenator.Concatenate(new List<IArrowArray>{ currentDictionary, deltaDictionary }, allocator);
-            AddOrReplaceDictionary(id, dictionary);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/IArrowArrayStream.cs b/csharp/src/Apache.Arrow/Ipc/IArrowArrayStream.cs
deleted file mode 100644
index 8dae61d..0000000
--- a/csharp/src/Apache.Arrow/Ipc/IArrowArrayStream.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Ipc
-{
-    public interface IArrowArrayStream : IArrowReader, IDisposable
-    {
-        Schema Schema { get; }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/IArrowReader.cs b/csharp/src/Apache.Arrow/Ipc/IArrowReader.cs
deleted file mode 100644
index 255ea4f..0000000
--- a/csharp/src/Apache.Arrow/Ipc/IArrowReader.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.Ipc
-{
-    public interface IArrowReader
-    {
-        ValueTask<RecordBatch> ReadNextRecordBatchAsync(
-            CancellationToken cancellationToken = default);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/IBufferCreator.cs b/csharp/src/Apache.Arrow/Ipc/IBufferCreator.cs
deleted file mode 100644
index a6be81f..0000000
--- a/csharp/src/Apache.Arrow/Ipc/IBufferCreator.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Ipc
-{
-    /// <summary>
-    /// Creates Arrow buffers from possibly compressed data
-    /// </summary>
-    internal interface IBufferCreator : IDisposable
-    {
-        ArrowBuffer CreateBuffer(ReadOnlyMemory<byte> source);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ICompressionCodec.cs b/csharp/src/Apache.Arrow/Ipc/ICompressionCodec.cs
deleted file mode 100644
index 16c01d7..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ICompressionCodec.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-
-namespace Apache.Arrow.Ipc
-{
-    /// <summary>
-    /// Codec for data compression and decompression (currently only decompression is supported)
-    /// </summary>
-    public interface ICompressionCodec : IDisposable
-    {
-        /// <summary>
-        /// Decompresses a compressed data buffer
-        /// </summary>
-        /// <param name="source">Data buffer to read compressed data from</param>
-        /// <param name="destination">Data buffer to write decompressed data to</param>
-        /// <returns>The number of decompressed bytes written into the destination</returns>
-        int Decompress(ReadOnlyMemory<byte> source, Memory<byte> destination);
-
-        /// <summary>
-        /// Write compressed data
-        /// </summary>
-        /// <param name="source">The data to compress</param>
-        /// <param name="destination">The stream to write compressed data to</param>
-        void Compress(ReadOnlyMemory<byte> source, Stream destination)
-#if NET6_0_OR_GREATER
-        {
-            throw new NotImplementedException("This codec does not support compression");
-        }
-#else
-        ;
-#endif
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ICompressionCodecFactory.cs b/csharp/src/Apache.Arrow/Ipc/ICompressionCodecFactory.cs
deleted file mode 100644
index f367b15..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ICompressionCodecFactory.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Ipc
-{
-    /// <summary>
-    /// Provides compression codec implementations for different compression codecs
-    /// </summary>
-    public interface ICompressionCodecFactory
-    {
-        /// <summary>
-        /// Create a new compression codec
-        /// </summary>
-        /// <param name="compressionCodecType">The type of codec to create</param>
-        /// <returns>The created codec</returns>
-        ICompressionCodec CreateCodec(CompressionCodecType compressionCodecType);
-
-        /// <summary>
-        /// Create a new compression codec with a specified compression level
-        /// </summary>
-        /// <param name="compressionCodecType">The type of codec to create</param>
-        /// <param name="compressionLevel">The compression level to use when compressing data</param>
-        /// <returns>The created codec</returns>
-        ICompressionCodec CreateCodec(CompressionCodecType compressionCodecType, int? compressionLevel)
-#if NET6_0_OR_GREATER
-        {
-            // Default implementation ignores the compression level
-            return CreateCodec(compressionCodecType);
-        }
-#else
-        ;
-#endif
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ITryCompressionCodec.cs b/csharp/src/Apache.Arrow/Ipc/ITryCompressionCodec.cs
deleted file mode 100644
index 123d9eb..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ITryCompressionCodec.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Ipc
-{
-    public interface ITryCompressionCodec : ICompressionCodec
-    {
-        /// <summary>
-        /// Try to write compressed data to a fixed length memory span
-        /// </summary>
-        /// <param name="source">The data to compress</param>
-        /// <param name="destination">Memory to write compressed data to</param>
-        /// <param name="bytesWritten">The number of bytes written to the destination</param>
-        /// <returns>true if compression was successful, false if the destination buffer is too small</returns>
-        bool TryCompress(ReadOnlyMemory<byte> source, Memory<byte> destination, out int bytesWritten);
-
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/IpcOptions.cs b/csharp/src/Apache.Arrow/Ipc/IpcOptions.cs
deleted file mode 100644
index 8484c9a..0000000
--- a/csharp/src/Apache.Arrow/Ipc/IpcOptions.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Ipc
-{
-    public class IpcOptions
-    {
-        internal static IpcOptions Default { get; } = new IpcOptions();
-
-        /// <summary>
-        /// Write the pre-0.15.0 encapsulated IPC message format
-        /// consisting of a 4-byte prefix instead of 8 byte.
-        /// </summary>
-        public bool WriteLegacyIpcFormat { get; set; }
-
-        /// <summary>
-        /// The compression codec to use to compress data buffers.
-        /// If null (the default value), no compression is used.
-        /// </summary>
-        public CompressionCodecType? CompressionCodec { get; set; }
-
-        /// <summary>
-        /// The compression codec factory used to create compression codecs.
-        /// Must be provided if a CompressionCodec is specified.
-        /// </summary>
-        public ICompressionCodecFactory CompressionCodecFactory { get; set; }
-
-        /// <summary>
-        /// Sets the compression level to use for codecs that support this.
-        /// </summary>
-        public int? CompressionLevel { get; set; }
-
-        public IpcOptions()
-        {
-        }
-
-        /// <summary>
-        /// Gets the number of bytes used in the IPC message prefix.
-        /// </summary>
-        internal int SizeOfIpcLength => WriteLegacyIpcFormat ? 4 : 8;
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/MessageSerializer.cs b/csharp/src/Apache.Arrow/Ipc/MessageSerializer.cs
deleted file mode 100644
index 7c7f7a3..0000000
--- a/csharp/src/Apache.Arrow/Ipc/MessageSerializer.cs
+++ /dev/null
@@ -1,248 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow.Ipc
-{
-    internal class MessageSerializer
-    {
-        public const int IpcContinuationToken = -1;
-
-        public static Types.NumberType GetNumberType(int bitWidth, bool signed)
-        {
-            if (signed)
-            {
-                if (bitWidth == 8)
-                    return Types.Int8Type.Default;
-                if (bitWidth == 16)
-                    return Types.Int16Type.Default;
-                if (bitWidth == 32)
-                    return Types.Int32Type.Default;
-                if (bitWidth == 64)
-                    return Types.Int64Type.Default;
-            }
-            else
-            {
-                if (bitWidth == 8)
-                    return Types.UInt8Type.Default;
-                if (bitWidth == 16)
-                    return Types.UInt16Type.Default;
-                if (bitWidth == 32)
-                    return Types.UInt32Type.Default;
-                if (bitWidth == 64)
-                    return Types.UInt64Type.Default;
-            }
-            throw new Exception($"Unexpected bit width of {bitWidth} for " +
-                                $"{(signed ? "signed " : "unsigned")} integer.");
-        }
-
-        internal static Schema GetSchema(Flatbuf.Schema schema, ref DictionaryMemo dictionaryMemo)
-        {
-            List<Field> fields = new List<Field>();
-            for (int i = 0; i < schema.FieldsLength; i++)
-            {
-                Flatbuf.Field field = schema.Fields(i).GetValueOrDefault();
-                fields.Add(FieldFromFlatbuffer(field, ref dictionaryMemo));
-            }
-
-            Dictionary<string, string> metadata = schema.CustomMetadataLength > 0 ? new Dictionary<string, string>() : null;
-            for (int i = 0; i < schema.CustomMetadataLength; i++)
-            {
-                Flatbuf.KeyValue keyValue = schema.CustomMetadata(i).GetValueOrDefault();
-
-                metadata[keyValue.Key] = keyValue.Value;
-            }
-
-            return new Schema(fields, metadata, copyCollections: false);
-        }
-
-        private static Field FieldFromFlatbuffer(Flatbuf.Field flatbufField, ref DictionaryMemo dictionaryMemo)
-        {
-            Field[] childFields = flatbufField.ChildrenLength > 0 ? new Field[flatbufField.ChildrenLength] : null;
-            for (int i = 0; i < flatbufField.ChildrenLength; i++)
-            {
-                Flatbuf.Field? childFlatbufField = flatbufField.Children(i);
-                childFields[i] = FieldFromFlatbuffer(childFlatbufField.Value, ref dictionaryMemo);
-            }
-
-            Flatbuf.DictionaryEncoding? dictionaryEncoding = flatbufField.Dictionary;
-            IArrowType type = GetFieldArrowType(flatbufField, childFields);
-
-            if (dictionaryEncoding.HasValue)
-            {
-                Flatbuf.Int? indexTypeAsInt = dictionaryEncoding.Value.IndexType;
-                IArrowType indexType = indexTypeAsInt.HasValue ?
-                    GetNumberType(indexTypeAsInt.Value.BitWidth, indexTypeAsInt.Value.IsSigned) :
-                    GetNumberType(Int32Type.Default.BitWidth, Int32Type.Default.IsSigned);
-
-                type = new DictionaryType(indexType, type, dictionaryEncoding.Value.IsOrdered);
-            }
-
-            Dictionary<string, string> metadata = flatbufField.CustomMetadataLength > 0 ? new Dictionary<string, string>() : null;
-            for (int i = 0; i < flatbufField.CustomMetadataLength; i++)
-            {
-                Flatbuf.KeyValue keyValue = flatbufField.CustomMetadata(i).GetValueOrDefault();
-
-                metadata[keyValue.Key] = keyValue.Value;
-            }
-
-            var arrowField = new Field(flatbufField.Name, type, flatbufField.Nullable, metadata, copyCollections: false);
-
-            if (dictionaryEncoding.HasValue)
-            {
-                dictionaryMemo ??= new DictionaryMemo();
-                dictionaryMemo.AddField(dictionaryEncoding.Value.Id, arrowField);
-            }
-
-            return arrowField;
-        }
-
-        private static Types.IArrowType GetFieldArrowType(Flatbuf.Field field, Field[] childFields = null)
-        {
-            switch (field.TypeType)
-            {
-                case Flatbuf.Type.Null:
-                    return Types.NullType.Default;
-                case Flatbuf.Type.Int:
-                    Flatbuf.Int intMetaData = field.Type<Flatbuf.Int>().Value;
-                    return MessageSerializer.GetNumberType(intMetaData.BitWidth, intMetaData.IsSigned);
-                case Flatbuf.Type.FloatingPoint:
-                    Flatbuf.FloatingPoint floatingPointTypeMetadata = field.Type<Flatbuf.FloatingPoint>().Value;
-                    switch (floatingPointTypeMetadata.Precision)
-                    {
-                        case Flatbuf.Precision.SINGLE:
-                            return Types.FloatType.Default;
-                        case Flatbuf.Precision.DOUBLE:
-                            return Types.DoubleType.Default;
-                        case Flatbuf.Precision.HALF:
-                            return Types.HalfFloatType.Default;
-                        default:
-                            throw new InvalidDataException("Unsupported floating point precision");
-                    }
-                case Flatbuf.Type.Bool:
-                    return Types.BooleanType.Default;
-                case Flatbuf.Type.Decimal:
-                    Flatbuf.Decimal decMeta = field.Type<Flatbuf.Decimal>().Value;
-                    switch (decMeta.BitWidth)
-                    {
-                        case 32:
-                            return new Types.Decimal32Type(decMeta.Precision, decMeta.Scale);
-                        case 64:
-                            return new Types.Decimal64Type(decMeta.Precision, decMeta.Scale);
-                        case 128:
-                            return new Types.Decimal128Type(decMeta.Precision, decMeta.Scale);
-                        case 256:
-                            return new Types.Decimal256Type(decMeta.Precision, decMeta.Scale);
-                        default:
-                            throw new InvalidDataException("Unsupported decimal bit width " + decMeta.BitWidth);
-                    }
-                case Flatbuf.Type.Date:
-                    Flatbuf.Date dateMeta = field.Type<Flatbuf.Date>().Value;
-                    switch (dateMeta.Unit)
-                    {
-                        case Flatbuf.DateUnit.DAY:
-                            return Types.Date32Type.Default;
-                        case Flatbuf.DateUnit.MILLISECOND:
-                            return Types.Date64Type.Default;
-                        default:
-                            throw new InvalidDataException("Unsupported date unit");
-                    }
-                case Flatbuf.Type.Time:
-                    Flatbuf.Time timeMeta = field.Type<Flatbuf.Time>().Value;
-                    switch (timeMeta.BitWidth)
-                    {
-                        case 32:
-                            return (Time32Type)TimeType.FromTimeUnit(timeMeta.Unit.ToArrow());
-                        case 64:
-                            return (Time64Type)TimeType.FromTimeUnit(timeMeta.Unit.ToArrow());
-                        default:
-                            throw new InvalidDataException("Unsupported time bit width");
-                    }
-                case Flatbuf.Type.Timestamp:
-                    Flatbuf.Timestamp timestampTypeMetadata = field.Type<Flatbuf.Timestamp>().Value;
-                    Types.TimeUnit unit = timestampTypeMetadata.Unit.ToArrow();
-                    string timezone = timestampTypeMetadata.Timezone;
-                    return new Types.TimestampType(unit, timezone);
-                case Flatbuf.Type.Duration:
-                    Flatbuf.Duration durationMeta = field.Type<Flatbuf.Duration>().Value;
-                    return DurationType.FromTimeUnit(durationMeta.Unit.ToArrow());
-                case Flatbuf.Type.Interval:
-                    Flatbuf.Interval intervalMetadata = field.Type<Flatbuf.Interval>().Value;
-                    return Types.IntervalType.FromIntervalUnit(intervalMetadata.Unit.ToArrow());
-                case Flatbuf.Type.Utf8:
-                    return Types.StringType.Default;
-                case Flatbuf.Type.Utf8View:
-                    return Types.StringViewType.Default;
-                case Flatbuf.Type.LargeUtf8:
-                    return Types.LargeStringType.Default;
-                case Flatbuf.Type.FixedSizeBinary:
-                    Flatbuf.FixedSizeBinary fixedSizeBinaryMetadata = field.Type<Flatbuf.FixedSizeBinary>().Value;
-                    return new Types.FixedSizeBinaryType(fixedSizeBinaryMetadata.ByteWidth);
-                case Flatbuf.Type.Binary:
-                    return Types.BinaryType.Default;
-                case Flatbuf.Type.BinaryView:
-                    return Types.BinaryViewType.Default;
-                case Flatbuf.Type.LargeBinary:
-                    return Types.LargeBinaryType.Default;
-                case Flatbuf.Type.List:
-                    if (childFields == null || childFields.Length != 1)
-                    {
-                        throw new InvalidDataException($"List type must have exactly one child.");
-                    }
-                    return new Types.ListType(childFields[0]);
-                case Flatbuf.Type.ListView:
-                    if (childFields == null || childFields.Length != 1)
-                    {
-                        throw new InvalidDataException($"List view type must have exactly one child.");
-                    }
-                    return new Types.ListViewType(childFields[0]);
-                case Flatbuf.Type.LargeList:
-                    if (childFields == null || childFields.Length != 1)
-                    {
-                        throw new InvalidDataException($"Large list type must have exactly one child.");
-                    }
-                    return new Types.LargeListType(childFields[0]);
-                case Flatbuf.Type.FixedSizeList:
-                    if (childFields == null || childFields.Length != 1)
-                    {
-                        throw new InvalidDataException($"Fixed-size list type must have exactly one child.");
-                    }
-                    Flatbuf.FixedSizeList fixedSizeListMetadata = field.Type<Flatbuf.FixedSizeList>().Value;
-                    return new Types.FixedSizeListType(childFields[0], fixedSizeListMetadata.ListSize);
-                case Flatbuf.Type.Struct_:
-                    Debug.Assert(childFields != null);
-                    return new Types.StructType(childFields);
-                case Flatbuf.Type.Union:
-                    Debug.Assert(childFields != null);
-                    Flatbuf.Union unionMetadata = field.Type<Flatbuf.Union>().Value;
-                    return new Types.UnionType(childFields, unionMetadata.GetTypeIdsArray(), unionMetadata.Mode.ToArrow());
-                case Flatbuf.Type.Map:
-                    if (childFields == null || childFields.Length != 1)
-                    {
-                        throw new InvalidDataException($"Map type must have exactly one struct child.");
-                    }
-                    Flatbuf.Map meta = field.Type<Flatbuf.Map>().Value;
-                    return new Types.MapType(childFields[0], meta.KeysSorted);
-                default:
-                    throw new InvalidDataException($"Arrow primitive '{field.TypeType}' is unsupported.");
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/NoOpBufferCreator.cs b/csharp/src/Apache.Arrow/Ipc/NoOpBufferCreator.cs
deleted file mode 100644
index 13c22c7..0000000
--- a/csharp/src/Apache.Arrow/Ipc/NoOpBufferCreator.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Ipc
-{
-    /// <summary>
-    /// Creates Arrow buffers from uncompressed data
-    /// </summary>
-    internal sealed class NoOpBufferCreator : IBufferCreator
-    {
-        /// <summary>
-        /// Singleton instance, used as this class doesn't need to be disposed and has no state
-        /// </summary>
-        public static readonly NoOpBufferCreator Instance = new NoOpBufferCreator();
-
-        public ArrowBuffer CreateBuffer(ReadOnlyMemory<byte> source)
-        {
-            return new ArrowBuffer(source);
-        }
-
-        public void Dispose()
-        {
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Ipc/ReadOnlyMemoryBufferAllocator.cs b/csharp/src/Apache.Arrow/Ipc/ReadOnlyMemoryBufferAllocator.cs
deleted file mode 100644
index 0f96873..0000000
--- a/csharp/src/Apache.Arrow/Ipc/ReadOnlyMemoryBufferAllocator.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Google.FlatBuffers;
-using System;
-
-namespace Apache.Arrow.Ipc
-{
-    internal sealed class ReadOnlyMemoryBufferAllocator : ByteBufferAllocator
-    {
-        private readonly ReadOnlyMemory<byte> _buffer;
-
-        public ReadOnlyMemoryBufferAllocator(ReadOnlyMemory<byte> buffer)
-        {
-            _buffer = buffer;
-            Length = buffer.Length;
-        }
-
-        public override ReadOnlySpan<byte> ReadOnlySpan => _buffer.Span;
-        public override ReadOnlyMemory<byte> ReadOnlyMemory => _buffer;
-
-        // since this is read-only, the following are not supported
-        public override Memory<byte> Memory => throw new NotSupportedException();
-        public override Span<byte> Span => throw new NotSupportedException();
-        public override void GrowFront(int newSize) => throw new NotSupportedException();
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Memory/ExportedAllocationOwner.cs b/csharp/src/Apache.Arrow/Memory/ExportedAllocationOwner.cs
deleted file mode 100644
index 8084cd2..0000000
--- a/csharp/src/Apache.Arrow/Memory/ExportedAllocationOwner.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Diagnostics;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Threading;
-
-namespace Apache.Arrow.Memory
-{
-    internal sealed class ExportedAllocationOwner : INativeAllocationOwner, IDisposable
-    {
-        private readonly List<IntPtr> _pointers = new List<IntPtr>();
-        private long _allocationSize;
-        private long _referenceCount;
-        private bool _disposed;
-
-        ~ExportedAllocationOwner()
-        {
-            Dispose();
-        }
-
-        public IntPtr Allocate(int size)
-        {
-            GC.AddMemoryPressure(size);
-            return Acquire(Marshal.AllocHGlobal(size), 0, size);
-        }
-
-        public IntPtr Acquire(IntPtr ptr, int offset, int length)
-        {
-            _pointers.Add(ptr);
-            _allocationSize += length;
-            return ptr;
-        }
-
-        public void Release(IntPtr ptr, int offset, int length)
-        {
-            throw new InvalidOperationException();
-        }
-
-        public void IncRef()
-        {
-            Interlocked.Increment(ref _referenceCount);
-        }
-
-        public void DecRef()
-        {
-            if (Interlocked.Decrement(ref _referenceCount) == 0)
-            {
-                Dispose();
-            }
-        }
-
-        public void Dispose()
-        {
-            if (_disposed)
-            {
-                return;
-            }
-            for (int i = 0; i < _pointers.Count; i++)
-            {
-                if (_pointers[i] != IntPtr.Zero)
-                {
-                    Marshal.FreeHGlobal(_pointers[i]);
-                    _pointers[i] = IntPtr.Zero;
-                }
-            }
-            GC.RemoveMemoryPressure(_allocationSize);
-            GC.SuppressFinalize(this);
-            _disposed = true;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Memory/INativeAllocationOwner.cs b/csharp/src/Apache.Arrow/Memory/INativeAllocationOwner.cs
deleted file mode 100644
index a1a73eb..0000000
--- a/csharp/src/Apache.Arrow/Memory/INativeAllocationOwner.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Memory
-{
-    internal interface INativeAllocationOwner
-    {
-        void Release(IntPtr ptr, int offset, int length);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Memory/IOwnableAllocation.cs b/csharp/src/Apache.Arrow/Memory/IOwnableAllocation.cs
deleted file mode 100644
index a5e7565..0000000
--- a/csharp/src/Apache.Arrow/Memory/IOwnableAllocation.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Memory
-{
-    internal interface IOwnableAllocation
-    {
-        bool TryAcquire(out IntPtr ptr, out int offset, out int length);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Memory/ImportedAllocationOwner.cs b/csharp/src/Apache.Arrow/Memory/ImportedAllocationOwner.cs
deleted file mode 100644
index b29135d..0000000
--- a/csharp/src/Apache.Arrow/Memory/ImportedAllocationOwner.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.Threading;
-
-namespace Apache.Arrow.Memory
-{
-    internal abstract class ImportedAllocationOwner : INativeAllocationOwner
-    {
-        long _referenceCount;
-        long _managedMemory;
-
-        protected ImportedAllocationOwner()
-        {
-            _referenceCount = 1;
-        }
-
-        public IMemoryOwner<byte> AddMemory(IntPtr ptr, int offset, int length)
-        {
-            if (_referenceCount <= 0)
-            {
-                throw new ObjectDisposedException(typeof(ImportedAllocationOwner).Name);
-            }
-
-            NativeMemoryManager memory = new NativeMemoryManager(this, ptr, offset, length);
-            Interlocked.Increment(ref _referenceCount);
-            if (length > 0)
-            {
-                Interlocked.Add(ref _managedMemory, length);
-                GC.AddMemoryPressure(length);
-            }
-            return memory;
-        }
-
-        public void Release(IntPtr ptr, int offset, int length)
-        {
-            Release();
-        }
-
-        public void Release()
-        {
-            if (Interlocked.Decrement(ref _referenceCount) == 0)
-            {
-                if (_managedMemory > 0)
-                {
-                    GC.RemoveMemoryPressure(_managedMemory);
-                }
-                FinalRelease();
-            }
-        }
-
-        protected abstract void FinalRelease();
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Memory/MemoryAllocator.cs b/csharp/src/Apache.Arrow/Memory/MemoryAllocator.cs
deleted file mode 100644
index 58bd110..0000000
--- a/csharp/src/Apache.Arrow/Memory/MemoryAllocator.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.Threading;
-
-namespace Apache.Arrow.Memory
-{
-    public abstract class MemoryAllocator
-    {
-        public const int DefaultAlignment = 64;
-
-        private static IMemoryOwner<byte> NullMemoryOwner { get; } = new NullMemoryOwner();
-
-        public static Lazy<MemoryAllocator> Default { get; } = new Lazy<MemoryAllocator>(BuildDefault, true);
-
-        public class Stats
-        {
-            private long _bytesAllocated;
-            private long _allocations;
-
-            public long Allocations => Interlocked.Read(ref _allocations);
-            public long BytesAllocated => Interlocked.Read(ref _bytesAllocated);
-
-            internal void Allocate(int n)
-            {
-                Interlocked.Increment(ref _allocations);
-                Interlocked.Add(ref _bytesAllocated, n);
-            }
-        }
-
-        public Stats Statistics { get; }
-
-        protected int Alignment { get; }
-
-        protected MemoryAllocator(int alignment = DefaultAlignment)
-        {
-            Statistics = new Stats();
-            Alignment = alignment;
-        }
-
-        public IMemoryOwner<byte> Allocate(int length)
-        {
-            if (length < 0)
-            {
-                throw new ArgumentOutOfRangeException(nameof(length));
-            }
-
-            if (length == 0)
-            {
-                return NullMemoryOwner;
-            }
-
-            IMemoryOwner<byte> memoryOwner = AllocateInternal(length, out int bytesAllocated);
-
-            Statistics.Allocate(bytesAllocated);
-
-            return memoryOwner;
-        }
-
-        private static MemoryAllocator BuildDefault()
-        {
-            return new NativeMemoryAllocator(DefaultAlignment);
-        }
-
-        protected abstract IMemoryOwner<byte> AllocateInternal(int length, out int bytesAllocated);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Memory/NativeMemoryAllocator.cs b/csharp/src/Apache.Arrow/Memory/NativeMemoryAllocator.cs
deleted file mode 100644
index 57f8551..0000000
--- a/csharp/src/Apache.Arrow/Memory/NativeMemoryAllocator.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.Runtime.InteropServices;
-
-namespace Apache.Arrow.Memory
-{
-    public class NativeMemoryAllocator : MemoryAllocator
-    {
-        internal static readonly INativeAllocationOwner ExclusiveOwner = new NativeAllocationOwner();
-
-        public NativeMemoryAllocator(int alignment = DefaultAlignment) 
-            : base(alignment) { }
-
-        protected override IMemoryOwner<byte> AllocateInternal(int length, out int bytesAllocated)
-        {
-            // TODO: Ensure memory is released if exception occurs.
-
-            // TODO: Optimize storage overhead; native memory manager stores a pointer
-            // to allocated memory, offset, and the allocation size. 
-
-            // TODO: Should the allocation be moved to NativeMemory?
-
-            int size = length + Alignment;
-            IntPtr ptr =  Marshal.AllocHGlobal(size);
-            int offset = (int)(Alignment - (ptr.ToInt64() & (Alignment - 1)));
-            var manager = new NativeMemoryManager(ptr, offset, length);
-
-            bytesAllocated = (length + Alignment);
-
-            GC.AddMemoryPressure(bytesAllocated);
-
-            // Ensure all allocated memory is zeroed.
-            manager.Memory.Span.Fill(0);
-
-            return manager;
-        }
-
-        private sealed class NativeAllocationOwner : INativeAllocationOwner
-        {
-            public void Release(IntPtr ptr, int offset, int length)
-            {
-                Marshal.FreeHGlobal(ptr);
-                GC.RemoveMemoryPressure(length);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Memory/NativeMemoryManager.cs b/csharp/src/Apache.Arrow/Memory/NativeMemoryManager.cs
deleted file mode 100644
index d42ee52..0000000
--- a/csharp/src/Apache.Arrow/Memory/NativeMemoryManager.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.Runtime.CompilerServices;
-using System.Threading;
-
-namespace Apache.Arrow.Memory
-{
-    public class NativeMemoryManager : MemoryManager<byte>, IOwnableAllocation
-    {
-        private IntPtr _ptr;
-        private readonly int _offset;
-        private readonly int _length;
-        private readonly INativeAllocationOwner _owner;
-
-        public NativeMemoryManager(IntPtr ptr, int offset, int length)
-            : this(NativeMemoryAllocator.ExclusiveOwner, ptr, offset, length)
-        {
-        }
-
-        internal NativeMemoryManager(INativeAllocationOwner owner, IntPtr ptr, int offset, int length)
-        {
-            _ptr = ptr;
-            _offset = offset;
-            _length = length;
-            _owner = owner;
-        }
-
-#pragma warning disable CA2015 // TODO: is this correct?
-        ~NativeMemoryManager()
-        {
-            Dispose(false);
-        }
-#pragma warning restore CA2015
-
-        public override unsafe Span<byte> GetSpan()
-        {
-            void* ptr = CalculatePointer(0);
-            return new Span<byte>(ptr, _length);
-        }
-
-        public override unsafe MemoryHandle Pin(int elementIndex = 0)
-        {
-            // NOTE: Unmanaged memory doesn't require GC pinning because by definition it's not
-            // managed by the garbage collector.
-
-            void* ptr = CalculatePointer(elementIndex);
-            return new MemoryHandle(ptr, default, this);
-        }
-
-        public override void Unpin()
-        {
-            // SEE: Pin implementation
-            return;
-        }
-
-        protected override void Dispose(bool disposing)
-        {
-            // Only free once.
-            IntPtr ptr = Interlocked.Exchange(ref _ptr, IntPtr.Zero);
-            if (ptr != IntPtr.Zero)
-            {
-                _owner.Release(ptr, _offset, _length);
-            }
-        }
-
-        bool IOwnableAllocation.TryAcquire(out IntPtr ptr, out int offset, out int length)
-        {
-            // TODO: implement refcounted buffers?
-
-            if (object.ReferenceEquals(_owner, NativeMemoryAllocator.ExclusiveOwner))
-            {
-                ptr = Interlocked.Exchange(ref _ptr, IntPtr.Zero);
-                if (ptr != IntPtr.Zero)
-                {
-                    offset = _offset;
-                    length = _length;
-                    return true;
-                }
-            }
-
-            ptr = IntPtr.Zero;
-            offset = 0;
-            length = 0;
-            return false;
-        }
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private unsafe void* CalculatePointer(int index) =>
-            (_ptr + _offset + index).ToPointer();
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Memory/NullMemoryOwner.cs b/csharp/src/Apache.Arrow/Memory/NullMemoryOwner.cs
deleted file mode 100644
index 7415ffc..0000000
--- a/csharp/src/Apache.Arrow/Memory/NullMemoryOwner.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-
-namespace Apache.Arrow.Memory
-{
-    internal class NullMemoryOwner : IMemoryOwner<byte>
-    {
-        public Memory<byte> Memory => Memory<byte>.Empty;
-
-        public void Dispose()
-        {
-        }
-    }
-}
\ No newline at end of file
diff --git a/csharp/src/Apache.Arrow/Properties/AssemblyInfo.cs b/csharp/src/Apache.Arrow/Properties/AssemblyInfo.cs
deleted file mode 100644
index 6b2a7ae..0000000
--- a/csharp/src/Apache.Arrow/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Runtime.CompilerServices;
-
-[assembly: InternalsVisibleTo("Apache.Arrow.Flight, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e504183f6d470d6b67b6d19212be3e1f598f70c246a120194bc38130101d0c1853e4a0f2232cb12e37a7a90e707aabd38511dac4f25fcb0d691b2aa265900bf42de7f70468fc997551a40e1e0679b605aa2088a4a69e07c117e988f5b1738c570ee66997fba02485e7856a49eca5fd0706d09899b8312577cbb9034599fc92d4")]
-[assembly: InternalsVisibleTo("Apache.Arrow.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e504183f6d470d6b67b6d19212be3e1f598f70c246a120194bc38130101d0c1853e4a0f2232cb12e37a7a90e707aabd38511dac4f25fcb0d691b2aa265900bf42de7f70468fc997551a40e1e0679b605aa2088a4a69e07c117e988f5b1738c570ee66997fba02485e7856a49eca5fd0706d09899b8312577cbb9034599fc92d4")]
diff --git a/csharp/src/Apache.Arrow/Properties/Resources.Designer.cs b/csharp/src/Apache.Arrow/Properties/Resources.Designer.cs
deleted file mode 100644
index b92b34e..0000000
--- a/csharp/src/Apache.Arrow/Properties/Resources.Designer.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.42000
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace Apache.Arrow.Properties {
-    using System;
-    using System.Reflection;
-    
-    
-    /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
-    /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // class via a tool like ResGen or Visual Studio.
-    // To add or remove a member, edit your .ResX file then rerun ResGen
-    // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class Resources {
-        
-        private static global::System.Resources.ResourceManager resourceMan;
-        
-        private static global::System.Globalization.CultureInfo resourceCulture;
-        
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal Resources() {
-        }
-        
-        /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager {
-            get {
-                if (object.ReferenceEquals(resourceMan, null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Apache.Arrow.Properties.Resources", typeof(Resources).GetTypeInfo().Assembly);
-                    resourceMan = temp;
-                }
-                return resourceMan;
-            }
-        }
-        
-        /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
-            get {
-                return resourceCulture;
-            }
-            set {
-                resourceCulture = value;
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Array has invalid data type..
-        /// </summary>
-        internal static string ExceptionArrayDataInvalidType {
-            get {
-                return ResourceManager.GetString("ExceptionArrayDataInvalidType", resourceCulture);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Properties/Resources.resx b/csharp/src/Apache.Arrow/Properties/Resources.resx
deleted file mode 100644
index 271675a..0000000
--- a/csharp/src/Apache.Arrow/Properties/Resources.resx
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <data name="ExceptionArrayDataInvalidType" xml:space="preserve">
-    <value>Array has invalid data type.</value>
-  </data>
-</root>
\ No newline at end of file
diff --git a/csharp/src/Apache.Arrow/RecordBatch.Builder.cs b/csharp/src/Apache.Arrow/RecordBatch.Builder.cs
deleted file mode 100644
index e9a84a4..0000000
--- a/csharp/src/Apache.Arrow/RecordBatch.Builder.cs
+++ /dev/null
@@ -1,186 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-using System;
-using System.Buffers;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Apache.Arrow
-{
-    public partial class RecordBatch
-    {
-        public class ArrayBuilder
-        {
-            private readonly MemoryAllocator _allocator;
-
-            internal ArrayBuilder(MemoryAllocator allocator)
-            {
-                _allocator = allocator;
-            }
-
-            public BooleanArray Boolean(Action<BooleanArray.Builder> action) => Build<BooleanArray, BooleanArray.Builder>(new BooleanArray.Builder(), action);
-            public Int8Array Int8(Action<Int8Array.Builder> action) => Build<Int8Array, Int8Array.Builder>(new Int8Array.Builder(), action);
-            public Int16Array Int16(Action<Int16Array.Builder> action) => Build<Int16Array, Int16Array.Builder>(new Int16Array.Builder(), action);
-            public Int32Array Int32(Action<Int32Array.Builder> action) => Build<Int32Array, Int32Array.Builder>(new Int32Array.Builder(), action);
-            public Int64Array Int64(Action<Int64Array.Builder> action) => Build<Int64Array, Int64Array.Builder>(new Int64Array.Builder(), action);
-            public UInt8Array UInt8(Action<UInt8Array.Builder> action) => Build<UInt8Array, UInt8Array.Builder>(new UInt8Array.Builder(), action);
-            public UInt16Array UInt16(Action<UInt16Array.Builder> action) => Build<UInt16Array, UInt16Array.Builder>(new UInt16Array.Builder(), action);
-            public UInt32Array UInt32(Action<UInt32Array.Builder> action) => Build<UInt32Array, UInt32Array.Builder>(new UInt32Array.Builder(), action);
-            public UInt64Array UInt64(Action<UInt64Array.Builder> action) => Build<UInt64Array, UInt64Array.Builder>(new UInt64Array.Builder(), action);
-#if NET5_0_OR_GREATER
-            public HalfFloatArray HalfFloat(Action<HalfFloatArray.Builder> action) => Build<HalfFloatArray, HalfFloatArray.Builder>(new HalfFloatArray.Builder(), action);
-#endif
-            public FloatArray Float(Action<FloatArray.Builder> action) => Build<FloatArray, FloatArray.Builder>(new FloatArray.Builder(), action);
-            public DoubleArray Double(Action<DoubleArray.Builder> action) => Build<DoubleArray, DoubleArray.Builder>(new DoubleArray.Builder(), action);
-            public Decimal32Array Decimal32(Decimal32Type type, Action<Decimal32Array.Builder> action) =>
-                Build<Decimal32Array, Decimal32Array.Builder>(
-                    new Decimal32Array.Builder(type), action);
-            public Decimal64Array Decimal64(Decimal64Type type, Action<Decimal64Array.Builder> action) =>
-                Build<Decimal64Array, Decimal64Array.Builder>(
-                    new Decimal64Array.Builder(type), action);
-            public Decimal128Array Decimal128(Decimal128Type type, Action<Decimal128Array.Builder> action) =>
-                Build<Decimal128Array, Decimal128Array.Builder>(
-                    new Decimal128Array.Builder(type), action);
-            public Decimal256Array Decimal256(Decimal256Type type, Action<Decimal256Array.Builder> action) =>
-                Build<Decimal256Array, Decimal256Array.Builder>(
-                    new Decimal256Array.Builder(type), action);
-            public Date32Array Date32(Action<Date32Array.Builder> action) => Build<Date32Array, Date32Array.Builder>(new Date32Array.Builder(), action);
-            public Date64Array Date64(Action<Date64Array.Builder> action) => Build<Date64Array, Date64Array.Builder>(new Date64Array.Builder(), action);
-            public Time32Array Time32(Action<Time32Array.Builder> action) => Build<Time32Array, Time32Array.Builder>(new Time32Array.Builder(), action);
-            public Time32Array Time32(Time32Type type, Action<Time32Array.Builder> action) =>
-                Build<Time32Array, Time32Array.Builder>(
-                    new Time32Array.Builder(type), action);
-            public Time64Array Time64(Action<Time64Array.Builder> action) => Build<Time64Array, Time64Array.Builder>(new Time64Array.Builder(), action);
-            public Time64Array Time64(Time64Type type, Action<Time64Array.Builder> action) =>
-                Build<Time64Array, Time64Array.Builder>(
-                    new Time64Array.Builder(type), action);
-            public DurationArray Duration(DurationType type, Action<DurationArray.Builder> action) =>
-                Build<DurationArray, DurationArray.Builder>(new DurationArray.Builder(type), action);
-            public BinaryArray Binary(Action<BinaryArray.Builder> action) => Build<BinaryArray, BinaryArray.Builder>(new BinaryArray.Builder(), action);
-            public StringArray String(Action<StringArray.Builder> action) => Build<StringArray, StringArray.Builder>(new StringArray.Builder(), action);
-            public TimestampArray Timestamp(Action<TimestampArray.Builder> action) => Build<TimestampArray, TimestampArray.Builder>(new TimestampArray.Builder(), action);
-            public TimestampArray Timestamp(TimestampType type, Action<TimestampArray.Builder> action) =>
-                Build<TimestampArray, TimestampArray.Builder>(
-                    new TimestampArray.Builder(type), action);
-            public TimestampArray Timestamp(TimeUnit unit, TimeZoneInfo timezone, Action<TimestampArray.Builder> action) =>
-                Build<TimestampArray, TimestampArray.Builder>(
-                    new TimestampArray.Builder(new TimestampType(unit, timezone)), action);
-
-            private TArray Build<TArray, TArrayBuilder>(TArrayBuilder builder, Action<TArrayBuilder> action)
-                where TArray: IArrowArray
-                where TArrayBuilder: IArrowArrayBuilder<TArray>
-            {
-                if (action == null)
-                {
-                    return default;
-                }
-
-                action(builder);
-
-                return builder.Build(_allocator);
-            }
-        }
-
-        public class Builder
-        {
-            private readonly MemoryAllocator _allocator;
-            private readonly ArrayBuilder _arrayBuilder;
-            private readonly Schema.Builder _schemaBuilder;
-            private readonly List<IArrowArray> _arrays;
-
-            public Builder(MemoryAllocator allocator = default)
-            {
-                _allocator = allocator ?? MemoryAllocator.Default.Value;
-                _arrayBuilder = new ArrayBuilder(_allocator);
-                _schemaBuilder = new Schema.Builder();
-                _arrays = new List<IArrowArray>();
-            }
-
-            public RecordBatch Build()
-            {
-                Schema schema = _schemaBuilder.Build();
-                int length = _arrays.Max(x => x.Length);
-
-                // each array has its own memoryOwner, so the RecordBatch itself doesn't
-                // have a memoryOwner
-                IMemoryOwner<byte> memoryOwner = null;
-                var batch = new RecordBatch(schema, memoryOwner, _arrays, length);
-
-                return batch;
-            }
-
-            public Builder Clear()
-            {
-                _schemaBuilder.Clear();
-                _arrays.Clear();
-                return this;
-            }
-
-            public Builder Append(RecordBatch batch)
-            {
-                foreach (Field field in batch.Schema.FieldsList)
-                {
-                    _schemaBuilder.Field(field);
-                }
-
-                foreach (IArrowArray array in batch.Arrays)
-                {
-                    _arrays.Add(array);
-                }
-
-                return this;
-            }
-
-            public Builder Append<TArray>(string name, bool nullable, IArrowArrayBuilder<TArray> builder)
-                where TArray: IArrowArray
-            {
-                return builder == null
-                    ? this
-                    : Append(name, nullable, builder.Build(_allocator));
-            }
-
-            public Builder Append<TArray>(string name, bool nullable, TArray array)
-                where TArray: IArrowArray
-            {
-                if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullException(nameof(name));
-                if (array == null) return this;
-
-                _arrays.Add(array);
-
-                _schemaBuilder.Field(f => f
-                    .Name(name)
-                    .Nullable(nullable)
-                    .DataType(array.Data.DataType));
-
-                return this;
-            }
-
-            public Builder Append<TArray>(string name, bool nullable, Func<ArrayBuilder, TArray> action)
-                where TArray: IArrowArray
-            {
-                if (action == null) return this;
-
-                TArray array = action(_arrayBuilder);
-
-                Append(name, nullable, array);
-
-                return this;
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/RecordBatch.cs b/csharp/src/Apache.Arrow/RecordBatch.cs
deleted file mode 100644
index 4067ba9..0000000
--- a/csharp/src/Apache.Arrow/RecordBatch.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow
-{
-    public partial class RecordBatch : IArrowRecord
-    {
-        public Schema Schema { get; }
-        public int ColumnCount => _arrays.Count;
-        public IEnumerable<IArrowArray> Arrays => _arrays;
-        public int Length { get; }
-
-        internal IReadOnlyList<IArrowArray> ArrayList => _arrays;
-
-        private readonly IMemoryOwner<byte> _memoryOwner;
-        private readonly List<IArrowArray> _arrays;
-
-        public IArrowArray Column(int i)
-        {
-            return _arrays[i];
-        }
-
-        public IArrowArray Column(string columnName)
-        {
-            return Column(columnName, null);
-        }
-
-        public IArrowArray Column(string columnName, IEqualityComparer<string> comparer)
-        {
-            int fieldIndex = Schema.GetFieldIndex(columnName, comparer);
-            return _arrays[fieldIndex];
-        }
-
-        public void Dispose()
-        {
-            Dispose(disposing: true);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                _memoryOwner?.Dispose();
-
-                foreach (IArrowArray array in _arrays)
-                {
-                    array.Dispose();
-                }
-            }
-        }
-
-        public RecordBatch(Schema schema, IEnumerable<IArrowArray> data, int length)
-        {
-            if (length < 0)
-            {
-                throw new ArgumentOutOfRangeException(nameof(length));
-            }
-
-            _arrays = data?.ToList() ?? throw new ArgumentNullException(nameof(data));
-
-            Schema = schema ?? throw new ArgumentNullException(nameof(schema));
-            Length = length;
-        }
-
-        internal RecordBatch(Schema schema, IMemoryOwner<byte> memoryOwner, List<IArrowArray> arrays, int length)
-        {
-            Debug.Assert(schema != null);
-            Debug.Assert(arrays != null);
-            Debug.Assert(length >= 0);
-
-            _memoryOwner = memoryOwner;
-            _arrays = arrays;
-            Schema = schema;
-            Length = length;
-        }
-
-        public RecordBatch Clone(MemoryAllocator allocator = default)
-        {
-            IEnumerable<IArrowArray> arrays = _arrays.Select(array => ArrowArrayFactory.BuildArray(array.Data.Clone(allocator)));
-            return new RecordBatch(Schema, arrays, Length);
-        }
-
-        public RecordBatch Slice(int offset, int length)
-        {
-            if (offset > Length)
-            {
-                throw new ArgumentException($"Offset {offset} cannot be greater than Length {Length} for RecordBatch.Slice");
-            }
-
-            length = Math.Min(Length - offset, length);
-            return new RecordBatch(Schema, _arrays.Select(a => ArrowArrayFactory.Slice(a, offset, length)), length);
-        }
-
-        public void Accept(IArrowArrayVisitor visitor)
-        {
-            switch (visitor)
-            {
-                case IArrowArrayVisitor<RecordBatch> recordBatchVisitor:
-                    recordBatchVisitor.Visit(this);
-                    break;
-                case IArrowArrayVisitor<IArrowRecord> arrowStructVisitor:
-                    arrowStructVisitor.Visit(this);
-                    break;
-                default:
-                    visitor.Visit(this);
-                    break;
-            }
-        }
-
-        public override string ToString() => $"{nameof(RecordBatch)}: {ColumnCount} columns by {Length} rows";
-
-        IRecordType IArrowRecord.Schema => this.Schema;
-        int IArrowArray.NullCount => 0;
-        int IArrowArray.Offset => 0;
-        ArrayData IArrowArray.Data => throw new NotSupportedException("Unable to get data for RecordBatch");
-
-        bool IArrowArray.IsNull(int index) => false;
-        bool IArrowArray.IsValid(int index) => true;
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Scalars/BinaryView.cs b/csharp/src/Apache.Arrow/Scalars/BinaryView.cs
deleted file mode 100644
index 143e687..0000000
--- a/csharp/src/Apache.Arrow/Scalars/BinaryView.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace Apache.Arrow.Scalars
-{
-    [StructLayout(LayoutKind.Explicit)]
-    public unsafe struct BinaryView : IEquatable<BinaryView>
-    {
-        public const int PrefixLength = 4;
-        public const int MaxInlineLength = 12;
-
-        [FieldOffset(0)]
-        public readonly int Length;
-
-        [FieldOffset(4)]
-        internal readonly int _prefix;
-
-        [FieldOffset(8)]
-        internal readonly int _bufferIndex;
-
-        [FieldOffset(12)]
-        internal readonly int _bufferOffset;
-
-        [FieldOffset(4)]
-        internal fixed byte _inline[MaxInlineLength];
-
-        public unsafe BinaryView(ReadOnlySpan<byte> inline) : this()
-        {
-            if (inline.Length > MaxInlineLength)
-            {
-                throw new ArgumentException("invalid inline data length", nameof(inline));
-            }
-
-            Length = inline.Length;
-            fixed (byte* dest = _inline)
-            fixed (byte* src = inline)
-            {
-                Buffer.MemoryCopy(src, dest, MaxInlineLength, inline.Length);
-            }
-        }
-
-        public BinaryView(int length, ReadOnlySpan<byte> prefix, int bufferIndex, int bufferOffset)
-        {
-            if (length < MaxInlineLength)
-            {
-                throw new ArgumentException("invalid length", nameof(length));
-            }
-            if (prefix.Length != PrefixLength)
-            {
-                throw new ArgumentException("invalid prefix length", nameof(prefix));
-            }
-
-            Length = length;
-            _bufferIndex = bufferIndex;
-            _bufferOffset = bufferOffset;
-            _prefix = prefix.CastTo<int>()[0];
-        }
-
-        private BinaryView(int length, int prefix, int bufferIndex, int offset)
-        {
-            Length = length;
-            _prefix = prefix;
-            _bufferIndex = bufferIndex;
-            _bufferOffset = offset;
-        }
-
-        public bool IsInline => Length <= MaxInlineLength;
-
-#if NET5_0_OR_GREATER
-        public ReadOnlySpan<byte> Bytes => MemoryMarshal.CreateReadOnlySpan<byte>(ref Unsafe.AsRef(in _inline[0]), IsInline ? Length : PrefixLength);
-#else
-        public unsafe ReadOnlySpan<byte> Bytes => new ReadOnlySpan<byte>(Unsafe.AsPointer(ref _inline[0]), IsInline ? Length : PrefixLength);
-#endif
-
-        public int BufferIndex => IsInline ? -1 : _bufferIndex;
-
-        public int BufferOffset => IsInline ? -1 : _bufferOffset;
-
-        public override int GetHashCode() => Length ^ _prefix ^ _bufferIndex ^ _bufferOffset;
-
-        public override bool Equals(object obj)
-        {
-            BinaryView? other = obj as BinaryView?;
-            return other != null && Equals(other.Value);
-        }
-
-        public bool Equals(BinaryView other) =>
-            Length == other.Length && _prefix == other._prefix && _bufferIndex == other._bufferIndex && _bufferOffset == other._bufferOffset;
-
-        internal BinaryView AdjustBufferIndex(int bufferOffset)
-        {
-            return new BinaryView(Length, _prefix, _bufferIndex + bufferOffset, _bufferOffset);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Scalars/DayTimeInterval.cs b/csharp/src/Apache.Arrow/Scalars/DayTimeInterval.cs
deleted file mode 100644
index 8d2814e..0000000
--- a/csharp/src/Apache.Arrow/Scalars/DayTimeInterval.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace Apache.Arrow.Scalars
-{
-    [StructLayout(LayoutKind.Explicit)]
-    public struct DayTimeInterval : IEquatable<DayTimeInterval>
-    {
-        [FieldOffset(0)]
-        public readonly int Days;
-
-        [FieldOffset(4)]
-        public readonly int Milliseconds;
-
-        public DayTimeInterval(int days, int milliseconds)
-        {
-            Days = days;
-            Milliseconds = milliseconds;
-        }
-
-        public override bool Equals(object obj) => obj switch
-        {
-            DayTimeInterval interval => Equals(interval),
-            _ => false,
-        };
-
-        public override int GetHashCode() => unchecked((17 + Days) * 23 + Milliseconds);
-
-        public bool Equals(DayTimeInterval interval)
-        {
-            return this.Days == interval.Days && this.Milliseconds == interval.Milliseconds;
-        }
-
-        public static DateTime operator +(DateTime dateTime, DayTimeInterval interval)
-            => dateTime.AddDays(interval.Days).AddMilliseconds(interval.Milliseconds);
-        public static DateTime operator +(DayTimeInterval interval, DateTime dateTime)
-            => dateTime.AddDays(interval.Days).AddMilliseconds(interval.Milliseconds);
-        public static DateTime operator -(DateTime dateTime, DayTimeInterval interval)
-            => dateTime.AddDays(-interval.Days).AddMilliseconds(-interval.Milliseconds);
-
-        public static DateTimeOffset operator +(DateTimeOffset dateTime, DayTimeInterval interval)
-            => dateTime.AddDays(interval.Days).AddMilliseconds(interval.Milliseconds);
-        public static DateTimeOffset operator +(DayTimeInterval interval, DateTimeOffset dateTime)
-            => dateTime.AddDays(interval.Days).AddMilliseconds(interval.Milliseconds);
-        public static DateTimeOffset operator -(DateTimeOffset dateTime, DayTimeInterval interval)
-            => dateTime.AddDays(-interval.Days).AddMilliseconds(-interval.Milliseconds);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Scalars/MonthDayNanosecondInterval.cs b/csharp/src/Apache.Arrow/Scalars/MonthDayNanosecondInterval.cs
deleted file mode 100644
index 2af0e6f..0000000
--- a/csharp/src/Apache.Arrow/Scalars/MonthDayNanosecondInterval.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace Apache.Arrow.Scalars
-{
-    [StructLayout(LayoutKind.Explicit)]
-    public struct MonthDayNanosecondInterval : IEquatable<MonthDayNanosecondInterval>
-    {
-        [FieldOffset(0)]
-        public readonly int Months;
-
-        [FieldOffset(4)]
-        public readonly int Days;
-
-        [FieldOffset(8)]
-        public readonly long Nanoseconds;
-
-        public MonthDayNanosecondInterval(int months, int days, long nanoseconds)
-        {
-            Months = months;
-            Days = days;
-            Nanoseconds = nanoseconds;
-        }
-
-        public override bool Equals(object obj) => obj switch
-        {
-            MonthDayNanosecondInterval interval => Equals(interval),
-            _ => false,
-        };
-
-        public override int GetHashCode() => unchecked(((17 + Months) * 23 + Days) * 23 + (int)Nanoseconds);
-
-        public bool Equals(MonthDayNanosecondInterval interval)
-        {
-            return this.Months == interval.Months && this.Days == interval.Days && this.Nanoseconds == interval.Nanoseconds;
-        }
-
-        public static DateTime operator +(DateTime dateTime, MonthDayNanosecondInterval interval)
-            => dateTime.AddMonths(interval.Months).AddDays(interval.Days).AddTicks(interval.Nanoseconds / 100);
-        public static DateTime operator +(MonthDayNanosecondInterval interval, DateTime dateTime)
-            => dateTime.AddMonths(interval.Months).AddDays(interval.Days).AddTicks(interval.Nanoseconds / 100);
-        public static DateTime operator -(DateTime dateTime, MonthDayNanosecondInterval interval)
-            => dateTime.AddMonths(-interval.Months).AddDays(-interval.Days).AddTicks(-interval.Nanoseconds / 100);
-
-        public static DateTimeOffset operator +(DateTimeOffset dateTime, MonthDayNanosecondInterval interval)
-            => dateTime.AddMonths(interval.Months).AddDays(interval.Days).AddTicks(interval.Nanoseconds / 100);
-        public static DateTimeOffset operator +(MonthDayNanosecondInterval interval, DateTimeOffset dateTime)
-            => dateTime.AddMonths(interval.Months).AddDays(interval.Days).AddTicks(interval.Nanoseconds / 100);
-        public static DateTimeOffset operator -(DateTimeOffset dateTime, MonthDayNanosecondInterval interval)
-            => dateTime.AddMonths(-interval.Months).AddDays(-interval.Days).AddTicks(-interval.Nanoseconds / 100);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Scalars/YearMonthInterval.cs b/csharp/src/Apache.Arrow/Scalars/YearMonthInterval.cs
deleted file mode 100644
index 365cc35..0000000
--- a/csharp/src/Apache.Arrow/Scalars/YearMonthInterval.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace Apache.Arrow.Scalars
-{
-    [StructLayout(LayoutKind.Explicit)]
-    public struct YearMonthInterval : IEquatable<YearMonthInterval>
-    {
-        private const int MonthsPerYear = 12;
-
-        [FieldOffset(0)]
-        public readonly int Months;
-
-        public YearMonthInterval(int totalMonths)
-        {
-            Months = totalMonths;
-        }
-
-        public YearMonthInterval(int years, int months)
-        {
-            Months = years * MonthsPerYear + months;
-        }
-
-        public override bool Equals(object obj) => obj switch
-        {
-            DayTimeInterval interval => Equals(interval),
-            _ => false,
-        };
-
-        public override int GetHashCode() => Months;
-
-        public bool Equals(YearMonthInterval interval)
-        {
-            return this.Months == interval.Months;
-        }
-
-        public static DateTime operator +(DateTime dateTime, YearMonthInterval interval) => dateTime.AddMonths(interval.Months);
-        public static DateTime operator +(YearMonthInterval interval, DateTime dateTime) => dateTime.AddMonths(interval.Months);
-        public static DateTime operator -(DateTime dateTime, YearMonthInterval interval) => dateTime.AddMonths(-interval.Months);
-
-        public static DateTimeOffset operator +(DateTimeOffset dateTime, YearMonthInterval interval) => dateTime.AddMonths(interval.Months);
-        public static DateTimeOffset operator +(YearMonthInterval interval, DateTimeOffset dateTime) => dateTime.AddMonths(interval.Months);
-        public static DateTimeOffset operator -(DateTimeOffset dateTime, YearMonthInterval interval) => dateTime.AddMonths(-interval.Months);
-
-#if NET6_0_OR_GREATER
-        public static DateOnly operator +(DateOnly date, YearMonthInterval interval) => date.AddMonths(interval.Months);
-        public static DateOnly operator +(YearMonthInterval interval, DateOnly date) => date.AddMonths(interval.Months);
-        public static DateOnly operator -(DateOnly date, YearMonthInterval interval) => date.AddMonths(-interval.Months);
-#endif
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Schema.Builder.cs b/csharp/src/Apache.Arrow/Schema.Builder.cs
deleted file mode 100644
index 89e9e3c..0000000
--- a/csharp/src/Apache.Arrow/Schema.Builder.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Arrow
-{
-    public partial class Schema
-    {
-        public class Builder
-        {
-            private readonly List<Field> _fields;
-            private Dictionary<string, string> _metadata;
-
-            public Builder()
-            {
-                _fields = new List<Field>();
-            }
-
-            public Builder Clear()
-            {
-                _fields.Clear();
-                _metadata?.Clear();
-                return this;
-            }
-
-            public Builder Field(Field field)
-            {
-                if (field == null) return this;
-
-                _fields.Add(field);
-                return this;
-            }
-
-            public Builder Field(Action<Field.Builder> fieldBuilderAction)
-            {
-                if (fieldBuilderAction == null) return this;
-
-                var fieldBuilder = new Field.Builder();
-                fieldBuilderAction(fieldBuilder);
-                Field field = fieldBuilder.Build();
-
-                _fields.Add(field);
-                return this;
-            }
-
-            public Builder Metadata(string key, string value)
-            {
-                if (string.IsNullOrWhiteSpace(key))
-                {
-                    throw new ArgumentNullException(nameof(key));
-                }
-
-                _metadata ??= new Dictionary<string, string>();
-
-                _metadata[key] = value;
-                return this;
-            }
-
-            public Builder Metadata(IEnumerable<KeyValuePair<string, string>> dictionary)
-            {
-                if (dictionary == null)
-                {
-                    throw new ArgumentNullException(nameof(dictionary));
-                }
-                foreach (KeyValuePair<string, string> entry in dictionary)
-                {
-                    Metadata(entry.Key, entry.Value);
-                }
-                return this;
-            }
-
-            public Schema Build()
-            {
-                return new Schema(_fields, _metadata);
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Schema.cs b/csharp/src/Apache.Arrow/Schema.cs
deleted file mode 100644
index 32615e5..0000000
--- a/csharp/src/Apache.Arrow/Schema.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-
-namespace Apache.Arrow
-{
-    public partial class Schema : IRecordType
-    {
-        [Obsolete("Use `FieldsList` or `FieldsLookup` instead")]
-        public IReadOnlyDictionary<string, Field> Fields => _fieldsDictionary;
-        private readonly Dictionary<string, Field> _fieldsDictionary;
-
-        public IReadOnlyList<Field> FieldsList => _fieldsList;
-        private readonly List<Field> _fieldsList;
-
-        public ILookup<string, Field> FieldsLookup { get; }
-
-        public IReadOnlyDictionary<string, string> Metadata { get; }
-
-        public bool HasMetadata => Metadata != null && Metadata.Count > 0;
-
-        public Field this[int index] => GetFieldByIndex(index);
-
-        public Field this[string name] => GetFieldByName(name);
-
-        public Schema(
-            IEnumerable<Field> fields,
-            IEnumerable<KeyValuePair<string, string>> metadata)
-        {
-            if (fields is null)
-            {
-                throw new ArgumentNullException(nameof(fields));
-            }
-
-            _fieldsList = fields.ToList();
-            FieldsLookup = _fieldsList.ToLookup(f => f.Name);
-            _fieldsDictionary = FieldsLookup.ToDictionary(g => g.Key, g => g.First());
-
-            Metadata = metadata?.ToDictionary(kv => kv.Key, kv => kv.Value);
-        }
-
-        internal Schema(List<Field> fieldsList, IReadOnlyDictionary<string, string> metadata, bool copyCollections)
-        {
-            Debug.Assert(fieldsList != null);
-            Debug.Assert(copyCollections == false, "This internal constructor is to not copy the collections.");
-
-            _fieldsList = fieldsList;
-            FieldsLookup = _fieldsList.ToLookup(f => f.Name);
-            _fieldsDictionary = FieldsLookup.ToDictionary(g => g.Key, g => g.First());
-
-            Metadata = metadata;
-        }
-
-        public Field GetFieldByIndex(int i) => _fieldsList[i];
-
-        public Field GetFieldByName(string name) => FieldsLookup[name].FirstOrDefault();
-
-        public int GetFieldIndex(string name, StringComparer comparer)
-        {
-            IEqualityComparer<string> equalityComparer = (IEqualityComparer<string>)comparer;
-            return GetFieldIndex(name, equalityComparer);
-        }
-
-        public int GetFieldIndex(string name, IEqualityComparer<string> comparer = default)
-        {
-            comparer ??= StringComparer.CurrentCulture;
-
-            for (int i = 0; i < _fieldsList.Count; i++)
-            {
-                if (comparer.Equals(_fieldsList[i].Name, name))
-                    return i;
-            }
-
-            return -1;
-        }
-
-        public Schema RemoveField(int fieldIndex)
-        {
-            if (fieldIndex < 0 || fieldIndex >= _fieldsList.Count)
-            {
-                throw new ArgumentException("Invalid fieldIndex", nameof(fieldIndex));
-            }
-
-            IList<Field> fields = Utility.DeleteListElement(_fieldsList, fieldIndex);
-
-            return new Schema(fields, Metadata);
-        }
-
-        public Schema InsertField(int fieldIndex, Field newField)
-        {
-            newField = newField ?? throw new ArgumentNullException(nameof(newField));
-            if (fieldIndex < 0 || fieldIndex > _fieldsList.Count)
-            {
-                throw new ArgumentException(nameof(fieldIndex), $"Invalid fieldIndex {fieldIndex} passed in to Schema.AddField");
-            }
-
-            IList<Field> fields = Utility.AddListElement(_fieldsList, fieldIndex, newField);
-
-            return new Schema(fields, Metadata);
-        }
-
-        public Schema SetField(int fieldIndex, Field newField)
-        {
-            if (fieldIndex < 0 || fieldIndex >= _fieldsList.Count)
-            {
-                throw new ArgumentException($"Invalid fieldIndex {fieldIndex} passed in to Schema.SetColumn");
-            }
-
-            IList<Field> fields = Utility.SetListElement(_fieldsList, fieldIndex, newField);
-
-            return new Schema(fields, Metadata);
-        }
-
-        public void Accept(IArrowTypeVisitor visitor)
-        {
-            if (visitor is IArrowTypeVisitor<Schema> schemaVisitor)
-            {
-                schemaVisitor.Visit(this);
-            }
-            else if (visitor is IArrowTypeVisitor<IRecordType> interfaceVisitor)
-            {
-                interfaceVisitor.Visit(this);
-            }
-            else
-            {
-                visitor.Visit(this);
-            }
-        }
-
-        public override string ToString() => $"{nameof(Schema)}: Num fields={_fieldsList.Count}, Num metadata={Metadata?.Count ?? 0}";
-
-        int IRecordType.FieldCount => _fieldsList.Count;
-        string IArrowType.Name => "RecordBatch";
-        ArrowTypeId IArrowType.TypeId => ArrowTypeId.RecordBatch;
-        bool IArrowType.IsFixedWidth => false;
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Table.cs b/csharp/src/Apache.Arrow/Table.cs
deleted file mode 100644
index dd21cf1..0000000
--- a/csharp/src/Apache.Arrow/Table.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Arrow
-{
-    /// <summary>
-    /// A logical Table class to represent a dataset as a sequence of Columns
-    /// </summary>
-    public class Table
-    {
-        public Schema Schema { get; }
-        public long RowCount { get; }
-        public int ColumnCount { get; private set; }
-        public Column Column(int columnIndex) => _columns[columnIndex];
-
-        private readonly IList<Column> _columns;
-        public static Table TableFromRecordBatches(Schema schema, IList<RecordBatch> recordBatches)
-        {
-            int nBatches = recordBatches.Count;
-            int nColumns = schema.FieldsList.Count;
-
-            List<Column> columns = new List<Column>(nColumns);
-            for (int icol = 0; icol < nColumns; icol++)
-            {
-                List<IArrowArray> columnArrays = new List<IArrowArray>(nBatches);
-                for (int jj = 0; jj < nBatches; jj++)
-                {
-                    columnArrays.Add(recordBatches[jj].Column(icol));
-                }
-                columns.Add(new Column(schema.GetFieldByIndex(icol), columnArrays));
-            }
-
-            return new Table(schema, columns);
-        }
-
-        public Table(Schema schema, IList<Column> columns)
-        {
-            Schema = schema;
-            _columns = columns;
-            if (columns.Count > 0)
-            {
-                RowCount = columns[0].Length;
-                ColumnCount = columns.Count;
-            }
-        }
-
-        public Table()
-        {
-            Schema = new Schema.Builder().Build();
-            _columns = new List<Column>();
-        }
-
-        public Table RemoveColumn(int columnIndex)
-        {
-            Schema newSchema = Schema.RemoveField(columnIndex);
-            IList<Column> newColumns = Utility.DeleteListElement(_columns, columnIndex);
-            return new Table(newSchema, newColumns);
-        }
-
-        public Table InsertColumn(int columnIndex, Column column)
-        {
-            column = column ?? throw new ArgumentNullException(nameof(column));
-            if (columnIndex < 0 || columnIndex > _columns.Count)
-            {
-                throw new ArgumentException($"Invalid columnIndex {columnIndex} passed into Table.AddColumn");
-            }
-            if (column.Length != RowCount)
-            {
-                throw new ArgumentException($"Column's length {column.Length} must match Table's length {RowCount}");
-            }
-
-            Schema newSchema = Schema.InsertField(columnIndex, column.Field);
-            IList<Column> newColumns = Utility.AddListElement(_columns, columnIndex, column);
-            return new Table(newSchema, newColumns);
-        }
-
-        public Table SetColumn(int columnIndex, Column column)
-        {
-            column = column ?? throw new ArgumentNullException(nameof(column));
-            if (columnIndex < 0 || columnIndex >= ColumnCount)
-            {
-                throw new ArgumentException($"Invalid columnIndex {columnIndex} passed in to Table.SetColumn");
-            }
-
-            if (column.Length != RowCount)
-            {
-                throw new ArgumentException($"Column's length {column.Length} must match table's length {RowCount}");
-            }
-
-            Schema newSchema = Schema.SetField(columnIndex, column.Field);
-            IList<Column> newColumns = Utility.SetListElement(_columns, columnIndex, column);
-            return new Table(newSchema, newColumns);
-        }
-
-        public override string ToString() => $"{nameof(Table)}: {ColumnCount} columns by {RowCount} rows";
-
-        // TODO: Flatten for Tables with Lists/Structs?
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/ArrowType.cs b/csharp/src/Apache.Arrow/Types/ArrowType.cs
deleted file mode 100644
index c0eca23..0000000
--- a/csharp/src/Apache.Arrow/Types/ArrowType.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public abstract class ArrowType: IArrowType
-    {
-        public abstract ArrowTypeId TypeId { get; }
-
-        public abstract string Name { get; }
-
-        public virtual bool IsFixedWidth => false;
-
-        public abstract void Accept(IArrowTypeVisitor visitor);
-
-        internal static void Accept<T>(T type, IArrowTypeVisitor visitor)
-            where T: class, IArrowType
-        {
-            switch (visitor)
-            {
-                case IArrowTypeVisitor<T> typedVisitor:
-                    typedVisitor.Visit(type);
-                    break;
-                default:
-                    visitor.Visit(type);
-                    break;
-            }
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/BinaryType.cs b/csharp/src/Apache.Arrow/Types/BinaryType.cs
deleted file mode 100644
index 6734d93..0000000
--- a/csharp/src/Apache.Arrow/Types/BinaryType.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public class BinaryType: ArrowType
-    {
-        public static readonly BinaryType Default = new BinaryType();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Binary;
-        public override string Name => "binary";
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/BinaryViewType.cs b/csharp/src/Apache.Arrow/Types/BinaryViewType.cs
deleted file mode 100644
index f5cfc03..0000000
--- a/csharp/src/Apache.Arrow/Types/BinaryViewType.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public class BinaryViewType: ArrowType
-    {
-        public static readonly BinaryViewType Default = new BinaryViewType();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.BinaryView;
-        public override string Name => "binaryview";
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/BooleanType.cs b/csharp/src/Apache.Arrow/Types/BooleanType.cs
deleted file mode 100644
index 3b57414..0000000
--- a/csharp/src/Apache.Arrow/Types/BooleanType.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class BooleanType: NumberType
-    {
-        public static readonly BooleanType Default = new BooleanType();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Boolean;
-        public override string Name => "bool";
-        public override int BitWidth => 1;
-        public override bool IsSigned => false;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Date32Type.cs b/csharp/src/Apache.Arrow/Types/Date32Type.cs
deleted file mode 100644
index 9673bf6..0000000
--- a/csharp/src/Apache.Arrow/Types/Date32Type.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Date32Type: DateType
-    {
-        public static readonly Date32Type Default = new Date32Type();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Date32;
-        public override string Name => "date32";
-        public override int BitWidth => 32;
-        public override DateUnit Unit => DateUnit.Day;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Date64Type.cs b/csharp/src/Apache.Arrow/Types/Date64Type.cs
deleted file mode 100644
index 2a9e1aa..0000000
--- a/csharp/src/Apache.Arrow/Types/Date64Type.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Date64Type : DateType
-    {
-        public static readonly Date64Type Default = new Date64Type();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Date64;
-        public override string Name => "date64";
-        public override int BitWidth => 64;
-        public override DateUnit Unit => DateUnit.Milliseconds;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/DateType.cs b/csharp/src/Apache.Arrow/Types/DateType.cs
deleted file mode 100644
index 8f15b08..0000000
--- a/csharp/src/Apache.Arrow/Types/DateType.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public enum DateUnit
-    {
-        Day = 0,
-        Milliseconds = 1
-    }
-
-    public abstract class DateType: FixedWidthType
-    {
-        public abstract DateUnit Unit { get; }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Decimal128Type.cs b/csharp/src/Apache.Arrow/Types/Decimal128Type.cs
deleted file mode 100644
index e00b9da..0000000
--- a/csharp/src/Apache.Arrow/Types/Decimal128Type.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Decimal128Type : FixedSizeBinaryType
-    {
-        public override ArrowTypeId TypeId => ArrowTypeId.Decimal128;
-        public override string Name => "decimal128";
-
-        public int Precision { get; }
-        public int Scale { get; }
-
-        public Decimal128Type(int precision, int scale)
-            : base(16)
-        {
-            Precision = precision;
-            Scale = scale;
-        }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Decimal256Type.cs b/csharp/src/Apache.Arrow/Types/Decimal256Type.cs
deleted file mode 100644
index b184deb..0000000
--- a/csharp/src/Apache.Arrow/Types/Decimal256Type.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Decimal256Type: FixedSizeBinaryType
-    {
-        public override ArrowTypeId TypeId => ArrowTypeId.Decimal256;
-        public override string Name => "decimal256";
-
-        public int Precision { get; }
-        public int Scale { get; }
-
-        public Decimal256Type(int precision, int scale)
-            : base(32)
-        {
-            Precision = precision;
-            Scale = scale;
-        }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Decimal32Type.cs b/csharp/src/Apache.Arrow/Types/Decimal32Type.cs
deleted file mode 100644
index c494b3b..0000000
--- a/csharp/src/Apache.Arrow/Types/Decimal32Type.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Decimal32Type : FixedSizeBinaryType
-    {
-        public override ArrowTypeId TypeId => ArrowTypeId.Decimal32;
-        public override string Name => "decimal32";
-
-        public int Precision { get; }
-        public int Scale { get; }
-
-        public Decimal32Type(int precision, int scale)
-            : base(4)
-        {
-            Precision = precision;
-            Scale = scale;
-        }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Decimal64Type.cs b/csharp/src/Apache.Arrow/Types/Decimal64Type.cs
deleted file mode 100644
index 30d544b..0000000
--- a/csharp/src/Apache.Arrow/Types/Decimal64Type.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Decimal64Type : FixedSizeBinaryType
-    {
-        public override ArrowTypeId TypeId => ArrowTypeId.Decimal64;
-        public override string Name => "decimal64";
-
-        public int Precision { get; }
-        public int Scale { get; }
-
-        public Decimal64Type(int precision, int scale)
-            : base(8)
-        {
-            Precision = precision;
-            Scale = scale;
-        }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/DictionaryType.cs b/csharp/src/Apache.Arrow/Types/DictionaryType.cs
deleted file mode 100644
index 6316578..0000000
--- a/csharp/src/Apache.Arrow/Types/DictionaryType.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-using System;
-
-namespace Apache.Arrow.Types
-{
-    public sealed class DictionaryType : FixedWidthType
-    {
-        [Obsolete]
-        public static readonly DictionaryType Default = new DictionaryType(Int64Type.Default, Int64Type.Default, false);
-
-        public DictionaryType(IArrowType indexType, IArrowType valueType, bool ordered)
-        {
-            if (!(indexType is IntegerType))
-            {
-                throw new ArgumentException($"{nameof(indexType)} must be integer");
-            }
-
-            IndexType = indexType;
-            ValueType = valueType;
-            Ordered = ordered;
-        }
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Dictionary;
-        public override string Name => "dictionary";
-        public override int BitWidth => ((IntegerType)IndexType).BitWidth;
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-
-        public IArrowType IndexType { get; private set; }
-        public IArrowType ValueType { get; private set; }
-        public bool Ordered { get; private set; }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/DoubleType.cs b/csharp/src/Apache.Arrow/Types/DoubleType.cs
deleted file mode 100644
index aa6ade6..0000000
--- a/csharp/src/Apache.Arrow/Types/DoubleType.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class DoubleType: FloatingPointType
-    {
-        public static readonly DoubleType Default = new DoubleType();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Double;
-        public override string Name => "double";
-        public override int BitWidth => 64;
-        public override bool IsSigned => true;
-        public override PrecisionKind Precision => PrecisionKind.Double;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/DurationType.cs b/csharp/src/Apache.Arrow/Types/DurationType.cs
deleted file mode 100644
index 7e937a6..0000000
--- a/csharp/src/Apache.Arrow/Types/DurationType.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class DurationType : TimeBasedType
-    {
-        public static readonly DurationType Second = new DurationType(TimeUnit.Second);
-        public static readonly DurationType Millisecond = new DurationType(TimeUnit.Millisecond);
-        public static readonly DurationType Microsecond = new DurationType(TimeUnit.Microsecond);
-        public static readonly DurationType Nanosecond = new DurationType(TimeUnit.Nanosecond);
-        private static readonly DurationType[] _types = new DurationType[] { Second, Millisecond, Microsecond, Nanosecond };
-
-        private DurationType(TimeUnit unit)
-            : base(unit)
-        {
-        }
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Duration;
-        public override string Name => "duration";
-        public override int BitWidth => 64;
-
-        public static DurationType FromTimeUnit(TimeUnit unit)
-        {
-            return _types[(int)unit];
-        }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/FixedSizeBinaryType.cs b/csharp/src/Apache.Arrow/Types/FixedSizeBinaryType.cs
deleted file mode 100644
index ccbfc8c..0000000
--- a/csharp/src/Apache.Arrow/Types/FixedSizeBinaryType.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Types
-{
-    public class FixedSizeBinaryType : FixedWidthType
-    {
-        public override ArrowTypeId TypeId => ArrowTypeId.FixedSizedBinary;
-        public override string Name => "fixed_size_binary";
-        public int ByteWidth { get; }
-        public override int BitWidth => ByteWidth * 8;
-
-        public FixedSizeBinaryType(int byteWidth)
-        {
-            if (byteWidth <= 0)
-                throw new ArgumentOutOfRangeException(nameof(byteWidth));
-
-            ByteWidth = byteWidth;
-        }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/FixedSizeListType.cs b/csharp/src/Apache.Arrow/Types/FixedSizeListType.cs
deleted file mode 100644
index 5a4c70b..0000000
--- a/csharp/src/Apache.Arrow/Types/FixedSizeListType.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Types
-{
-    public sealed class FixedSizeListType : NestedType
-    {
-        public override ArrowTypeId TypeId => ArrowTypeId.FixedSizeList;
-        public override string Name => "fixed_size_list";
-        public int ListSize { get; }
-
-        public Field ValueField => Fields[0];
-
-        public IArrowType ValueDataType => Fields[0].DataType;
-
-        public FixedSizeListType(Field valueField, int listSize)
-           : base(valueField)
-        {
-            if (listSize <= 0)
-                throw new ArgumentOutOfRangeException(nameof(listSize));
-
-            ListSize = listSize;
-        }
-
-        public FixedSizeListType(IArrowType valueDataType, int listSize)
-            : this(new Field("item", valueDataType, true), listSize) { }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/FixedWidthType.cs b/csharp/src/Apache.Arrow/Types/FixedWidthType.cs
deleted file mode 100644
index d1c9e8c..0000000
--- a/csharp/src/Apache.Arrow/Types/FixedWidthType.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public abstract class FixedWidthType: ArrowType
-    {
-        public override bool IsFixedWidth => true;
-
-        public abstract int BitWidth { get; }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/FloatType.cs b/csharp/src/Apache.Arrow/Types/FloatType.cs
deleted file mode 100644
index a3f7b39..0000000
--- a/csharp/src/Apache.Arrow/Types/FloatType.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class FloatType: FloatingPointType
-    {
-        public static readonly FloatType Default = new FloatType();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Float;
-        public override string Name => "float";
-        public override int BitWidth => 32;
-        public override bool IsSigned => true;
-        public override PrecisionKind Precision => PrecisionKind.Single;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/FloatingPointType.cs b/csharp/src/Apache.Arrow/Types/FloatingPointType.cs
deleted file mode 100644
index 9fbe43a..0000000
--- a/csharp/src/Apache.Arrow/Types/FloatingPointType.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public abstract class FloatingPointType: NumberType
-    {
-        public enum PrecisionKind
-        {
-            Half,
-            Single,
-            Double
-        }
-
-        public abstract PrecisionKind Precision { get; }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/HalfFloatType.cs b/csharp/src/Apache.Arrow/Types/HalfFloatType.cs
deleted file mode 100644
index 5bfa232..0000000
--- a/csharp/src/Apache.Arrow/Types/HalfFloatType.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class HalfFloatType: FloatingPointType
-    {
-        public static readonly HalfFloatType Default = new HalfFloatType();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.HalfFloat;
-        public override string Name => "halffloat";
-        public override int BitWidth => 16;
-        public override bool IsSigned => true;
-        public override PrecisionKind Precision => PrecisionKind.Half;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/IArrowType.cs b/csharp/src/Apache.Arrow/Types/IArrowType.cs
deleted file mode 100644
index 6020fd4..0000000
--- a/csharp/src/Apache.Arrow/Types/IArrowType.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public enum ArrowTypeId
-    {
-        Null,
-        Boolean,
-        UInt8,
-        Int8,
-        UInt16,
-        Int16,
-        UInt32,
-        Int32,
-        UInt64,
-        Int64,
-        HalfFloat,
-        Float,
-        Double,
-        String,
-        Binary,
-        FixedSizedBinary,
-        Date32,
-        Date64,
-        Timestamp,
-        Time32,
-        Time64,
-        Interval,
-        Decimal128,
-        Decimal256,
-        List,
-        Struct,
-        Union,
-        Dictionary,
-        Map,
-        FixedSizeList,
-        Duration,
-        RecordBatch,
-        BinaryView,
-        StringView,
-        ListView,
-        LargeList,
-        LargeBinary,
-        LargeString,
-        Decimal32,
-        Decimal64,
-    }
-
-    public interface IArrowType
-    {
-        ArrowTypeId TypeId { get; }
-
-        string Name { get; }
- 
-        void Accept(IArrowTypeVisitor visitor);
-
-        bool IsFixedWidth { get; }
-    
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/IArrowTypeVisitor.cs b/csharp/src/Apache.Arrow/Types/IArrowTypeVisitor.cs
deleted file mode 100644
index ce5b114..0000000
--- a/csharp/src/Apache.Arrow/Types/IArrowTypeVisitor.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public interface IArrowTypeVisitor
-    {
-        void Visit(IArrowType type);
-    }
-
-    public interface IArrowTypeVisitor<in T>: IArrowTypeVisitor
-        where T: IArrowType
-    {
-        void Visit(T type);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/IRecordType.cs b/csharp/src/Apache.Arrow/Types/IRecordType.cs
deleted file mode 100644
index 510edad..0000000
--- a/csharp/src/Apache.Arrow/Types/IRecordType.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Collections.Generic;
-
-namespace Apache.Arrow.Types
-{
-    public interface IRecordType : IArrowType
-    {
-        int FieldCount { get; }
-
-        Field GetFieldByIndex(int index);
-        Field GetFieldByName(string name);
-        int GetFieldIndex(string name, IEqualityComparer<string> comparer);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Int16Type.cs b/csharp/src/Apache.Arrow/Types/Int16Type.cs
deleted file mode 100644
index 564ae06..0000000
--- a/csharp/src/Apache.Arrow/Types/Int16Type.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Int16Type : IntegerType
-    {
-        public static readonly Int16Type Default = new Int16Type();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Int16;
-        public override string Name => "int16";
-        public override int BitWidth => 16;
-        public override bool IsSigned => true;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Int32Type.cs b/csharp/src/Apache.Arrow/Types/Int32Type.cs
deleted file mode 100644
index bc2ad32..0000000
--- a/csharp/src/Apache.Arrow/Types/Int32Type.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Int32Type : IntegerType
-    {
-        public static readonly Int32Type Default = new Int32Type();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Int32;
-        public override string Name => "int32";
-        public override int BitWidth => 32;
-        public override bool IsSigned => true;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Int64Type.cs b/csharp/src/Apache.Arrow/Types/Int64Type.cs
deleted file mode 100644
index 9be7f21..0000000
--- a/csharp/src/Apache.Arrow/Types/Int64Type.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Int64Type : IntegerType
-    {
-        public static readonly Int64Type Default = new Int64Type();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Int64;
-        public override string Name => "int64";
-        public override int BitWidth => 64;
-        public override bool IsSigned => true;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Int8Type.cs b/csharp/src/Apache.Arrow/Types/Int8Type.cs
deleted file mode 100644
index fd6e471..0000000
--- a/csharp/src/Apache.Arrow/Types/Int8Type.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Int8Type : IntegerType
-    {
-        public static readonly Int8Type Default = new Int8Type();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Int8;
-        public override string Name => "int8";
-        public override int BitWidth => 8;
-        public override bool IsSigned => true;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/IntegerType.cs b/csharp/src/Apache.Arrow/Types/IntegerType.cs
deleted file mode 100644
index 7a5057c..0000000
--- a/csharp/src/Apache.Arrow/Types/IntegerType.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public abstract class IntegerType: NumberType
-    {
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/IntervalType.cs b/csharp/src/Apache.Arrow/Types/IntervalType.cs
deleted file mode 100644
index b8e1fde..0000000
--- a/csharp/src/Apache.Arrow/Types/IntervalType.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Types
-{
-    public sealed class IntervalType : FixedWidthType
-    {
-        public static readonly IntervalType YearMonth = new IntervalType(IntervalUnit.YearMonth);
-        public static readonly IntervalType DayTime = new IntervalType(IntervalUnit.DayTime);
-        public static readonly IntervalType MonthDayNanosecond = new IntervalType(IntervalUnit.MonthDayNanosecond);
-        private static readonly IntervalType[] _types = new IntervalType[] { YearMonth, DayTime, MonthDayNanosecond };
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Interval;
-        public override string Name => "interval";
-        public override int BitWidth => Unit switch
-        {
-            IntervalUnit.YearMonth => 32,
-            IntervalUnit.DayTime => 64,
-            IntervalUnit.MonthDayNanosecond => 128,
-            _ => throw new InvalidOperationException($"Unsupported interval unit {Unit}"),
-        };
-
-        public IntervalUnit Unit { get; }
-
-        public IntervalType(IntervalUnit unit = IntervalUnit.YearMonth)
-        {
-            Unit = unit;
-        }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-
-        public static IntervalType FromIntervalUnit(IntervalUnit unit)
-        {
-            return _types[(int)unit];
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/IntervalUnit.cs b/csharp/src/Apache.Arrow/Types/IntervalUnit.cs
deleted file mode 100644
index 09cdc4d..0000000
--- a/csharp/src/Apache.Arrow/Types/IntervalUnit.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public enum IntervalUnit
-    {
-        YearMonth = 0,
-        DayTime = 1,
-        MonthDayNanosecond = 2,
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/LargeBinaryType.cs b/csharp/src/Apache.Arrow/Types/LargeBinaryType.cs
deleted file mode 100644
index e22c333..0000000
--- a/csharp/src/Apache.Arrow/Types/LargeBinaryType.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types;
-
-public class LargeBinaryType: ArrowType
-{
-    public static readonly LargeBinaryType Default = new LargeBinaryType();
-
-    public override ArrowTypeId TypeId => ArrowTypeId.LargeBinary;
-
-    public override string Name => "large_binary";
-
-    public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-}
diff --git a/csharp/src/Apache.Arrow/Types/LargeListType.cs b/csharp/src/Apache.Arrow/Types/LargeListType.cs
deleted file mode 100644
index 2fe8166..0000000
--- a/csharp/src/Apache.Arrow/Types/LargeListType.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class LargeListType : NestedType
-    {
-        public override ArrowTypeId TypeId => ArrowTypeId.LargeList;
-
-        public override string Name => "large_list";
-
-        public Field ValueField => Fields[0];
-
-        public IArrowType ValueDataType => Fields[0].DataType;
-
-        public LargeListType(Field valueField)
-           : base(valueField) { }
-
-        public LargeListType(IArrowType valueDataType)
-            : this(new Field("item", valueDataType, true)) { }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/LargeStringType.cs b/csharp/src/Apache.Arrow/Types/LargeStringType.cs
deleted file mode 100644
index 8698ca4..0000000
--- a/csharp/src/Apache.Arrow/Types/LargeStringType.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types;
-
-public sealed class LargeStringType : ArrowType
-{
-    public static readonly LargeStringType Default = new LargeStringType();
-
-    public override ArrowTypeId TypeId => ArrowTypeId.LargeString;
-
-    public override string Name => "large_utf8";
-
-    public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-}
diff --git a/csharp/src/Apache.Arrow/Types/ListType.cs b/csharp/src/Apache.Arrow/Types/ListType.cs
deleted file mode 100644
index b467934..0000000
--- a/csharp/src/Apache.Arrow/Types/ListType.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class ListType : NestedType
-    {
-        public override ArrowTypeId TypeId => ArrowTypeId.List;
-        public override string Name => "list";
-
-        public Field ValueField => Fields[0];
-
-        public IArrowType ValueDataType => Fields[0].DataType;
-
-        public ListType(Field valueField)
-           : base(valueField) { }
-
-        public ListType(IArrowType valueDataType)
-            : this(new Field("item", valueDataType, true)) { }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/ListViewType.cs b/csharp/src/Apache.Arrow/Types/ListViewType.cs
deleted file mode 100644
index ecf7457..0000000
--- a/csharp/src/Apache.Arrow/Types/ListViewType.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class ListViewType : NestedType
-    {
-        public override ArrowTypeId TypeId => ArrowTypeId.ListView;
-        public override string Name => "listview";
-
-        public Field ValueField => Fields[0];
-
-        public IArrowType ValueDataType => Fields[0].DataType;
-
-        public ListViewType(Field valueField)
-           : base(valueField) { }
-
-        public ListViewType(IArrowType valueDataType)
-            : this(new Field("item", valueDataType, true)) { }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/MapType.cs b/csharp/src/Apache.Arrow/Types/MapType.cs
deleted file mode 100644
index 47e0be4..0000000
--- a/csharp/src/Apache.Arrow/Types/MapType.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Arrow.Types
-{
-    public sealed class MapType : NestedType // MapType = ListType(StructType("key", "value")) 
-    {
-        private const string EntriesKey = "entries";
-        private const string KeyKey = "key";
-        private const string ValueKey = "value";
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Map;
-        public override string Name => "map";
-        public readonly bool KeySorted;
-
-        public StructType KeyValueType => Fields[0].DataType as StructType;
-        public Field KeyField => KeyValueType.Fields[0];
-        public Field ValueField => KeyValueType.Fields[1];
-
-        public MapType(IArrowType key, IArrowType value, bool nullable = true, bool keySorted = false)
-            : base(Entries(key, value, nullable))
-        {
-            KeySorted = keySorted;
-        }
-
-        public MapType(Field key, Field value, bool keySorted = false)
-            : base(Entries(key, value))
-        {
-            KeySorted = keySorted;
-        }
-
-        public MapType(StructType entries, bool keySorted = false) : base(Entries(entries))
-        {
-            KeySorted = keySorted;
-        }
-
-        public MapType(Field entries, bool keySorted = false) : base(Entries(entries))
-        {
-            KeySorted = keySorted;
-        }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-
-        public MapType UnsortedKey()
-        {
-            if (!KeySorted) { return this; }
-
-            return new MapType(Fields[0], keySorted: false);
-        }
-
-        private static Field Entries(IArrowType key, IArrowType value, bool nullable) =>
-            new Field(EntriesKey, NewStruct(new Field(KeyKey, key, false), new Field(ValueKey, value, nullable)), false);
-
-        private static Field Entries(Field key, Field value) =>
-            new Field(EntriesKey, NewStruct(NamedField(KeyKey, key), NamedField(ValueKey, value)), false);
-
-        private static Field Entries(StructType entries)
-        {
-            return new Field(EntriesKey, Struct(entries), false);
-        }
-
-        private static StructType NewStruct(Field key, Field value) => new StructType(new[] { key, value });
-
-        private static StructType Struct(StructType entries)
-        {
-            Field key = NamedField(KeyKey, entries.Fields[0]);
-            Field value = NamedField(ValueKey, entries.Fields[1]);
-            return object.ReferenceEquals(key, entries.Fields[0]) && object.ReferenceEquals(value, entries.Fields[1]) ? entries : NewStruct(key, value);
-        }
-
-        private static Field Entries(Field entries)
-        {
-            StructType structType = (StructType)entries.DataType;
-            StructType adjustedStruct = Struct(structType);
-            return StringComparer.Ordinal.Equals(entries.Name, EntriesKey) && object.ReferenceEquals(structType, adjustedStruct) ? entries : new Field(EntriesKey, adjustedStruct, false);
-        }
-
-        private static Field NamedField(string name, Field field)
-        {
-            return StringComparer.Ordinal.Equals(name, field.Name) ? field : new Field(name, field.DataType, field.IsNullable, field.Metadata);
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/NestedType.cs b/csharp/src/Apache.Arrow/Types/NestedType.cs
deleted file mode 100644
index da6b014..0000000
--- a/csharp/src/Apache.Arrow/Types/NestedType.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Arrow.Types
-{
-    public abstract class NestedType : ArrowType
-    {
-        [Obsolete("Use `Fields` instead")]
-        public IReadOnlyList<Field> Children => Fields;
-
-        public IReadOnlyList<Field> Fields { get; }
-
-        protected NestedType(IReadOnlyList<Field> fields)
-        {
-            if (fields == null || fields.Count == 0)
-            {
-                throw new ArgumentNullException(nameof(fields));
-            }
-            Fields = fields;
-        }
-
-        protected NestedType(Field field)
-        {
-            if (field == null)
-            {
-                throw new ArgumentNullException(nameof(field));
-            }
-            Fields = new Field[] { field };
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/NullType.cs b/csharp/src/Apache.Arrow/Types/NullType.cs
deleted file mode 100644
index 4afe1dc..0000000
--- a/csharp/src/Apache.Arrow/Types/NullType.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class NullType : ArrowType
-    {
-        public static readonly NullType Default = new NullType();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Null;
-        public override string Name => "null";
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/NumberType.cs b/csharp/src/Apache.Arrow/Types/NumberType.cs
deleted file mode 100644
index 04d21bc..0000000
--- a/csharp/src/Apache.Arrow/Types/NumberType.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public abstract class NumberType: FixedWidthType
-    {
-        public abstract bool IsSigned { get; }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/StringType.cs b/csharp/src/Apache.Arrow/Types/StringType.cs
deleted file mode 100644
index 33620aa..0000000
--- a/csharp/src/Apache.Arrow/Types/StringType.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class StringType : ArrowType
-    {
-        public static StringType Default = new StringType();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.String;
-        public override string Name => "utf8";
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/StringViewType.cs b/csharp/src/Apache.Arrow/Types/StringViewType.cs
deleted file mode 100644
index 0c539a5..0000000
--- a/csharp/src/Apache.Arrow/Types/StringViewType.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class StringViewType : ArrowType
-    {
-        public static StringViewType Default = new StringViewType();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.StringView;
-        public override string Name => "utf8view";
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/StructType.cs b/csharp/src/Apache.Arrow/Types/StructType.cs
deleted file mode 100644
index da2411d..0000000
--- a/csharp/src/Apache.Arrow/Types/StructType.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Apache.Arrow.Types
-{
-    public sealed class StructType : NestedType, IRecordType
-    {
-        public override ArrowTypeId TypeId => ArrowTypeId.Struct;
-        public override string Name => "struct";
-
-        public StructType(IReadOnlyList<Field> fields) : base(fields)
-        { }
-
-        public Field GetFieldByIndex(int index) => Fields[index];
-
-        public Field GetFieldByName(string name,
-            IEqualityComparer<string> comparer = default)
-        {
-            if (comparer == null)
-                comparer = StringComparer.Ordinal;
-
-            return Fields.FirstOrDefault(
-                field => comparer.Equals(field.Name, name));
-        }
-
-        public int GetFieldIndex(string name,
-            IEqualityComparer<string> comparer = default)
-        {
-            if (comparer == null)
-                comparer = StringComparer.Ordinal;
-
-            // TODO: Consider caching field index if this method is in hot path.
-
-            for (int i = 0; i < Fields.Count; i++)
-            {
-                if (comparer.Equals(Fields[i].Name, name))
-                {
-                    return i;
-                }
-            }
-
-            return -1;
-        }
-
-        public override void Accept(IArrowTypeVisitor visitor)
-        {
-            if (visitor is IArrowTypeVisitor<StructType> structTypeVisitor)
-            {
-                structTypeVisitor.Visit(this);
-            }
-            else if (visitor is IArrowTypeVisitor<IRecordType> interfaceVisitor)
-            {
-                interfaceVisitor.Visit(this);
-            }
-            else
-            {
-                visitor.Visit(this);
-            }
-        }
-
-        int IRecordType.FieldCount => Fields.Count;
-
-        Field IRecordType.GetFieldByName(string name) => GetFieldByName(name);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Time32Type.cs b/csharp/src/Apache.Arrow/Types/Time32Type.cs
deleted file mode 100644
index 7eb3c26..0000000
--- a/csharp/src/Apache.Arrow/Types/Time32Type.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Time32Type : TimeType
-    {
-        public static Time32Type Default => Millisecond;
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Time32;
-        public override string Name => "time32";
-        public override int BitWidth => 32;
-
-        public Time32Type(TimeUnit unit = TimeUnit.Millisecond)
-            : base(unit) { }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/Time64Type.cs b/csharp/src/Apache.Arrow/Types/Time64Type.cs
deleted file mode 100644
index f674c25..0000000
--- a/csharp/src/Apache.Arrow/Types/Time64Type.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-namespace Apache.Arrow.Types
-{
-    public sealed class Time64Type : TimeType
-    {
-        public static Time64Type Default => Nanosecond;
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Time64;
-        public override string Name => "time64";
-        public override int BitWidth => 64;
-
-        public Time64Type(TimeUnit unit = TimeUnit.Nanosecond)
-            : base(unit) { }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/TimeBasedType.cs b/csharp/src/Apache.Arrow/Types/TimeBasedType.cs
deleted file mode 100644
index ffcd3f5..0000000
--- a/csharp/src/Apache.Arrow/Types/TimeBasedType.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public abstract class TimeBasedType : FixedWidthType
-    {
-        public TimeUnit Unit { get; }
-
-        protected TimeBasedType(TimeUnit unit)
-        {
-            Unit = unit;
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/TimeType.cs b/csharp/src/Apache.Arrow/Types/TimeType.cs
deleted file mode 100644
index b317df2..0000000
--- a/csharp/src/Apache.Arrow/Types/TimeType.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public abstract class TimeType : TimeBasedType
-    {
-        public static readonly Time32Type Second = new Time32Type(TimeUnit.Second);
-        public static readonly Time32Type Millisecond = new Time32Type(TimeUnit.Millisecond);
-        public static readonly Time64Type Microsecond = new Time64Type(TimeUnit.Microsecond);
-        public static readonly Time64Type Nanosecond = new Time64Type(TimeUnit.Nanosecond);
-        private static readonly TimeType[] _types = new TimeType[] { Second, Millisecond, Microsecond, Nanosecond };
-
-        protected TimeType(TimeUnit unit)
-            : base(unit)
-        {
-        }
-
-        public static TimeType FromTimeUnit(TimeUnit unit)
-        {
-            return _types[(int)unit];
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/TimeUnit.cs b/csharp/src/Apache.Arrow/Types/TimeUnit.cs
deleted file mode 100644
index ba60fa9..0000000
--- a/csharp/src/Apache.Arrow/Types/TimeUnit.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.IO;
-using System;
-
-namespace Apache.Arrow.Types
-{
-    public enum TimeUnit
-    {
-        Second,
-        Millisecond,
-        Microsecond,
-        Nanosecond
-    }
-
-    internal static class TimeUnitExtensions
-    {
-        private const long TicksPerMicrosecond = 10;
-        private const long NanosecondsPerTick = 100;
-
-        public static long ConvertFromTicks(this TimeUnit unit, long ticks)
-        {
-            return unit switch
-            {
-                TimeUnit.Second => ticks / TimeSpan.TicksPerSecond,
-                TimeUnit.Millisecond => ticks / TimeSpan.TicksPerMillisecond,
-                TimeUnit.Microsecond => ticks / TicksPerMicrosecond,
-                TimeUnit.Nanosecond => ticks * NanosecondsPerTick,
-                _ => throw new InvalidDataException($"Unsupported time unit: {unit}")
-            };
-        }
-
-        public static long ConvertToTicks(this TimeUnit unit, long units)
-        {
-            return unit switch
-            {
-                TimeUnit.Second => units * TimeSpan.TicksPerSecond,
-                TimeUnit.Millisecond => units * TimeSpan.TicksPerMillisecond,
-                TimeUnit.Microsecond => units * TicksPerMicrosecond,
-                TimeUnit.Nanosecond => units / NanosecondsPerTick,
-                _ => throw new InvalidDataException($"Unsupported time unit: {unit}")
-            };
-        }
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/TimestampType.cs b/csharp/src/Apache.Arrow/Types/TimestampType.cs
deleted file mode 100644
index 565eb62..0000000
--- a/csharp/src/Apache.Arrow/Types/TimestampType.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-using System;
-
-namespace Apache.Arrow.Types
-{
-    public sealed class TimestampType : TimeBasedType
-    {
-        public static readonly TimestampType Default = new TimestampType(TimeUnit.Millisecond, "+00:00");
-
-        public override ArrowTypeId TypeId => ArrowTypeId.Timestamp;
-        public override string Name => "timestamp";
-        public override int BitWidth => 64;
-
-        public string Timezone { get; }
-
-        public bool IsTimeZoneAware => !string.IsNullOrWhiteSpace(Timezone);
-
-        public TimestampType(
-            TimeUnit unit = TimeUnit.Millisecond,
-            string timezone = default)
-            : base(unit)
-        {
-            Timezone = timezone;
-        }
-
-        public TimestampType(
-            TimeUnit unit = TimeUnit.Millisecond,
-            TimeZoneInfo timezone = default)
-            : base(unit)
-        {
-            Timezone = timezone?.BaseUtcOffset.ToTimeZoneOffsetString();
-        }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/UInt16Type.cs b/csharp/src/Apache.Arrow/Types/UInt16Type.cs
deleted file mode 100644
index 7e020d3..0000000
--- a/csharp/src/Apache.Arrow/Types/UInt16Type.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class UInt16Type : IntegerType
-    {
-        public static readonly UInt16Type Default = new UInt16Type();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.UInt16;
-        public override string Name => "uint16";
-        public override int BitWidth => 16;
-        public override bool IsSigned => false;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/UInt32Type.cs b/csharp/src/Apache.Arrow/Types/UInt32Type.cs
deleted file mode 100644
index 9015f11..0000000
--- a/csharp/src/Apache.Arrow/Types/UInt32Type.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class UInt32Type : IntegerType
-    {
-        public static readonly UInt32Type Default = new UInt32Type();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.UInt32;
-        public override string Name => "uint32";
-        public override int BitWidth => 32;
-        public override bool IsSigned => false;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/UInt64Type.cs b/csharp/src/Apache.Arrow/Types/UInt64Type.cs
deleted file mode 100644
index a414e70..0000000
--- a/csharp/src/Apache.Arrow/Types/UInt64Type.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class UInt64Type : IntegerType
-    {
-        public static readonly UInt64Type Default = new UInt64Type();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.UInt64;
-        public override string Name => "uint64";
-        public override int BitWidth => 64;
-        public override bool IsSigned => false;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/UInt8Type.cs b/csharp/src/Apache.Arrow/Types/UInt8Type.cs
deleted file mode 100644
index 31121b4..0000000
--- a/csharp/src/Apache.Arrow/Types/UInt8Type.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Types
-{
-    public sealed class UInt8Type : IntegerType
-    {
-        public static readonly UInt8Type Default = new UInt8Type();
-
-        public override ArrowTypeId TypeId => ArrowTypeId.UInt8;
-        public override string Name => "uint8";
-        public override int BitWidth => 8;
-        public override bool IsSigned => false;
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Types/UnionType.cs b/csharp/src/Apache.Arrow/Types/UnionType.cs
deleted file mode 100644
index 23fa3b4..0000000
--- a/csharp/src/Apache.Arrow/Types/UnionType.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Apache.Arrow.Types
-{
-    public enum UnionMode
-    {
-        Sparse,
-        Dense
-    }
-
-    public sealed class UnionType : NestedType
-    {
-        public override ArrowTypeId TypeId => ArrowTypeId.Union;
-        public override string Name => "union";
-
-        public UnionMode Mode { get; }
-
-        public int[] TypeIds { get; }
-
-        public UnionType(
-            IEnumerable<Field> fields, IEnumerable<int> typeIds,
-            UnionMode mode = UnionMode.Sparse)
-            : base(fields.ToArray())
-        {
-            TypeIds = typeIds.ToArray();
-            Mode = mode;
-        }
-
-        public override void Accept(IArrowTypeVisitor visitor) => Accept(this, visitor);
-    }
-}
diff --git a/csharp/src/Apache.Arrow/Utility.cs b/csharp/src/Apache.Arrow/Utility.cs
deleted file mode 100644
index 22b3ff1..0000000
--- a/csharp/src/Apache.Arrow/Utility.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Arrow
-{
-    internal static class Utility
-    {
-        public static IList<T> DeleteListElement<T>(IList<T> values, int index)
-        {
-            if (index < 0 || index >= values.Count)
-            {
-                throw new ArgumentException("Invalid index", nameof(index));
-            }
-
-            List<T> newList = new List<T>(values.Count - 1);
-            for (int i = 0; i < index; i++)
-            {
-                newList.Add(values[i]);
-            }
-            for (int i = index + 1; i < values.Count; i++)
-            {
-                newList.Add(values[i]);
-            }
-
-            return newList;
-        }
-
-        public static IList<T> AddListElement<T>(IList<T> values, int index, T newElement)
-        {
-            if (index < 0 || index > values.Count)
-            {
-                throw new ArgumentException("Invalid index", nameof(index));
-            }
-
-            List<T> newList = new List<T>(values.Count + 1);
-            for (int i = 0; i < index; i++)
-            {
-                newList.Add(values[i]);
-            }
-            newList.Add(newElement);
-            for (int i = index; i < values.Count; i++)
-            {
-                newList.Add(values[i]);
-            }
-
-            return newList;
-        }
-
-        public static IList<T> SetListElement<T>(IList<T> values, int index, T newElement)
-        {
-            if (index < 0 || index >= values.Count)
-            {
-                throw new ArgumentException("Invalid index", nameof(index));
-            }
-
-            List<T> newList = new List<T>(values.Count);
-            for (int i = 0; i < index; i++)
-            {
-                newList.Add(values[i]);
-            }
-            newList.Add(newElement);
-            for (int i = index + 1; i < values.Count; i++)
-            {
-                newList.Add(values[i]);
-            }
-
-            return newList;
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Benchmarks/Apache.Arrow.Benchmarks.csproj b/csharp/test/Apache.Arrow.Benchmarks/Apache.Arrow.Benchmarks.csproj
deleted file mode 100644
index 27148de..0000000
--- a/csharp/test/Apache.Arrow.Benchmarks/Apache.Arrow.Benchmarks.csproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>net8.0</TargetFramework>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="BenchmarkDotNet" Version="0.15.2" />
-    <PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.15.2" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\..\src\Apache.Arrow\Apache.Arrow.csproj" />
-    <ProjectReference Include="..\Apache.Arrow.Tests\Apache.Arrow.Tests.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/test/Apache.Arrow.Benchmarks/ArrowReaderBenchmark.cs b/csharp/test/Apache.Arrow.Benchmarks/ArrowReaderBenchmark.cs
deleted file mode 100644
index cd8198d..0000000
--- a/csharp/test/Apache.Arrow.Benchmarks/ArrowReaderBenchmark.cs
+++ /dev/null
@@ -1,160 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Ipc;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Tests;
-using Apache.Arrow.Types;
-using BenchmarkDotNet.Attributes;
-using System;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.Benchmarks
-{
-    //[EtwProfiler] - needs elevated privileges
-    [MemoryDiagnoser]
-    public class ArrowReaderBenchmark
-    {
-        [Params(10_000, 1_000_000)]
-        public int Count { get; set; }
-
-        private MemoryStream _memoryStream;
-        private static readonly MemoryAllocator s_allocator = new TestMemoryAllocator();
-
-        [GlobalSetup]
-        public async Task GlobalSetup()
-        {
-            RecordBatch batch = TestData.CreateSampleRecordBatch(length: Count, createDictionaryArray: false);
-            _memoryStream = new MemoryStream();
-
-            ArrowStreamWriter writer = new ArrowStreamWriter(_memoryStream, batch.Schema);
-            await writer.WriteRecordBatchAsync(batch);
-        }
-
-        [IterationSetup]
-        public void Setup()
-        {
-            _memoryStream.Position = 0;
-        }
-
-        [Benchmark]
-        public async Task<double> ArrowReaderWithMemoryStream()
-        {
-            double sum = 0;
-            var reader = new ArrowStreamReader(_memoryStream);
-            RecordBatch recordBatch;
-            while ((recordBatch = await reader.ReadNextRecordBatchAsync()) != null)
-            {
-                using (recordBatch)
-                {
-                    sum += SumAllNumbers(recordBatch);
-                }
-            }
-            return sum;
-        }
-
-        [Benchmark]
-        public async Task<double> ArrowReaderWithMemoryStream_ManagedMemory()
-        {
-            double sum = 0;
-            var reader = new ArrowStreamReader(_memoryStream, s_allocator);
-            RecordBatch recordBatch;
-            while ((recordBatch = await reader.ReadNextRecordBatchAsync()) != null)
-            {
-                using (recordBatch)
-                {
-                    sum += SumAllNumbers(recordBatch);
-                }
-            }
-            return sum;
-        }
-
-        [Benchmark]
-        public async Task<double> ArrowReaderWithMemory()
-        {
-            double sum = 0;
-            var reader = new ArrowStreamReader(_memoryStream.GetBuffer());
-            RecordBatch recordBatch;
-            while ((recordBatch = await reader.ReadNextRecordBatchAsync()) != null)
-            {
-                using (recordBatch)
-                {
-                    sum += SumAllNumbers(recordBatch);
-                }
-            }
-            return sum;
-        }
-
-        private static double SumAllNumbers(RecordBatch recordBatch)
-        {
-            double sum = 0;
-
-            for (int k = 0; k < recordBatch.ColumnCount; k++)
-            {
-                var array = recordBatch.Arrays.ElementAt(k);
-                switch (recordBatch.Schema.GetFieldByIndex(k).DataType.TypeId)
-                {
-                    case ArrowTypeId.Int64:
-                        Int64Array int64Array = (Int64Array)array;
-                        sum += Sum(int64Array);
-                        break;
-                    case ArrowTypeId.Double:
-                        DoubleArray doubleArray = (DoubleArray)array;
-                        sum += Sum(doubleArray);
-                        break;
-                    case ArrowTypeId.Decimal128:
-                        Decimal128Array decimalArray = (Decimal128Array)array;
-                        sum += Sum(decimalArray);
-                        break;
-                }
-            }
-            return sum;
-        }
-
-        private static double Sum(DoubleArray doubleArray)
-        {
-            double sum = 0;
-            ReadOnlySpan<double> values = doubleArray.Values;
-            for (int valueIndex = 0; valueIndex < values.Length; valueIndex++)
-            {
-                sum += values[valueIndex];
-            }
-            return sum;
-        }
-
-        private static long Sum(Int64Array int64Array)
-        {
-            long sum = 0;
-            ReadOnlySpan<long> values = int64Array.Values;
-            for (int valueIndex = 0; valueIndex < values.Length; valueIndex++)
-            {
-                sum += values[valueIndex];
-            }
-            return sum;
-        }
-
-        private static double Sum(Decimal128Array decimal128Array)
-        {
-            double sum = 0;
-            for (int valueIndex = 0; valueIndex < decimal128Array.Length; valueIndex++)
-            {
-                sum += (double)decimal128Array.GetValue(valueIndex);
-            }
-            return sum;
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Benchmarks/ArrowWriterBenchmark.cs b/csharp/test/Apache.Arrow.Benchmarks/ArrowWriterBenchmark.cs
deleted file mode 100644
index f35c2a5..0000000
--- a/csharp/test/Apache.Arrow.Benchmarks/ArrowWriterBenchmark.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Ipc;
-using Apache.Arrow.Tests;
-using BenchmarkDotNet.Attributes;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.Benchmarks
-{
-    //[EtwProfiler] - needs elevated privileges
-    [MemoryDiagnoser]
-    public class ArrowWriterBenchmark
-    {
-        [Params(10_000, 1_000_000)]
-        public int BatchLength{ get; set; }
-
-        //Max column set count is 15 before reaching 2gb limit of memory stream
-        [Params(10, 14)]
-        public int ColumnSetCount { get; set; }
-
-        private MemoryStream _memoryStream;
-        private RecordBatch _batch;
-
-        [GlobalSetup]
-        public void GlobalSetup()
-        {
-            _batch = TestData.CreateSampleRecordBatch(BatchLength, ColumnSetCount);
-            _memoryStream = new MemoryStream();
-        }
-
-        [IterationSetup]
-        public void Setup()
-        {
-            _memoryStream.Position = 0;
-        }
-
-        [Benchmark]
-        public async Task WriteBatch()
-        {
-            ArrowStreamWriter writer = new ArrowStreamWriter(_memoryStream, _batch.Schema);
-            await writer.WriteRecordBatchAsync(_batch);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Benchmarks/Program.cs b/csharp/test/Apache.Arrow.Benchmarks/Program.cs
deleted file mode 100644
index 0f1410f..0000000
--- a/csharp/test/Apache.Arrow.Benchmarks/Program.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using BenchmarkDotNet.Running;
-
-namespace Apache.Arrow.Benchmarks
-{
-    public static class Program
-    {
-        public static void Main(string[] args)
-        {
-            BenchmarkSwitcher
-                .FromAssembly(typeof(Program).Assembly)
-                .Run(args);
-        }
-    }
-}
\ No newline at end of file
diff --git a/csharp/test/Apache.Arrow.Compression.Tests/Apache.Arrow.Compression.Tests.csproj b/csharp/test/Apache.Arrow.Compression.Tests/Apache.Arrow.Compression.Tests.csproj
deleted file mode 100644
index d36bc0f..0000000
--- a/csharp/test/Apache.Arrow.Compression.Tests/Apache.Arrow.Compression.Tests.csproj
+++ /dev/null
@@ -1,28 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
-
-    <IsPackable>false</IsPackable>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
-    <PackageReference Include="xunit" Version="2.9.3" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\..\src\Apache.Arrow\Apache.Arrow.csproj" />
-    <ProjectReference Include="..\..\src\Apache.Arrow.Compression\Apache.Arrow.Compression.csproj" />
-    <ProjectReference Include="..\Apache.Arrow.Tests\Apache.Arrow.Tests.csproj" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <EmbeddedResource Include="Resources\ipc_lz4_compression.arrow" />
-    <EmbeddedResource Include="Resources\ipc_lz4_compression.arrow_stream" />
-    <EmbeddedResource Include="Resources\ipc_zstd_compression.arrow" />
-    <EmbeddedResource Include="Resources\ipc_zstd_compression.arrow_stream" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/test/Apache.Arrow.Compression.Tests/ArrowFileReaderTests.cs b/csharp/test/Apache.Arrow.Compression.Tests/ArrowFileReaderTests.cs
deleted file mode 100644
index 667f25f..0000000
--- a/csharp/test/Apache.Arrow.Compression.Tests/ArrowFileReaderTests.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Ipc;
-using System;
-using System.Reflection;
-using Xunit;
-
-namespace Apache.Arrow.Compression.Tests
-{
-    public class ArrowFileReaderTests
-    {
-        [Theory]
-        [InlineData("ipc_lz4_compression.arrow")]
-        [InlineData("ipc_zstd_compression.arrow")]
-        public void CanReadCompressedIpcFile(string fileName)
-        {
-            var assembly = Assembly.GetExecutingAssembly();
-            using var stream = assembly.GetManifestResourceStream($"Apache.Arrow.Compression.Tests.Resources.{fileName}");
-            Assert.NotNull(stream);
-            var codecFactory = new CompressionCodecFactory();
-            using var reader = new ArrowFileReader(stream, codecFactory);
-
-            var batch = reader.ReadNextRecordBatch();
-
-            var intArray = (Int32Array) batch.Column("integers");
-            var floatArray = (FloatArray) batch.Column("floats");
-
-            const int numRows = 100;
-            Assert.Equal(numRows, intArray.Length);
-            Assert.Equal(numRows, floatArray.Length);
-
-            for (var i = 0; i < numRows; ++i)
-            {
-                Assert.Equal(i, intArray.GetValue(i));
-                Assert.True(Math.Abs(floatArray.GetValue(i).Value - 0.1f * i) < 1.0e-6);
-            }
-        }
-
-        [Fact]
-        public void ErrorReadingCompressedFileWithoutCodecFactory()
-        {
-            var assembly = Assembly.GetExecutingAssembly();
-            using var stream = assembly.GetManifestResourceStream("Apache.Arrow.Compression.Tests.Resources.ipc_lz4_compression.arrow");
-            Assert.NotNull(stream);
-            using var reader = new ArrowFileReader(stream);
-
-            var exception = Assert.Throws<Exception>(() => reader.ReadNextRecordBatch());
-            Assert.Contains("no ICompressionCodecFactory has been configured", exception.Message);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Compression.Tests/ArrowFileWriterTests.cs b/csharp/test/Apache.Arrow.Compression.Tests/ArrowFileWriterTests.cs
deleted file mode 100644
index a237f9c..0000000
--- a/csharp/test/Apache.Arrow.Compression.Tests/ArrowFileWriterTests.cs
+++ /dev/null
@@ -1,147 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading.Tasks;
-using Apache.Arrow.Ipc;
-using Apache.Arrow.Tests;
-using K4os.Compression.LZ4;
-using Xunit;
-
-namespace Apache.Arrow.Compression.Tests
-{
-    public class ArrowFileWriterTests
-    {
-        [Fact]
-        public void ThrowsWhenNoCompressionFactoryProvided()
-        {
-            var batch = TestData.CreateSampleRecordBatch(length: 100);
-            var options = new IpcOptions
-            {
-                CompressionCodec = CompressionCodecType.Zstd,
-            };
-
-            using var stream = new MemoryStream();
-            var exception = Assert.Throws<ArgumentException>(
-                () => new ArrowFileWriter(stream, batch.Schema, leaveOpen: true, options));
-
-            Assert.Contains("A CompressionCodecFactory must be provided", exception.Message);
-        }
-
-        [Theory]
-        [InlineData(CompressionCodecType.Zstd, null)]
-        [InlineData(CompressionCodecType.Zstd, 2)]
-        [InlineData(CompressionCodecType.Lz4Frame, null)]
-        [InlineData(CompressionCodecType.Lz4Frame, (int)LZ4Level.L03_HC)]
-        public void CanWriteCompressedIpcFile(CompressionCodecType codec, int? compressionLevel)
-        {
-            var batch = TestData.CreateSampleRecordBatch(length: 100);
-            var codecFactory = new CompressionCodecFactory();
-            var options = new IpcOptions
-            {
-                CompressionCodecFactory = codecFactory,
-                CompressionCodec = codec,
-                CompressionLevel = compressionLevel,
-            };
-            TestRoundTripRecordBatches(new [] {batch}, options, codecFactory);
-        }
-
-        [Theory]
-        [InlineData(CompressionCodecType.Zstd)]
-        [InlineData(CompressionCodecType.Lz4Frame)]
-        public async Task CanWriteCompressedIpcFileAsync(CompressionCodecType codec)
-        {
-            var batch = TestData.CreateSampleRecordBatch(length: 100);
-            var codecFactory = new CompressionCodecFactory();
-            var options = new IpcOptions
-            {
-                CompressionCodecFactory = codecFactory,
-                CompressionCodec = codec,
-            };
-            await TestRoundTripRecordBatchesAsync(new [] {batch}, options, codecFactory);
-        }
-
-        private static void TestRoundTripRecordBatches(
-            IReadOnlyList<RecordBatch> originalBatches, IpcOptions options, ICompressionCodecFactory codecFactory)
-        {
-            using var stream = new MemoryStream();
-
-            using (var writer = new ArrowFileWriter(stream, originalBatches[0].Schema, leaveOpen: true, options))
-            {
-                foreach (var originalBatch in originalBatches)
-                {
-                    writer.WriteRecordBatch(originalBatch);
-                }
-                writer.WriteEnd();
-            }
-
-            // Should throw if trying to read without an ICompressionCodecFactory
-            stream.Position = 0;
-            var exception = Assert.Throws<Exception>(() =>
-            {
-                using var reader = new ArrowFileReader(stream, leaveOpen: true);
-                reader.ReadNextRecordBatch();
-            });
-            Assert.Contains(nameof(ICompressionCodecFactory), exception.Message);
-
-            stream.Position = 0;
-            using (var reader = new ArrowFileReader(stream, codecFactory))
-            {
-                foreach (var originalBatch in originalBatches)
-                {
-                    var newBatch = reader.ReadNextRecordBatch();
-                    ArrowReaderVerifier.CompareBatches(originalBatch, newBatch);
-                }
-            }
-        }
-
-        private static async Task TestRoundTripRecordBatchesAsync(
-            IReadOnlyList<RecordBatch> originalBatches, IpcOptions options, ICompressionCodecFactory codecFactory)
-        {
-            using var stream = new MemoryStream();
-
-            using (var writer = new ArrowFileWriter(stream, originalBatches[0].Schema, leaveOpen: true, options))
-            {
-                foreach (var originalBatch in originalBatches)
-                {
-                    await writer.WriteRecordBatchAsync(originalBatch);
-                }
-                await writer.WriteEndAsync();
-            }
-
-            // Should throw if trying to read without an ICompressionCodecFactory
-            stream.Position = 0;
-            var exception = await Assert.ThrowsAsync<Exception>(async () =>
-            {
-                using var reader = new ArrowFileReader(stream, leaveOpen: true);
-                await reader.ReadNextRecordBatchAsync();
-            });
-            Assert.Contains(nameof(ICompressionCodecFactory), exception.Message);
-
-            stream.Position = 0;
-            using (var reader = new ArrowFileReader(stream, codecFactory))
-            {
-                foreach (var originalBatch in originalBatches)
-                {
-                    var newBatch = await reader.ReadNextRecordBatchAsync();
-                    ArrowReaderVerifier.CompareBatches(originalBatch, newBatch);
-                }
-            }
-        }
-    }
-}
-
diff --git a/csharp/test/Apache.Arrow.Compression.Tests/ArrowStreamReaderTests.cs b/csharp/test/Apache.Arrow.Compression.Tests/ArrowStreamReaderTests.cs
deleted file mode 100644
index 6f6a26e..0000000
--- a/csharp/test/Apache.Arrow.Compression.Tests/ArrowStreamReaderTests.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Ipc;
-using System;
-using System.Reflection;
-using Apache.Arrow.Tests;
-using Xunit;
-
-namespace Apache.Arrow.Compression.Tests
-{
-    public class ArrowStreamReaderTests
-    {
-        [Theory]
-        [InlineData("ipc_lz4_compression.arrow_stream")]
-        [InlineData("ipc_zstd_compression.arrow_stream")]
-        public void CanReadCompressedIpcStream(string fileName)
-        {
-            var assembly = Assembly.GetExecutingAssembly();
-            using var stream = assembly.GetManifestResourceStream($"Apache.Arrow.Compression.Tests.Resources.{fileName}");
-            Assert.NotNull(stream);
-            var codecFactory = new CompressionCodecFactory();
-            using var reader = new ArrowStreamReader(stream, codecFactory);
-
-            VerifyCompressedIpcFileBatch(reader.ReadNextRecordBatch());
-
-        }
-
-        [Theory]
-        [InlineData("ipc_lz4_compression.arrow_stream")]
-        [InlineData("ipc_zstd_compression.arrow_stream")]
-        public void CanReadCompressedIpcStreamFromMemoryBuffer(string fileName)
-        {
-            var assembly = Assembly.GetExecutingAssembly();
-            using var stream = assembly.GetManifestResourceStream($"Apache.Arrow.Compression.Tests.Resources.{fileName}");
-            Assert.NotNull(stream);
-            var buffer = new byte[stream.Length];
-            stream.ReadExactly(buffer);
-            var codecFactory = new Compression.CompressionCodecFactory();
-            using var reader = new ArrowStreamReader(buffer, codecFactory);
-
-            VerifyCompressedIpcFileBatch(reader.ReadNextRecordBatch());
-        }
-
-        [Fact]
-        public void ErrorReadingCompressedStreamWithoutCodecFactory()
-        {
-            var assembly = Assembly.GetExecutingAssembly();
-            using var stream = assembly.GetManifestResourceStream("Apache.Arrow.Compression.Tests.Resources.ipc_lz4_compression.arrow_stream");
-            Assert.NotNull(stream);
-            using var reader = new ArrowStreamReader(stream);
-
-            var exception = Assert.Throws<Exception>(() => reader.ReadNextRecordBatch());
-            Assert.Contains("no ICompressionCodecFactory has been configured", exception.Message);
-        }
-
-        [Theory]
-        [InlineData("ipc_lz4_compression.arrow_stream")]
-        [InlineData("ipc_zstd_compression.arrow_stream")]
-        public void MemoryPoolDisposedOnReadCompressedIpcStream(string fileName)
-        {
-            var assembly = Assembly.GetExecutingAssembly();
-            using var stream = assembly.GetManifestResourceStream($"Apache.Arrow.Compression.Tests.Resources.{fileName}");
-            Assert.NotNull(stream);
-            var codecFactory = new CompressionCodecFactory();
-            var allocator = new TestMemoryAllocator();
-            using var reader = new ArrowStreamReader(stream, allocator, codecFactory, false);
-            using (var recordBatch = reader.ReadNextRecordBatch())
-            {
-                VerifyCompressedIpcFileBatch(recordBatch);
-            }
-            Assert.True(allocator.Statistics.Allocations > 0);
-            Assert.Equal(0, allocator.Rented);
-
-        }
-
-        private static void VerifyCompressedIpcFileBatch(RecordBatch batch)
-        {
-            var intArray = (Int32Array) batch.Column("integers");
-            var floatArray = (FloatArray) batch.Column("floats");
-
-            const int numRows = 100;
-            Assert.Equal(numRows, intArray.Length);
-            Assert.Equal(numRows, floatArray.Length);
-
-            for (var i = 0; i < numRows; ++i)
-            {
-                Assert.Equal(i, intArray.GetValue(i));
-                Assert.True(Math.Abs(floatArray.GetValue(i).Value - 0.1f * i) < 1.0e-6);
-            }
-        }
-    }
-}
-
diff --git a/csharp/test/Apache.Arrow.Compression.Tests/ArrowStreamWriterTests.cs b/csharp/test/Apache.Arrow.Compression.Tests/ArrowStreamWriterTests.cs
deleted file mode 100644
index 1f0f61c..0000000
--- a/csharp/test/Apache.Arrow.Compression.Tests/ArrowStreamWriterTests.cs
+++ /dev/null
@@ -1,199 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading.Tasks;
-using Apache.Arrow.Ipc;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Tests;
-using K4os.Compression.LZ4;
-using Xunit;
-
-namespace Apache.Arrow.Compression.Tests
-{
-    public class ArrowStreamWriterTests
-    {
-        [Fact]
-        public void ThrowsWhenNoCompressionFactoryProvided()
-        {
-            var batch = TestData.CreateSampleRecordBatch(length: 100);
-            var options = new IpcOptions
-            {
-                CompressionCodec = CompressionCodecType.Zstd,
-            };
-
-            using var stream = new MemoryStream();
-            var exception = Assert.Throws<ArgumentException>(
-                () => new ArrowStreamWriter(stream, batch.Schema, leaveOpen: true, options));
-
-            Assert.Contains("A CompressionCodecFactory must be provided", exception.Message);
-        }
-
-        [Theory]
-        [InlineData(CompressionCodecType.Zstd, null)]
-        [InlineData(CompressionCodecType.Zstd, 2)]
-        [InlineData(CompressionCodecType.Lz4Frame, null)]
-        [InlineData(CompressionCodecType.Lz4Frame, (int)LZ4Level.L03_HC)]
-        public void CanWriteCompressedIpcStream(CompressionCodecType codec, int? compressionLevel)
-        {
-            var batch = TestData.CreateSampleRecordBatch(length: 100);
-            var codecFactory = new CompressionCodecFactory();
-            var options = new IpcOptions
-            {
-                CompressionCodecFactory = codecFactory,
-                CompressionCodec = codec,
-                CompressionLevel = compressionLevel,
-            };
-            TestRoundTripRecordBatches(new [] {batch}, options, codecFactory);
-        }
-
-        [Theory]
-        [InlineData(CompressionCodecType.Zstd)]
-        [InlineData(CompressionCodecType.Lz4Frame)]
-        public async Task CanWriteCompressedIpcStreamAsync(CompressionCodecType codec)
-        {
-            var batch = TestData.CreateSampleRecordBatch(length: 100);
-            var codecFactory = new CompressionCodecFactory();
-            var options = new IpcOptions
-            {
-                CompressionCodecFactory = codecFactory,
-                CompressionCodec = codec,
-            };
-            await TestRoundTripRecordBatchesAsync(new [] {batch}, options, codecFactory);
-        }
-
-        [Fact]
-        public void CanWriteEmptyBatches()
-        {
-            var batch = TestData.CreateSampleRecordBatch(length: 0);
-            var codecFactory = new CompressionCodecFactory();
-            var options = new IpcOptions
-            {
-                CompressionCodecFactory = codecFactory,
-                CompressionCodec = CompressionCodecType.Lz4Frame,
-            };
-            TestRoundTripRecordBatches(new [] {batch}, options, codecFactory);
-        }
-
-        [Theory]
-        [InlineData(CompressionCodecType.Zstd)]
-        [InlineData(CompressionCodecType.Lz4Frame)]
-        public void ThrowsForInvalidCompressionLevel(CompressionCodecType codec)
-        {
-            var batch = TestData.CreateSampleRecordBatch(length: 100);
-            var codecFactory = new CompressionCodecFactory();
-            var options = new IpcOptions
-            {
-                CompressionCodecFactory = codecFactory,
-                CompressionCodec = codec,
-                CompressionLevel = 12345,
-            };
-
-            using var stream = new MemoryStream();
-
-            Assert.Throws<ArgumentException>(() =>
-            {
-                using var writer = new ArrowStreamWriter(stream, batch.Schema, leaveOpen: false, options);
-                writer.WriteRecordBatch(batch);
-                writer.WriteEnd();
-            });
-        }
-        [Theory]
-        [InlineData(CompressionCodecType.Zstd)]
-        [InlineData(CompressionCodecType.Lz4Frame)]
-        public async Task MemoryOwnerDisposal(CompressionCodecType codec)
-        {
-            var allocator = new TestMemoryAllocator();
-            var originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-            var options = new IpcOptions() { CompressionCodecFactory = new CompressionCodecFactory(), CompressionCodec = codec };
-            await TestRoundTripRecordBatchesAsync(new List<RecordBatch> () {originalBatch}, options, options.CompressionCodecFactory,
-                allocator);
-            Assert.True(allocator.Statistics.Allocations > 0);
-            // make sure all memory allocated by the writer was disposed
-            Assert.Equal(0,allocator.Rented);
-        }
-
-        private static void TestRoundTripRecordBatches(
-            IReadOnlyList<RecordBatch> originalBatches, IpcOptions options, ICompressionCodecFactory codecFactory)
-        {
-            using var stream = new MemoryStream();
-
-            using (var writer = new ArrowStreamWriter(stream, originalBatches[0].Schema, leaveOpen: true, options))
-            {
-                foreach (var originalBatch in originalBatches)
-                {
-                    writer.WriteRecordBatch(originalBatch);
-                }
-                writer.WriteEnd();
-            }
-
-            // Should throw if trying to read without an ICompressionCodecFactory
-            stream.Position = 0;
-            var exception = Assert.Throws<Exception>(() =>
-            {
-                using var reader = new ArrowStreamReader(stream, leaveOpen: true);
-                reader.ReadNextRecordBatch();
-            });
-            Assert.Contains(nameof(ICompressionCodecFactory), exception.Message);
-
-            stream.Position = 0;
-            using (var reader = new ArrowStreamReader(stream, codecFactory))
-            {
-                foreach (var originalBatch in originalBatches)
-                {
-                    var newBatch = reader.ReadNextRecordBatch();
-                    ArrowReaderVerifier.CompareBatches(originalBatch, newBatch);
-                }
-            }
-        }
-
-        private static async Task TestRoundTripRecordBatchesAsync(
-            IReadOnlyList<RecordBatch> originalBatches, IpcOptions options, ICompressionCodecFactory codecFactory, MemoryAllocator writerAllocator = null)
-        {
-            using var stream = new MemoryStream();
-
-            using (var writer = new ArrowStreamWriter(stream, originalBatches[0].Schema, leaveOpen: true, options, writerAllocator))
-            {
-                foreach (var originalBatch in originalBatches)
-                {
-                    await writer.WriteRecordBatchAsync(originalBatch);
-                }
-                await writer.WriteEndAsync();
-            }
-
-            // Should throw if trying to read without an ICompressionCodecFactory
-            stream.Position = 0;
-            var exception = await Assert.ThrowsAsync<Exception>(async () =>
-            {
-                using var reader = new ArrowStreamReader(stream, leaveOpen: true);
-                await reader.ReadNextRecordBatchAsync();
-            });
-            Assert.Contains(nameof(ICompressionCodecFactory), exception.Message);
-
-            stream.Position = 0;
-            using (var reader = new ArrowStreamReader(stream, codecFactory))
-            {
-                foreach (var originalBatch in originalBatches)
-                {
-                    var newBatch = await reader.ReadNextRecordBatchAsync();
-                    ArrowReaderVerifier.CompareBatches(originalBatch, newBatch);
-                }
-            }
-        }
-    }
-}
-
diff --git a/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_lz4_compression.arrow b/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_lz4_compression.arrow
deleted file mode 100644
index f4ef4ac..0000000
--- a/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_lz4_compression.arrow
+++ /dev/null
Binary files differ
diff --git a/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_lz4_compression.arrow_stream b/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_lz4_compression.arrow_stream
deleted file mode 100644
index 50b2502..0000000
--- a/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_lz4_compression.arrow_stream
+++ /dev/null
Binary files differ
diff --git a/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_zstd_compression.arrow b/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_zstd_compression.arrow
deleted file mode 100644
index 2c943c5..0000000
--- a/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_zstd_compression.arrow
+++ /dev/null
Binary files differ
diff --git a/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_zstd_compression.arrow_stream b/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_zstd_compression.arrow_stream
deleted file mode 100644
index 8923e95..0000000
--- a/csharp/test/Apache.Arrow.Compression.Tests/Resources/ipc_zstd_compression.arrow_stream
+++ /dev/null
Binary files differ
diff --git a/csharp/test/Apache.Arrow.Compression.Tests/generate_resources.py b/csharp/test/Apache.Arrow.Compression.Tests/generate_resources.py
deleted file mode 100644
index c53a3bd..0000000
--- a/csharp/test/Apache.Arrow.Compression.Tests/generate_resources.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Generates files required for tests where it's not possible to generate
-them with dotnet Arrow.
-"""
-
-import pyarrow as pa
-from pathlib import Path
-
-
-def write_compressed_ipc_file(path: Path, compression: str, stream: bool = False):
-    schema = pa.schema([
-        pa.field('integers', pa.int32()),
-        pa.field('floats', pa.float32()),
-    ])
-
-    integers = pa.array(range(100), type=pa.int32())
-    floats = pa.array((x * 0.1 for x in range(100)), type=pa.float32())
-    batch = pa.record_batch([integers, floats], schema)
-
-    options = pa.ipc.IpcWriteOptions(compression=compression)
-
-    with pa.OSFile(path.as_posix(), 'wb') as sink:
-        if stream:
-            with pa.ipc.new_stream(sink, schema, options=options) as writer:
-                writer.write(batch)
-        else:
-            with pa.ipc.new_file(sink, schema, options=options) as writer:
-                writer.write(batch)
-
-
-if __name__ == '__main__':
-    resource_dir = Path(__file__).resolve().parent / 'Resources'
-
-    write_compressed_ipc_file(resource_dir / 'ipc_lz4_compression.arrow', 'lz4')
-    write_compressed_ipc_file(resource_dir / 'ipc_lz4_compression.arrow_stream', 'lz4', stream=True)
-    write_compressed_ipc_file(resource_dir / 'ipc_zstd_compression.arrow', 'zstd')
-    write_compressed_ipc_file(resource_dir / 'ipc_zstd_compression.arrow_stream', 'zstd', stream=True)
diff --git a/csharp/test/Apache.Arrow.Flight.IntegrationTest/Apache.Arrow.Flight.IntegrationTest.csproj b/csharp/test/Apache.Arrow.Flight.IntegrationTest/Apache.Arrow.Flight.IntegrationTest.csproj
deleted file mode 100644
index 3403062..0000000
--- a/csharp/test/Apache.Arrow.Flight.IntegrationTest/Apache.Arrow.Flight.IntegrationTest.csproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>net8.0</TargetFramework>
-    <RootNamespace>Apache.Arrow.Flight.IntegrationTest</RootNamespace>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
-    <PackageReference Include="System.Text.Json" Version="8.0.5" />
-    <ProjectReference Include="..\..\src\Apache.Arrow.Flight\Apache.Arrow.Flight.csproj" />
-    <ProjectReference Include="..\Apache.Arrow.Flight.TestWeb\Apache.Arrow.Flight.TestWeb.csproj" />
-    <ProjectReference Include="..\Apache.Arrow.IntegrationTest\Apache.Arrow.IntegrationTest.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/test/Apache.Arrow.Flight.IntegrationTest/FlightClientCommand.cs b/csharp/test/Apache.Arrow.Flight.IntegrationTest/FlightClientCommand.cs
deleted file mode 100644
index a26bcf0..0000000
--- a/csharp/test/Apache.Arrow.Flight.IntegrationTest/FlightClientCommand.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.IntegrationTest.Scenarios;
-
-namespace Apache.Arrow.Flight.IntegrationTest;
-
-public class FlightClientCommand
-{
-    private readonly int _port;
-    private readonly string _scenario;
-    private readonly FileInfo _jsonFileInfo;
-
-    public FlightClientCommand(int port, string scenario, FileInfo jsonFileInfo)
-    {
-        _port = port;
-        _scenario = scenario;
-        _jsonFileInfo = jsonFileInfo;
-    }
-
-    public async Task Execute()
-    {
-        IScenario scenario = _scenario switch
-        {
-            null => new JsonTestScenario(_jsonFileInfo),
-            "do_exchange:echo" => new DoExchangeEchoScenario(),
-            _ => throw new NotSupportedException($"Scenario '{_scenario}' is not supported"),
-        };
-
-        await scenario.RunClient(_port).ConfigureAwait(false);
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.IntegrationTest/FlightServerCommand.cs b/csharp/test/Apache.Arrow.Flight.IntegrationTest/FlightServerCommand.cs
deleted file mode 100644
index 38f14b7..0000000
--- a/csharp/test/Apache.Arrow.Flight.IntegrationTest/FlightServerCommand.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Net;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.IntegrationTest.Scenarios;
-using Apache.Arrow.Flight.Server;
-using Apache.Arrow.Flight.TestWeb;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Hosting.Server;
-using Microsoft.AspNetCore.Hosting.Server.Features;
-using Microsoft.AspNetCore.Server.Kestrel.Core;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Console;
-
-namespace Apache.Arrow.Flight.IntegrationTest;
-
-public class FlightServerCommand
-{
-    private readonly string _scenario;
-
-    public FlightServerCommand(string scenario)
-    {
-        _scenario = scenario;
-    }
-
-    public async Task Execute()
-    {
-        IScenario scenario = _scenario switch
-        {
-            null => null,
-            "do_exchange:echo" => new DoExchangeEchoScenario(),
-            _ => throw new NotSupportedException($"Scenario {_scenario} is not supported")
-        };
-
-        var host = Host.CreateDefaultBuilder()
-            .ConfigureWebHostDefaults(webBuilder =>
-            {
-                webBuilder
-                    .ConfigureKestrel(options =>
-                    {
-                        options.Listen(IPEndPoint.Parse("127.0.0.1:0"), l => l.Protocols = HttpProtocols.Http2);
-                    })
-                    .ConfigureServices(services =>
-                    {
-                        if (scenario == null)
-                        {
-                            // Use the TestFlightServer for JSON based integration tests
-                            services.AddGrpc().AddFlightServer<TestFlightServer>();
-                            services.AddSingleton(new FlightStore());
-                        }
-                        else
-                        {
-                            // Use a scenario-specific server implementation
-                            services.AddGrpc().Services.AddScoped<FlightServer>(_ => scenario.MakeServer());
-                        }
-
-                        // The integration tests rely on the port being written to the first line of stdout,
-                        // so send all logging to stderr.
-                        services.Configure<ConsoleLoggerOptions>(
-                            o => o.LogToStandardErrorThreshold = LogLevel.Debug);
-
-                    })
-                    .UseStartup<Startup>();
-            })
-            .Build();
-
-        await host.StartAsync().ConfigureAwait(false);
-
-        var addresses = host.Services.GetService<IServer>().Features.Get<IServerAddressesFeature>().Addresses;
-        foreach (var address in addresses)
-        {
-            Console.WriteLine($"Server listening on {address}");
-        }
-
-        await host.WaitForShutdownAsync().ConfigureAwait(false);
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.IntegrationTest/GrpcResolver.cs b/csharp/test/Apache.Arrow.Flight.IntegrationTest/GrpcResolver.cs
deleted file mode 100644
index 44b1075..0000000
--- a/csharp/test/Apache.Arrow.Flight.IntegrationTest/GrpcResolver.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Grpc.Net.Client.Balancer;
-
-namespace Apache.Arrow.Flight.IntegrationTest;
-
-/// <summary>
-/// The Grpc.Net.Client library doesn't know how to handle the "grpc+tcp" scheme used by Arrow Flight.
-/// This ResolverFactory passes these through to the standard Static Resolver used for the http scheme.
-/// </summary>
-public class GrpcTcpResolverFactory : ResolverFactory
-{
-    public override string Name => "grpc+tcp";
-
-    public override Resolver Create(ResolverOptions options)
-    {
-        return new StaticResolverFactory(
-                uri => new[] { new BalancerAddress(options.Address.Host, options.Address.Port) })
-            .Create(options);
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.IntegrationTest/IScenario.cs b/csharp/test/Apache.Arrow.Flight.IntegrationTest/IScenario.cs
deleted file mode 100644
index 41ed631..0000000
--- a/csharp/test/Apache.Arrow.Flight.IntegrationTest/IScenario.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Server;
-
-namespace Apache.Arrow.Flight.IntegrationTest;
-
-/// <summary>
-/// A Flight integration test scenario
-/// </summary>
-internal interface IScenario
-{
-    /// <summary>
-    /// Create a FlightServer instance to run the scenario
-    /// </summary>
-    FlightServer MakeServer();
-
-    /// <summary>
-    /// Run the scenario using a Flight client
-    /// </summary>
-    Task RunClient(int serverPort);
-}
diff --git a/csharp/test/Apache.Arrow.Flight.IntegrationTest/Program.cs b/csharp/test/Apache.Arrow.Flight.IntegrationTest/Program.cs
deleted file mode 100644
index 24d39de..0000000
--- a/csharp/test/Apache.Arrow.Flight.IntegrationTest/Program.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.CommandLine;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.Flight.IntegrationTest;
-
-public static class Program
-{
-    public static async Task<int> Main(string[] args)
-    {
-        var portOption = new Option<int>(
-            new[] { "--port", "-p" },
-            description: "Port the Flight server is listening on");
-        var scenarioOption = new Option<string>(
-            new[] { "--scenario", "-s" },
-            "The name of the scenario to run");
-        var pathOption = new Option<FileInfo>(
-            new[] { "--path", "-j" },
-            "Path to a JSON file of test data");
-
-        var rootCommand = new RootCommand(
-            "Integration test application for Apache.Arrow .NET Flight.");
-
-        var clientCommand = new Command("client", "Run the Flight client")
-        {
-            portOption,
-            scenarioOption,
-            pathOption,
-        };
-        rootCommand.AddCommand(clientCommand);
-
-        clientCommand.SetHandler(async (port, scenario, jsonFile) =>
-        {
-            var command = new FlightClientCommand(port, scenario, jsonFile);
-            await command.Execute().ConfigureAwait(false);
-        }, portOption, scenarioOption, pathOption);
-
-        var serverCommand = new Command("server", "Run the Flight server")
-        {
-            scenarioOption,
-        };
-        rootCommand.AddCommand(serverCommand);
-
-        serverCommand.SetHandler(async scenario =>
-        {
-            var command = new FlightServerCommand(scenario);
-            await command.Execute().ConfigureAwait(false);
-        }, scenarioOption);
-
-        return await rootCommand.InvokeAsync(args).ConfigureAwait(false);
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.IntegrationTest/Scenarios/DoExchangeEchoScenario.cs b/csharp/test/Apache.Arrow.Flight.IntegrationTest/Scenarios/DoExchangeEchoScenario.cs
deleted file mode 100644
index 6e9b269..0000000
--- a/csharp/test/Apache.Arrow.Flight.IntegrationTest/Scenarios/DoExchangeEchoScenario.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Client;
-using Apache.Arrow.Flight.Server;
-using Google.Protobuf;
-using Grpc.Core;
-using Grpc.Net.Client;
-using Grpc.Net.Client.Balancer;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Apache.Arrow.Flight.IntegrationTest.Scenarios;
-
-internal class DoExchangeServer : FlightServer
-{
-    public override async Task DoExchange(
-        FlightServerRecordBatchStreamReader requestStream,
-        FlightServerRecordBatchStreamWriter responseStream,
-        ServerCallContext context)
-    {
-        var descriptor = await requestStream.FlightDescriptor;
-        var command = descriptor.Command?.ToStringUtf8();
-        if (command != "echo")
-        {
-            throw new Exception($"Unsupported command: '{command}'");
-        }
-
-        while (await requestStream.MoveNext())
-        {
-            await responseStream.WriteAsync(
-                requestStream.Current, requestStream.ApplicationMetadata.FirstOrDefault());
-        }
-    }
-}
-
-internal class DoExchangeEchoScenario : IScenario
-{
-    public FlightServer MakeServer() => new DoExchangeServer();
-
-    public async Task RunClient(int serverPort)
-    {
-        var services = new ServiceCollection();
-        services.AddSingleton<ResolverFactory>(new GrpcTcpResolverFactory());
-        var serviceProvider = services.BuildServiceProvider();
-
-        var address = $"grpc+tcp://localhost:{serverPort}";
-        using var channel = GrpcChannel.ForAddress(
-            address,
-            new GrpcChannelOptions
-            {
-                ServiceProvider = serviceProvider,
-                Credentials = ChannelCredentials.Insecure
-            });
-
-        var client = new FlightClient(channel);
-        var descriptor = FlightDescriptor.CreateCommandDescriptor("echo");
-        using var exchange = client.DoExchange(descriptor);
-
-        using var writer = exchange.RequestStream;
-        using var reader = exchange.ResponseStream;
-
-        for (var batchIdx = 0; batchIdx < 4; batchIdx++)
-        {
-            using var batch = new RecordBatch.Builder()
-                .Append(
-                    "x",
-                    nullable: false,
-                    array: new Int32Array.Builder().AppendRange(Enumerable.Range(batchIdx, 10)).Build())
-                .Build();
-
-            var expectedMetadata = $"{batchIdx}";
-            var writeMetadata = batchIdx % 2 == 0;
-            if (writeMetadata)
-            {
-                await writer.WriteAsync(batch, ByteString.CopyFromUtf8(expectedMetadata));
-            }
-            else
-            {
-                await writer.WriteAsync(batch);
-            }
-
-            if (!await reader.MoveNext(CancellationToken.None))
-            {
-                throw new Exception("Unexpected end of read stream");
-            }
-
-            var readMetadata = reader.ApplicationMetadata?.FirstOrDefault()?.ToStringUtf8();
-
-            if (writeMetadata && readMetadata != expectedMetadata)
-            {
-                throw new Exception($"Expected metadata '{expectedMetadata}' but received '{readMetadata}'");
-            }
-            if (!writeMetadata && readMetadata != null)
-            {
-                throw new Exception($"Unexpected metadata received: '{readMetadata}'");
-            }
-        }
-
-        await writer.CompleteAsync();
-
-        if (await reader.MoveNext(CancellationToken.None))
-        {
-            throw new Exception("Expected end of read stream");
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.IntegrationTest/Scenarios/JsonTestScenario.cs b/csharp/test/Apache.Arrow.Flight.IntegrationTest/Scenarios/JsonTestScenario.cs
deleted file mode 100644
index 7847510..0000000
--- a/csharp/test/Apache.Arrow.Flight.IntegrationTest/Scenarios/JsonTestScenario.cs
+++ /dev/null
@@ -1,177 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Client;
-using Apache.Arrow.Flight.Server;
-using Apache.Arrow.IntegrationTest;
-using Apache.Arrow.Tests;
-using Apache.Arrow.Types;
-using Google.Protobuf;
-using Grpc.Net.Client;
-using Grpc.Core;
-using Grpc.Net.Client.Balancer;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Apache.Arrow.Flight.IntegrationTest.Scenarios;
-
-/// <summary>
-/// A test scenario defined using a JSON data file
-/// </summary>
-internal class JsonTestScenario : IScenario
-{
-    private readonly FileInfo _jsonFile;
-    private readonly ServiceProvider _serviceProvider;
-
-    public JsonTestScenario(FileInfo jsonFile)
-    {
-        if (!(jsonFile?.Exists ?? false))
-        {
-            throw new Exception($"Invalid JSON file path '{jsonFile?.FullName}'");
-        }
-
-        _jsonFile = jsonFile;
-
-        var services = new ServiceCollection();
-        services.AddSingleton<ResolverFactory>(new GrpcTcpResolverFactory());
-        _serviceProvider = services.BuildServiceProvider();
-    }
-
-    public FlightServer MakeServer()
-    {
-        throw new NotImplementedException();
-    }
-
-    public async Task RunClient(int serverPort)
-    {
-        var address = $"grpc+tcp://localhost:{serverPort}";
-        using var channel = GrpcChannel.ForAddress(
-            address,
-            new GrpcChannelOptions
-            {
-                ServiceProvider = _serviceProvider,
-                Credentials = ChannelCredentials.Insecure
-            });
-        var client = new FlightClient(channel);
-
-        var descriptor = FlightDescriptor.CreatePathDescriptor(_jsonFile.FullName);
-
-        var jsonFile = await JsonFile.ParseAsync(_jsonFile).ConfigureAwait(false);
-        var schema = jsonFile.GetSchemaAndDictionaries(out Func<DictionaryType, IArrowArray> dictionaries);
-        var batches = jsonFile.Batches.Select(batch => batch.ToArrow(schema, dictionaries)).ToArray();
-
-        // 1. Put the data to the server.
-        await UploadBatches(client, descriptor, schema, batches).ConfigureAwait(false);
-
-        // 2. Get the ticket for the data.
-        var info = await client.GetInfo(descriptor).ConfigureAwait(false);
-        if (info.Endpoints.Count == 0)
-        {
-            throw new Exception("No endpoints received");
-        }
-
-        // 3. Stream data from the server, comparing individual batches.
-        foreach (var endpoint in info.Endpoints)
-        {
-            var locations = endpoint.Locations.ToArray();
-            if (locations.Length == 0)
-            {
-                // Can read with existing client
-                await ConsumeFlightLocation(client, endpoint.Ticket, batches).ConfigureAwait(false);
-            }
-            else
-            {
-                foreach (var location in locations)
-                {
-                    using var readChannel = GrpcChannel.ForAddress(
-                        location.Uri,
-                        new GrpcChannelOptions
-                        {
-                            ServiceProvider = _serviceProvider,
-                            Credentials = ChannelCredentials.Insecure
-                        });
-                    var readClient = new FlightClient(readChannel);
-                    await ConsumeFlightLocation(readClient, endpoint.Ticket, batches).ConfigureAwait(false);
-                }
-            }
-        }
-    }
-
-    private static async Task UploadBatches(
-        FlightClient client, FlightDescriptor descriptor, Schema schema, RecordBatch[] batches)
-    {
-        using var putCall = await client.StartPut(descriptor, schema);
-        using var writer = putCall.RequestStream;
-
-        try
-        {
-            var counter = 0;
-            foreach (var batch in batches)
-            {
-                var metadata = $"{counter}";
-
-                await writer.WriteAsync(batch, ByteString.CopyFromUtf8(metadata)).ConfigureAwait(false);
-
-                // Verify server has acknowledged the write request
-                await putCall.ResponseStream.MoveNext().ConfigureAwait(false);
-                var responseString = putCall.ResponseStream.Current.ApplicationMetadata.ToStringUtf8();
-
-                if (responseString != metadata)
-                {
-                    throw new Exception($"Response metadata '{responseString}' does not match expected metadata '{metadata}'");
-                }
-
-                counter++;
-            }
-        }
-        finally
-        {
-            await writer.CompleteAsync().ConfigureAwait(false);
-        }
-
-        // Drain the response stream to ensure the server has stored the data
-        var hasMore = await putCall.ResponseStream.MoveNext().ConfigureAwait(false);
-        if (hasMore)
-        {
-            throw new Exception("Expected to have reached the end of the response stream");
-        }
-    }
-
-    private static async Task ConsumeFlightLocation(FlightClient client, FlightTicket ticket, RecordBatch[] batches)
-    {
-        using var readStream = client.GetStream(ticket);
-        var counter = 0;
-        foreach (var originalBatch in batches)
-        {
-            if (!await readStream.ResponseStream.MoveNext().ConfigureAwait(false))
-            {
-                throw new Exception($"Expected {batches.Length} batches but received {counter}");
-            }
-
-            var batch = readStream.ResponseStream.Current;
-            ArrowReaderVerifier.CompareBatches(originalBatch, batch, strictCompare: false);
-
-            counter++;
-        }
-
-        if (await readStream.ResponseStream.MoveNext().ConfigureAwait(false))
-        {
-            throw new Exception($"Expected to reach the end of the response stream after {batches.Length} batches");
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.IntegrationTest/Startup.cs b/csharp/test/Apache.Arrow.Flight.IntegrationTest/Startup.cs
deleted file mode 100644
index 7e29d19..0000000
--- a/csharp/test/Apache.Arrow.Flight.IntegrationTest/Startup.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Hosting;
-
-namespace Apache.Arrow.Flight.IntegrationTest
-{
-    public class Startup
-    {
-        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
-        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
-        {
-            if (env.IsDevelopment())
-            {
-                app.UseDeveloperExceptionPage();
-            }
-
-            app.UseRouting();
-
-            app.UseEndpoints(endpoints =>
-            {
-                endpoints.MapFlightEndpoint();
-
-                endpoints.MapGet("/", async context =>
-                {
-                    await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
-                });
-            });
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.Sql.Tests/Apache.Arrow.Flight.Sql.Tests.csproj b/csharp/test/Apache.Arrow.Flight.Sql.Tests/Apache.Arrow.Flight.Sql.Tests.csproj
deleted file mode 100644
index 39cae70..0000000
--- a/csharp/test/Apache.Arrow.Flight.Sql.Tests/Apache.Arrow.Flight.Sql.Tests.csproj
+++ /dev/null
@@ -1,20 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-    <PropertyGroup>
-      <TargetFramework>net8.0</TargetFramework>
-      <IsPackable>false</IsPackable>
-    </PropertyGroup>
-
-    <ItemGroup>
-      <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
-      <PackageReference Include="xunit" Version="2.9.3" />
-      <PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
-      <PackageReference Include="coverlet.collector" Version="6.0.4" />
-    </ItemGroup>
-
-    <ItemGroup>
-      <ProjectReference Include="..\..\src\Apache.Arrow.Flight.Sql\Apache.Arrow.Flight.Sql.csproj" />
-      <ProjectReference Include="..\Apache.Arrow.Flight.Tests\Apache.Arrow.Flight.Tests.csproj" />
-      <ProjectReference Include="..\Apache.Arrow.Flight.TestWeb\Apache.Arrow.Flight.TestWeb.csproj" />
-    </ItemGroup>
-</Project>
diff --git a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlClientTests.cs b/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlClientTests.cs
deleted file mode 100644
index 17a5e6f..0000000
--- a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlClientTests.cs
+++ /dev/null
@@ -1,868 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Client;
-using Apache.Arrow.Flight.Sql.Client;
-using Apache.Arrow.Flight.TestWeb;
-using Apache.Arrow.Types;
-using Arrow.Flight.Protocol.Sql;
-using Google.Protobuf;
-using Grpc.Core.Utils;
-using Xunit;
-
-namespace Apache.Arrow.Flight.Sql.Tests;
-
-public class FlightSqlClientTests : IDisposable
-{
-    readonly TestFlightSqlWebFactory _testWebFactory;
-    readonly FlightStore _flightStore;
-    private readonly FlightSqlClient _flightSqlClient;
-    private readonly FlightSqlTestUtils _testUtils;
-
-    public FlightSqlClientTests()
-    {
-        _flightStore = new FlightStore();
-        _testWebFactory = new TestFlightSqlWebFactory(_flightStore);
-        FlightClient flightClient = new(_testWebFactory.GetChannel());
-        _flightSqlClient = new FlightSqlClient(flightClient);
-
-        _testUtils = new FlightSqlTestUtils(_testWebFactory, _flightStore);
-    }
-
-    #region Transactions
-
-    [Fact]
-    public async Task CommitTransactionAsync()
-    {
-        // Arrange
-        string transactionId = "sample-transaction-id";
-        var transaction = new Transaction(transactionId);
-
-        // Act
-        var streamCall = _flightSqlClient.CommitAsync(transaction);
-        var result = await streamCall.ResponseStream.ToListAsync();
-
-        // Assert
-        Assert.NotNull(result);
-        Assert.Equal(transaction.TransactionId, result.FirstOrDefault()?.Body);
-    }
-
-    [Fact]
-    public async Task BeginTransactionAsync()
-    {
-        // Arrange
-        string expectedTransactionId = "sample-transaction-id";
-
-        // Act
-        var transaction = await _flightSqlClient.BeginTransactionAsync();
-
-        // Assert
-        Assert.NotEqual(Transaction.NoTransaction, transaction);
-        Assert.Equal(ByteString.CopyFromUtf8(expectedTransactionId), transaction.TransactionId);
-    }
-
-    [Fact]
-    public async Task RollbackTransactionAsync()
-    {
-        // Arrange
-        string transactionId = "sample-transaction-id";
-        var transaction = new Transaction(transactionId);
-
-        // Act
-        var streamCall = _flightSqlClient.RollbackAsync(transaction);
-        var result = await streamCall.ResponseStream.ToListAsync();
-
-        // Assert
-        Assert.Equal(result.FirstOrDefault()?.Body, transaction.TransactionId);
-    }
-
-    #endregion
-
-    #region PreparedStatement
-
-    [Theory]
-    [InlineData("sample-transaction-id", true)]
-    [InlineData(null, false)]
-    public async Task PreparedAsync(string transactionId, bool expectTransaction)
-    {
-        // Arrange
-        string query = "INSERT INTO users (id, name) VALUES (1, 'John Doe')";
-        var transaction = string.IsNullOrEmpty(transactionId)
-            ? Transaction.NoTransaction
-            : new Transaction(transactionId);
-
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-
-        // Create a sample schema for the dataset and parameters
-        var schema = new Schema.Builder()
-            .Field(f => f.Name("id").DataType(Int32Type.Default))
-            .Field(f => f.Name("name").DataType(StringType.Default))
-            .Build();
-
-        var recordBatch = new RecordBatch(schema, new Array[]
-        {
-            new Int32Array.Builder().Append(1).Build(),
-            new StringArray.Builder().Append("John Doe").Build()
-        }, 1);
-
-        var flightHolder = new FlightHolder(flightDescriptor, schema, _testWebFactory.GetAddress());
-        flightHolder.AddBatch(new RecordBatchWithMetadata(recordBatch));
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        var datasetSchemaBytes = SchemaExtensions.SerializeSchema(schema);
-        var parameterSchemaBytes = SchemaExtensions.SerializeSchema(schema);
-
-        var preparedStatementResponse = new ActionCreatePreparedStatementResult
-        {
-            PreparedStatementHandle = ByteString.CopyFromUtf8("prepared-handle"),
-            DatasetSchema = ByteString.CopyFrom(datasetSchemaBytes),
-            ParameterSchema = ByteString.CopyFrom(parameterSchemaBytes)
-        };
-
-        // Act
-        PreparedStatement preparedStatement;
-        if (expectTransaction)
-        {
-             preparedStatement = await _flightSqlClient.PrepareAsync(query, transaction);
-        }
-        else
-        {
-            preparedStatement = await _flightSqlClient.PrepareAsync(query);
-        }
-        var deserializedDatasetSchema =
-            SchemaExtensions.DeserializeSchema(preparedStatementResponse.DatasetSchema.ToByteArray());
-        var deserializedParameterSchema =
-            SchemaExtensions.DeserializeSchema(preparedStatementResponse.ParameterSchema.ToByteArray());
-
-        // Assert
-        Assert.NotNull(preparedStatement);
-        Assert.NotNull(deserializedDatasetSchema);
-        Assert.NotNull(deserializedParameterSchema);
-        CompareSchemas(schema, deserializedDatasetSchema);
-        CompareSchemas(schema, deserializedParameterSchema);
-    }
-
-    #endregion
-
-    [Fact]
-    public async Task ExecuteUpdateAsync()
-    {
-        // Arrange
-        string query = "UPDATE test_table SET column1 = 'value'";
-        var transaction = new Transaction("sample-transaction-id");
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-
-        var schema = new Schema.Builder()
-            .Field(f => f.Name("id").DataType(Int32Type.Default))
-            .Field(f => f.Name("name").DataType(StringType.Default))
-            .Build();
-
-        var recordBatch = new RecordBatch(schema, new IArrowArray[]
-        {
-            new Int32Array.Builder().AppendRange([1, 2, 3, 4, 5]).Build(),
-            new StringArray.Builder().AppendRange(["John Doe", "Jane Doe", "Alice", "Bob", "Charlie"]).Build()
-        }, 5);
-
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema, _testWebFactory.GetAddress());
-        flightHolder.AddBatch(new RecordBatchWithMetadata(recordBatch));
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        long affectedRows = await _flightSqlClient.ExecuteUpdateAsync(query, transaction);
-
-        // Assert
-        Assert.Equal(5, affectedRows);
-    }
-
-    [Fact]
-    public async Task ExecuteAsync()
-    {
-        // Arrange
-        string query = "SELECT * FROM test_table";
-        var transaction = new Transaction("sample-transaction-id");
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema, _testWebFactory.GetAddress());
-        flightHolder.AddBatch(new RecordBatchWithMetadata(recordBatch));
-
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var flightInfo = await _flightSqlClient.ExecuteAsync(query, transaction);
-
-        // Assert
-        Assert.NotNull(flightInfo);
-        Assert.Single(flightInfo.Endpoints);
-    }
-
-    [Fact]
-    public async Task ExecuteAsync_ShouldReturnFlightInfo_WhenValidInputsAreProvided()
-    {
-        // Arrange
-        string query = "SELECT * FROM test_table";
-        var transaction = new Transaction("sample-transaction-id");
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var flightInfo = await _flightSqlClient.ExecuteAsync(query, transaction);
-
-        // Assert
-        Assert.NotNull(flightInfo);
-        Assert.IsType<FlightInfo>(flightInfo);
-    }
-
-    [Fact]
-    public async Task ExecuteAsync_ShouldThrowArgumentException_WhenQueryIsEmpty()
-    {
-        // Arrange
-        string emptyQuery = string.Empty;
-        var transaction = new Transaction("sample-transaction-id");
-
-        // Act & Assert
-        await Assert.ThrowsAsync<ArgumentException>(async () =>
-            await _flightSqlClient.ExecuteAsync(emptyQuery, transaction));
-    }
-
-    [Fact]
-    public async Task ExecuteAsync_ShouldReturnFlightInfo_WhenTransactionIsNoTransaction()
-    {
-        // Arrange
-        string query = "SELECT * FROM test_table";
-        var transaction = Transaction.NoTransaction;
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var flightInfo = await _flightSqlClient.ExecuteAsync(query, transaction);
-
-        // Assert
-        Assert.NotNull(flightInfo);
-        Assert.IsType<FlightInfo>(flightInfo);
-    }
-
-    [Fact]
-    public async Task GetFlightInfoAsync()
-    {
-        // Arrange
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-        // Act
-        var flightInfo = await _flightSqlClient.GetFlightInfoAsync(flightDescriptor);
-
-        // Assert
-        Assert.NotNull(flightInfo);
-    }
-
-    [Fact]
-    public async Task GetExecuteSchemaAsync()
-    {
-        // Arrange
-        string query = "SELECT * FROM test_table";
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        Schema resultSchema =
-            await _flightSqlClient.GetExecuteSchemaAsync(query, new Transaction("sample-transaction-id"));
-
-        // Assert
-        Assert.NotNull(resultSchema);
-        Assert.Equal(recordBatch.Schema.FieldsList.Count, resultSchema.FieldsList.Count);
-        CompareSchemas(resultSchema, recordBatch.Schema);
-    }
-
-    [Fact]
-    public async Task GetCatalogsAsync()
-    {
-        // Arrange
-        var options = new FlightCallOptions();
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var result = await _flightSqlClient.GetCatalogsAsync(options);
-
-        // Assert
-        Assert.NotNull(result);
-        Assert.Equal(flightHolder.GetFlightInfo().Endpoints.Count, result.Endpoints.Count);
-        Assert.Equal(flightDescriptor, result.Descriptor);
-    }
-
-    [Fact]
-    public async Task GetSchemaAsync()
-    {
-        // Arrange
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var result = await _flightSqlClient.GetSchemaAsync(flightDescriptor);
-
-        // Assert
-        Assert.NotNull(result);
-        Assert.Equal(recordBatch.Schema.FieldsList.Count, result.FieldsList.Count);
-        CompareSchemas(result, recordBatch.Schema);
-    }
-
-    [Fact]
-    public async Task GetDbSchemasAsync()
-    {
-        // Arrange
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-        string catalog = "test-catalog";
-        string dbSchemaFilterPattern = "test-schema-pattern";
-
-        // Act
-        var result = await _flightSqlClient.GetDbSchemasAsync(catalog, dbSchemaFilterPattern);
-
-        // Assert
-        Assert.NotNull(result);
-        var expectedFlightInfo = flightHolder.GetFlightInfo();
-        Assert.Equal(recordBatch.Schema.FieldsList.Count, result.Schema.FieldsList.Count);
-        Assert.Equal(expectedFlightInfo.Descriptor.Command, result.Descriptor.Command);
-        Assert.Equal(expectedFlightInfo.Descriptor.Type, result.Descriptor.Type);
-        Assert.Equal(expectedFlightInfo.Schema.FieldsList.Count, result.Schema.FieldsList.Count);
-        Assert.Equal(expectedFlightInfo.Endpoints.Count, result.Endpoints.Count);
-
-        for (int i = 0; i < expectedFlightInfo.Schema.FieldsList.Count; i++)
-        {
-            var expectedField = expectedFlightInfo.Schema.FieldsList[i];
-            var actualField = result.Schema.FieldsList[i];
-
-            Assert.Equal(expectedField.Name, actualField.Name);
-            Assert.Equal(expectedField.DataType, actualField.DataType);
-            Assert.Equal(expectedField.IsNullable, actualField.IsNullable);
-            Assert.Equal(expectedField.Metadata?.Count ?? 0, actualField.Metadata?.Count ?? 0);
-        }
-
-        for (int i = 0; i < expectedFlightInfo.Endpoints.Count; i++)
-        {
-            var expectedEndpoint = expectedFlightInfo.Endpoints[i];
-            var actualEndpoint = result.Endpoints[i];
-
-            Assert.Equal(expectedEndpoint.Ticket, actualEndpoint.Ticket);
-            Assert.Equal(expectedEndpoint.Locations.Count(), actualEndpoint.Locations.Count());
-        }
-    }
-
-    [Fact]
-    public async Task GetPrimaryKeysAsync()
-    {
-        // Arrange
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var tableRef = new TableRef("test-catalog", "test-schema", "test-table");
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var result = await _flightSqlClient.GetPrimaryKeysAsync(tableRef);
-
-        // Assert
-        Assert.NotNull(result);
-        var expectedFlightInfo = flightHolder.GetFlightInfo();
-        Assert.Equal(expectedFlightInfo.Descriptor.Command, result.Descriptor.Command);
-        Assert.Equal(expectedFlightInfo.Descriptor.Type, result.Descriptor.Type);
-        Assert.Equal(expectedFlightInfo.Schema.FieldsList.Count, result.Schema.FieldsList.Count);
-
-        for (int i = 0; i < expectedFlightInfo.Schema.FieldsList.Count; i++)
-        {
-            var expectedField = expectedFlightInfo.Schema.FieldsList[i];
-            var actualField = result.Schema.FieldsList[i];
-            Assert.Equal(expectedField.Name, actualField.Name);
-            Assert.Equal(expectedField.DataType, actualField.DataType);
-            Assert.Equal(expectedField.IsNullable, actualField.IsNullable);
-            Assert.Equal(expectedField.Metadata?.Count ?? 0, actualField.Metadata?.Count ?? 0);
-        }
-
-        Assert.Equal(expectedFlightInfo.Endpoints.Count, result.Endpoints.Count);
-
-        for (int i = 0; i < expectedFlightInfo.Endpoints.Count; i++)
-        {
-            var expectedEndpoint = expectedFlightInfo.Endpoints[i];
-            var actualEndpoint = result.Endpoints[i];
-
-            Assert.Equal(expectedEndpoint.Ticket, actualEndpoint.Ticket);
-            Assert.Equal(expectedEndpoint.Locations.Count(), actualEndpoint.Locations.Count());
-        }
-    }
-
-    [Fact]
-    public async Task GetTablesAsync()
-    {
-        // Arrange
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        string catalog = "sample_catalog";
-        string dbSchemaFilterPattern = "sample_schema";
-        string tableFilterPattern = "sample_table";
-        bool includeSchema = true;
-        var tableTypes = new List<string> { "BASE TABLE" };
-
-        // Act
-        var result = await _flightSqlClient.GetTablesAsync(catalog, dbSchemaFilterPattern, tableFilterPattern,
-            includeSchema, tableTypes);
-
-        // Assert
-        Assert.NotNull(result);
-        Assert.Single(result);
-
-        var expectedFlightInfo = flightHolder.GetFlightInfo();
-        var flightInfo = result.First();
-        Assert.Equal(expectedFlightInfo.Descriptor.Command, flightInfo.Descriptor.Command);
-        Assert.Equal(expectedFlightInfo.Descriptor.Type, flightInfo.Descriptor.Type);
-        Assert.Equal(expectedFlightInfo.Schema.FieldsList.Count, flightInfo.Schema.FieldsList.Count);
-        for (int i = 0; i < expectedFlightInfo.Schema.FieldsList.Count; i++)
-        {
-            var expectedField = expectedFlightInfo.Schema.FieldsList[i];
-            var actualField = flightInfo.Schema.FieldsList[i];
-            Assert.Equal(expectedField.Name, actualField.Name);
-            Assert.Equal(expectedField.DataType, actualField.DataType);
-            Assert.Equal(expectedField.IsNullable, actualField.IsNullable);
-        }
-
-        Assert.Equal(expectedFlightInfo.Endpoints.Count, flightInfo.Endpoints.Count);
-    }
-
-    [Fact]
-    public async Task GetCatalogsSchemaAsync()
-    {
-        // Arrange
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var schema = await _flightSqlClient.GetCatalogsSchemaAsync();
-
-        // Assert
-        Assert.NotNull(schema);
-        var expectedFlightInfo = flightHolder.GetFlightInfo();
-        for (int i = 0; i < expectedFlightInfo.Schema.FieldsList.Count; i++)
-        {
-            var expectedField = expectedFlightInfo.Schema.FieldsList[i];
-            var actualField = schema.FieldsList[i];
-            Assert.Equal(expectedField.Name, actualField.Name);
-            Assert.Equal(expectedField.DataType, actualField.DataType);
-            Assert.Equal(expectedField.IsNullable, actualField.IsNullable);
-        }
-    }
-
-    [Fact]
-    public async Task GetDbSchemasSchemaAsync()
-    {
-        // Arrange
-        var options = new FlightCallOptions();
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var schema = await _flightSqlClient.GetDbSchemasSchemaAsync(options);
-
-        // Assert
-        Assert.NotNull(schema);
-        for (int i = 0; i < schema.FieldsList.Count; i++)
-        {
-            var expectedField = schema.FieldsList[i];
-            var actualField = schema.FieldsList[i];
-            Assert.Equal(expectedField.Name, actualField.Name);
-            Assert.Equal(expectedField.DataType, actualField.DataType);
-            Assert.Equal(expectedField.IsNullable, actualField.IsNullable);
-        }
-    }
-
-    [Fact]
-    public async Task DoPutAsync()
-    {
-        // Arrange
-        var schema = new Schema.Builder()
-            .Field(f => f.Name("DATA_TYPE_ID").DataType(Int32Type.Default).Nullable(false))
-            .Field(f => f.Name("TYPE_NAME").DataType(StringType.Default).Nullable(false))
-            .Field(f => f.Name("PRECISION").DataType(Int32Type.Default).Nullable(false))
-            .Field(f => f.Name("LITERAL_PREFIX").DataType(StringType.Default).Nullable(false))
-            .Field(f => f.Name("COLUMN_SIZE").DataType(Int32Type.Default).Nullable(false))
-            .Build();
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-
-        int[] dataTypeIds = { 1, 2, 3 };
-        string[] typeNames = ["INTEGER", "VARCHAR", "BOOLEAN"];
-        int[] precisions = { 32, 255, 1 };
-        string[] literalPrefixes = ["N'", "'", "b'"];
-        int[] columnSizes = [10, 255, 1];
-
-        var recordBatch = new RecordBatch(schema,
-        [
-            new Int32Array.Builder().AppendRange(dataTypeIds).Build(),
-            new StringArray.Builder().AppendRange(typeNames).Build(),
-            new Int32Array.Builder().AppendRange(precisions).Build(),
-            new StringArray.Builder().AppendRange(literalPrefixes).Build(),
-            new Int32Array.Builder().AppendRange(columnSizes).Build()
-        ], 5);
-        Assert.NotNull(recordBatch);
-        Assert.Equal(5, recordBatch.Length);
-        var flightHolder = new FlightHolder(flightDescriptor, schema, _testWebFactory.GetAddress());
-        flightHolder.AddBatch(new RecordBatchWithMetadata(_testUtils.CreateTestBatch(0, 100)));
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        var expectedBatch = _testUtils.CreateTestBatch(0, 100);
-
-        // Act
-        var result = await _flightSqlClient.DoPutAsync(flightDescriptor, expectedBatch);
-
-        // Assert
-        Assert.NotNull(result);
-    }
-
-    [Fact]
-    public async Task GetExportedKeysAsync()
-    {
-        // Arrange
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var tableRef = new TableRef("test-catalog", "test-schema", "test-table");
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var flightInfo = await _flightSqlClient.GetExportedKeysAsync(tableRef);
-
-        // Assert
-        Assert.NotNull(flightInfo);
-        Assert.Equal("test", flightInfo.Descriptor.Command.ToStringUtf8());
-    }
-
-    [Fact]
-    public async Task GetExportedKeysSchemaAsync()
-    {
-        // Arrange
-        var options = new FlightCallOptions();
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var tableRef = new TableRef("test-catalog", "test-schema", "test-table");
-        var schema = await _flightSqlClient.GetExportedKeysSchemaAsync(tableRef);
-
-        // Assert
-        Assert.NotNull(schema);
-        Assert.True(schema.FieldsList.Count > 0, "Schema should contain fields.");
-        Assert.Equal("test", schema.FieldsList.First().Name);
-    }
-
-    [Fact]
-    public async Task GetImportedKeysAsync()
-    {
-        // Arrange
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var flightInfo =
-            await _flightSqlClient.GetImportedKeysAsync(new TableRef("test-catalog", "test-schema", "test-table"));
-
-        // Assert
-        Assert.NotNull(flightInfo);
-        for (int i = 0; i < recordBatch.Schema.FieldsList.Count; i++)
-        {
-            var expectedField = recordBatch.Schema.FieldsList[i];
-            var actualField = flightInfo.Schema.FieldsList[i];
-            Assert.Equal(expectedField.Name, actualField.Name);
-            Assert.Equal(expectedField.DataType, actualField.DataType);
-            Assert.Equal(expectedField.IsNullable, actualField.IsNullable);
-        }
-    }
-
-    [Fact]
-    public async Task GetImportedKeysSchemaAsync()
-    {
-        // Arrange
-        var options = new FlightCallOptions();
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var schema = await _flightSqlClient.GetImportedKeysSchemaAsync(options);
-
-        // Assert
-        var expectedSchema = recordBatch.Schema;
-        Assert.NotNull(schema);
-        Assert.Equal(expectedSchema.FieldsList.Count, schema.FieldsList.Count);
-        CompareSchemas(expectedSchema, schema);
-    }
-
-    [Fact]
-    public async Task GetCrossReferenceAsync()
-    {
-        // Arrange
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema, _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-        var pkTableRef = new TableRef("PKCatalog", "PKSchema", "PKTable");
-        var fkTableRef = new TableRef("FKCatalog", "FKSchema", "FKTable");
-
-        // Act
-        var flightInfo = await _flightSqlClient.GetCrossReferenceAsync(pkTableRef, fkTableRef);
-
-        // Assert
-        Assert.NotNull(flightInfo);
-        Assert.Equal(flightDescriptor, flightInfo.Descriptor);
-        Assert.Single(flightInfo.Schema.FieldsList);
-    }
-
-    [Fact]
-    public async Task GetCrossReferenceSchemaAsync()
-    {
-        // Arrange
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var recordBatch = _testUtils.CreateTestBatch(0, 100);
-        var flightHolder = new FlightHolder(flightDescriptor, recordBatch.Schema,
-            _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var schema = await _flightSqlClient.GetCrossReferenceSchemaAsync();
-
-        // Assert
-        var expectedSchema = recordBatch.Schema;
-        Assert.NotNull(schema);
-        Assert.Equal(expectedSchema.FieldsList.Count, schema.FieldsList.Count);
-    }
-
-    [Fact]
-    public async Task GetTableTypesAsync()
-    {
-        // Arrange
-        var expectedSchema = new Schema.Builder()
-            .Field(f => f.Name("DATA_TYPE_ID").DataType(Int32Type.Default).Nullable(false))
-            .Build();
-        var commandGetTableTypes = new CommandGetTableTypes();
-        byte[] packedCommand = commandGetTableTypes.PackAndSerialize().ToByteArray();
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor(packedCommand);
-        var flightHolder = new FlightHolder(flightDescriptor, expectedSchema, "http://localhost:5000");
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var flightInfo = await _flightSqlClient.GetTableTypesAsync();
-        var actualSchema = flightInfo.Schema;
-
-        // Assert
-        Assert.NotNull(flightInfo);
-        CompareSchemas(expectedSchema, actualSchema);
-    }
-
-    [Fact]
-    public async Task GetTableTypesSchemaAsync()
-    {
-        // Arrange
-        var options = new FlightCallOptions();
-        var expectedSchema = new Schema.Builder()
-            .Field(f => f.Name("DATA_TYPE_ID").DataType(Int32Type.Default).Nullable(false))
-            .Build();
-        var commandGetTableTypesSchema = new CommandGetTableTypes();
-        byte[] packedCommand = commandGetTableTypesSchema.PackAndSerialize().ToByteArray();
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor(packedCommand);
-
-        var flightHolder = new FlightHolder(flightDescriptor, expectedSchema, "http://localhost:5000");
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var schemaResult = await _flightSqlClient.GetTableTypesSchemaAsync(options);
-
-        // Assert
-        Assert.NotNull(schemaResult);
-        CompareSchemas(expectedSchema, schemaResult);
-    }
-
-    [Fact]
-    public async Task GetXdbcTypeInfoAsync()
-    {
-        // Arrange
-        var options = new FlightCallOptions();
-        var expectedSchema = new Schema.Builder()
-            .Field(f => f.Name("DATA_TYPE_ID").DataType(Int32Type.Default).Nullable(false))
-            .Field(f => f.Name("TYPE_NAME").DataType(StringType.Default).Nullable(false))
-            .Field(f => f.Name("PRECISION").DataType(Int32Type.Default).Nullable(false))
-            .Field(f => f.Name("LITERAL_PREFIX").DataType(StringType.Default).Nullable(false))
-            .Field(f => f.Name("COLUMN_SIZE").DataType(Int32Type.Default).Nullable(false))
-            .Build();
-        var commandGetXdbcTypeInfo = new CommandGetXdbcTypeInfo();
-        byte[] packedCommand = commandGetXdbcTypeInfo.PackAndSerialize().ToByteArray();
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor(packedCommand);
-
-        // Creating a flight holder with the expected schema and adding it to the flight store
-        var flightHolder = new FlightHolder(flightDescriptor, expectedSchema, "http://localhost:5000");
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var flightInfo = await _flightSqlClient.GetXdbcTypeInfoAsync(options);
-
-        // Assert
-        Assert.NotNull(flightInfo);
-        CompareSchemas(expectedSchema, flightInfo.Schema);
-    }
-
-    [Fact]
-    public async Task GetXdbcTypeInfoSchemaAsync()
-    {
-        // Arrange
-        var options = new FlightCallOptions();
-        var expectedSchema = new Schema.Builder()
-            .Field(f => f.Name("DATA_TYPE_ID").DataType(Int32Type.Default).Nullable(false))
-            .Field(f => f.Name("TYPE_NAME").DataType(StringType.Default).Nullable(false))
-            .Field(f => f.Name("PRECISION").DataType(Int32Type.Default).Nullable(false))
-            .Field(f => f.Name("LITERAL_PREFIX").DataType(StringType.Default).Nullable(false))
-            .Build();
-
-        var commandGetXdbcTypeInfo = new CommandGetXdbcTypeInfo();
-        byte[] packedCommand = commandGetXdbcTypeInfo.PackAndSerialize().ToByteArray();
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor(packedCommand);
-
-        var flightHolder = new FlightHolder(flightDescriptor, expectedSchema, "http://localhost:5000");
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var schema = await _flightSqlClient.GetXdbcTypeInfoSchemaAsync(options);
-
-        // Assert
-        Assert.NotNull(schema);
-        CompareSchemas(expectedSchema, schema);
-    }
-
-    [Fact]
-    public async Task GetSqlInfoSchemaAsync()
-    {
-        // Arrange
-        var options = new FlightCallOptions();
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("sqlInfo");
-        var expectedSchema = new Schema.Builder()
-            .Field(f => f.Name("DATA_TYPE_ID").DataType(Int32Type.Default).Nullable(false))
-            .Build();
-        var flightHolder = new FlightHolder(flightDescriptor, expectedSchema, _testWebFactory.GetAddress());
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        // Act
-        var schema = await _flightSqlClient.GetSqlInfoSchemaAsync(options);
-
-        // Assert
-        Assert.NotNull(schema);
-        CompareSchemas(expectedSchema, schema);
-    }
-
-    [Fact]
-    public async Task CancelFlightInfoAsync()
-    {
-        // Arrange
-        var schema = new Schema.Builder()
-            .Field(f => f.Name("DATA_TYPE_ID").DataType(Int32Type.Default).Nullable(false))
-            .Build();
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var flightInfo = new FlightInfo(schema, flightDescriptor, new List<FlightEndpoint>(), 0, 0);
-        var cancelRequest = new FlightInfoCancelRequest(flightInfo);
-
-        // Act
-        var cancelResult = await _flightSqlClient.CancelFlightInfoAsync(cancelRequest);
-
-        // Assert
-        Assert.Equal(1, cancelResult.GetCancelStatus());
-    }
-
-    [Fact]
-    public async Task CancelQueryAsync()
-    {
-        // Arrange
-        var flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test");
-        var schema = new Schema.Builder()
-            .Field(f => f.Name("DATA_TYPE_ID").DataType(Int32Type.Default).Nullable(false))
-            .Build();
-        var flightInfo = new FlightInfo(schema, flightDescriptor, new List<FlightEndpoint>(), 0, 0);
-
-        // Adding the flight info to the flight store for testing
-        _flightStore.Flights.Add(flightDescriptor,
-            new FlightHolder(flightDescriptor, schema, _testWebFactory.GetAddress()));
-
-        // Act
-        var cancelStatus = await _flightSqlClient.CancelQueryAsync(flightInfo);
-
-        // Assert
-        Assert.Equal(1, cancelStatus.GetCancelStatus());
-    }
-
-    public void Dispose() => _testWebFactory?.Dispose();
-
-    private void CompareSchemas(Schema expectedSchema, Schema actualSchema)
-    {
-        Assert.Equal(expectedSchema.FieldsList.Count, actualSchema.FieldsList.Count);
-
-        for (int i = 0; i < expectedSchema.FieldsList.Count; i++)
-        {
-            var expectedField = expectedSchema.FieldsList[i];
-            var actualField = actualSchema.FieldsList[i];
-
-            Assert.Equal(expectedField.Name, actualField.Name);
-            Assert.Equal(expectedField.DataType, actualField.DataType);
-            Assert.Equal(expectedField.IsNullable, actualField.IsNullable);
-            Assert.Equal(expectedField.Metadata, actualField.Metadata);
-        }
-    }
-}
\ No newline at end of file
diff --git a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlPreparedStatementTests.cs b/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlPreparedStatementTests.cs
deleted file mode 100644
index 24647bf..0000000
--- a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlPreparedStatementTests.cs
+++ /dev/null
@@ -1,226 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Client;
-using Apache.Arrow.Flight.Sql.Client;
-using Apache.Arrow.Flight.TestWeb;
-using Apache.Arrow.Types;
-using Arrow.Flight.Protocol.Sql;
-using Google.Protobuf;
-using Grpc.Core;
-using Xunit;
-
-namespace Apache.Arrow.Flight.Sql.Tests
-{
-    public class FlightSqlPreparedStatementTests
-    {
-        readonly TestFlightSqlWebFactory _testWebFactory;
-        readonly FlightStore _flightStore;
-        readonly FlightSqlClient _flightSqlClient;
-        private readonly PreparedStatement _preparedStatement;
-        private readonly Schema _schema;
-        private readonly FlightDescriptor _flightDescriptor;
-        private readonly RecordBatch _parameterBatch;
-
-        public FlightSqlPreparedStatementTests()
-        {
-            _flightStore = new FlightStore();
-            _testWebFactory = new TestFlightSqlWebFactory(_flightStore);
-            _flightSqlClient = new FlightSqlClient(new FlightClient(_testWebFactory.GetChannel()));
-
-            _flightDescriptor = FlightDescriptor.CreateCommandDescriptor("test-query");
-            _schema = CreateSchema();
-            _parameterBatch = CreateParameterBatch();
-            _preparedStatement = new PreparedStatement(_flightSqlClient, "test-handle-guid", _schema, _schema);
-        }
-
-        private static Schema CreateSchema()
-        {
-            return new Schema.Builder()
-                .Field(f => f.Name("DATA_TYPE_ID").DataType(Int32Type.Default).Nullable(false))
-                .Build();
-        }
-
-        private RecordBatch CreateParameterBatch()
-        {
-            return new RecordBatch(_schema,
-                new IArrowArray[]
-                {
-                    new Int32Array.Builder().AppendRange(new[] { 1, 2, 3 }).Build(),
-                    new StringArray.Builder().AppendRange(new[] { "INTEGER", "VARCHAR", "BOOLEAN" }).Build(),
-                    new Int32Array.Builder().AppendRange(new[] { 32, 255, 1 }).Build()
-                }, 3);
-        }
-        
-        [Fact]
-        public async Task ExecuteAsync_ShouldReturnFlightInfo_WhenValidInputsAreProvided()
-        {
-            var validRecordBatch = CreateParameterBatch();
-            _preparedStatement.SetParameters(validRecordBatch);
-            var flightInfo = await _preparedStatement.ExecuteAsync();
-
-            Assert.NotNull(flightInfo);
-            Assert.IsType<FlightInfo>(flightInfo);
-        }
-
-        [Fact]
-        public async Task GetSchemaAsync_ShouldThrowInvalidOperationException_WhenStatementIsClosed()
-        {
-            await _preparedStatement.CloseAsync(new FlightCallOptions());
-            await Assert.ThrowsAsync<InvalidOperationException>(() =>
-                _preparedStatement.GetSchemaAsync(new FlightCallOptions()));
-        }
-
-        [Fact]
-        public async Task ExecuteUpdateAsync_ShouldReturnAffectedRows_WhenParametersAreSet()
-        {
-            var affectedRows = await _preparedStatement.ExecuteUpdateAsync(_parameterBatch);
-            Assert.True(affectedRows > 0, "Expected affected rows to be greater than 0.");
-        }
-
-        [Fact]
-        public async Task BindParametersAsync_ShouldReturnMetadata_WhenValidInputsAreProvided()
-        {
-            var metadata = await _preparedStatement.BindParametersAsync(_flightDescriptor, _parameterBatch);
-            Assert.NotNull(metadata);
-            Assert.True(metadata.Length > 0, "Metadata should have a length greater than 0 when valid.");
-        }
-
-        [Theory]
-        [MemberData(nameof(GetTestData))]
-        public async Task TestSetParameters(RecordBatch parameterBatch, Schema parameterSchema, Type expectedException)
-        {
-            var preparedStatement = new PreparedStatement(_flightSqlClient, "TestHandle", _schema, parameterSchema);
-            if (expectedException != null)
-            {
-                var exception =
-                    await Record.ExceptionAsync(() => Task.Run(() => preparedStatement.SetParameters(parameterBatch)));
-                Assert.NotNull(exception);
-                Assert.IsType(expectedException, exception);
-            }
-        }
-
-        [Fact]
-        public async Task TestSetParameters_Cancelled()
-        {
-            var validRecordBatch = CreateRecordBatch([1, 2, 3]);
-            var cts = new CancellationTokenSource();
-            await cts.CancelAsync();
-            _preparedStatement.SetParameters(validRecordBatch);
-        }
-
-        [Fact]
-        public async Task TestCloseAsync()
-        {
-            await _preparedStatement.CloseAsync(new FlightCallOptions());
-            Assert.True(_preparedStatement.IsClosed,
-                "PreparedStatement should be marked as closed after calling CloseAsync.");
-        }
-
-        [Fact]
-        public async Task ReadResultAsync_ShouldPopulateMessage_WhenValidFlightData()
-        {
-            var message = new ActionCreatePreparedStatementResult();
-            var flightData = new FlightData(_flightDescriptor, ByteString.CopyFromUtf8("test-data"));
-            var results = GetAsyncEnumerable(new List<FlightData> { flightData });
-
-            await _preparedStatement.ReadResultAsync(results, message);
-            Assert.NotEmpty(message.PreparedStatementHandle.ToStringUtf8());
-        }
-
-        [Fact]
-        public async Task ReadResultAsync_ShouldNotThrow_WhenFlightDataBodyIsNullOrEmpty()
-        {
-            var message = new ActionCreatePreparedStatementResult();
-            var flightData1 = new FlightData(_flightDescriptor, ByteString.Empty);
-            var flightData2 = new FlightData(_flightDescriptor, ByteString.CopyFromUtf8(""));
-            var results = GetAsyncEnumerable(new List<FlightData> { flightData1, flightData2 });
-
-            await _preparedStatement.ReadResultAsync(results, message);
-            Assert.Empty(message.PreparedStatementHandle.ToStringUtf8());
-        }
-
-        [Fact]
-        public async Task ParseResponseAsync_ShouldReturnPreparedStatement_WhenValidData()
-        {
-            var preparedStatementHandle = "test-handle";
-            var actionResult = new ActionCreatePreparedStatementResult
-            {
-                PreparedStatementHandle = ByteString.CopyFrom(preparedStatementHandle, Encoding.UTF8),
-                DatasetSchema = _schema.ToByteString(),
-                ParameterSchema = _schema.ToByteString()
-            };
-            var flightData = new FlightData(_flightDescriptor, ByteString.CopyFrom(actionResult.ToByteArray()));
-            var results = GetAsyncEnumerable(new List<FlightData> { flightData });
-
-            var preparedStatement = await _preparedStatement.ParseResponseAsync(_flightSqlClient, results);
-            Assert.NotNull(preparedStatement);
-            Assert.Equal(preparedStatementHandle, preparedStatement.Handle);
-        }
-
-        [Theory]
-        [InlineData(null)]
-        [InlineData("")]
-        public async Task ParseResponseAsync_ShouldThrowException_WhenPreparedStatementHandleIsNullOrEmpty(
-            string handle)
-        {
-            ActionCreatePreparedStatementResult actionResult = string.IsNullOrEmpty(handle)
-                ? new ActionCreatePreparedStatementResult()
-                : new ActionCreatePreparedStatementResult
-                    { PreparedStatementHandle = ByteString.CopyFrom(handle, Encoding.UTF8) };
-
-            var flightData = new FlightData(_flightDescriptor, ByteString.CopyFrom(actionResult.ToByteArray()));
-            var results = GetAsyncEnumerable(new List<FlightData> { flightData });
-
-            await Assert.ThrowsAsync<InvalidOperationException>(() =>
-                _preparedStatement.ParseResponseAsync(_flightSqlClient, results));
-        }
-
-        private async IAsyncEnumerable<T> GetAsyncEnumerable<T>(IEnumerable<T> enumerable)
-        {
-            foreach (var item in enumerable)
-            {
-                yield return item;
-                await Task.Yield();
-            }
-        }
-
-        public static IEnumerable<object[]> GetTestData()
-        {
-            var schema = new Schema.Builder().Field(f => f.Name("field1").DataType(Int32Type.Default)).Build();
-            var validRecordBatch = CreateRecordBatch([1, 2, 3]);
-            var invalidSchema = new Schema.Builder().Field(f => f.Name("invalid_field").DataType(Int32Type.Default))
-                .Build();
-            var invalidRecordBatch = CreateRecordBatch([4, 5, 6]);
-
-            return new List<object[]>
-            {
-                new object[] { validRecordBatch, schema, null },
-                new object[] { null, schema, typeof(ArgumentNullException) }
-            };
-        }
-
-        public static RecordBatch CreateRecordBatch(int[] values)
-        {
-            var int32Array = new Int32Array.Builder().AppendRange(values).Build();
-            return new RecordBatch.Builder().Append("field1", true, int32Array).Build();
-        }
-    }
-}
\ No newline at end of file
diff --git a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlServerTests.cs b/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlServerTests.cs
deleted file mode 100644
index e5e64b0..0000000
--- a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlServerTests.cs
+++ /dev/null
@@ -1,376 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#nullable enable
-
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Server;
-using Apache.Arrow.Types;
-using Arrow.Flight.Protocol.Sql;
-using Google.Protobuf;
-using Grpc.Core;
-using Xunit;
-
-namespace Apache.Arrow.Flight.Sql.Tests;
-
-public class FlightSqlServerTests
-{
-    [Theory]
-    [InlineData(FlightDescriptorType.Path, null)]
-    [InlineData(FlightDescriptorType.Command, null)]
-    [InlineData(FlightDescriptorType.Command, typeof(CommandGetCatalogs))]
-    public void EnsureGetCommandReturnsTheCorrectResponse(FlightDescriptorType type, Type? expectedResult)
-    {
-        //Given
-        FlightDescriptor descriptor;
-        if (type == FlightDescriptorType.Command)
-        {
-            descriptor = expectedResult != null ?
-                FlightDescriptor.CreateCommandDescriptor(((IMessage) Activator.CreateInstance(expectedResult!)!).PackAndSerialize().ToByteArray()) :
-                FlightDescriptor.CreateCommandDescriptor(ByteString.Empty.ToStringUtf8());
-        }
-        else
-        {
-            descriptor = FlightDescriptor.CreatePathDescriptor(System.Array.Empty<string>());
-        }
-
-        //When
-        var result = FlightSqlServer.GetCommand(descriptor);
-
-        //Then
-        Assert.Equal(expectedResult, result?.GetType());
-    }
-
-    [Fact]
-    public async Task EnsureTheCorrectActionsAreGiven()
-    {
-        //Given
-        var producer = new TestFlightSqlSever();
-        var streamWriter = new MockServerStreamWriter<FlightActionType>();
-
-        //When
-        await producer.ListActions(streamWriter, new MockServerCallContext());
-        var actions = streamWriter.Messages.ToArray();
-
-        Assert.Equal(FlightSqlUtils.FlightSqlActions, actions);
-    }
-
-    [Theory]
-    [InlineData(false,
-        new[] {"catalog_name", "db_schema_name", "table_name", "table_type"},
-        new[] {typeof(StringType), typeof(StringType), typeof(StringType), typeof(StringType)},
-        new[] {true, true, false, false})
-    ]
-    [InlineData(true,
-        new[] {"catalog_name", "db_schema_name", "table_name", "table_type", "table_schema"},
-        new[] {typeof(StringType), typeof(StringType), typeof(StringType), typeof(StringType), typeof(BinaryType)},
-        new[] {true, true, false, false, false})
-    ]
-    public void EnsureTableSchemaIsCorrectWithoutTableSchema(bool includeTableSchemaField, string[] expectedNames, Type[] expectedTypes, bool[] expectedIsNullable)
-    {
-        // Arrange
-
-        // Act
-        var schema = FlightSqlServer.GetTableSchema(includeTableSchemaField);
-        var fields = schema.FieldsList;
-
-        //Assert
-        Assert.False(schema.HasMetadata);
-        Assert.Equal(expectedNames.Length, fields.Count);
-        for (int i = 0; i < fields.Count; i++)
-        {
-            Assert.Equal(expectedNames[i], fields[i].Name);
-            Assert.Equal(expectedTypes[i], fields[i].DataType.GetType());
-            Assert.Equal(expectedIsNullable[i], fields[i].IsNullable);
-        }
-    }
-
-    #region FlightInfoTests
-    [Theory]
-    [InlineData(typeof(CommandStatementQuery), "GetStatementQueryFlightInfo")]
-    [InlineData(typeof(CommandPreparedStatementQuery), "GetPreparedStatementQueryFlightInfo")]
-    [InlineData(typeof(CommandGetCatalogs), "GetCatalogFlightInfo")]
-    [InlineData(typeof(CommandGetDbSchemas), "GetDbSchemaFlightInfo")]
-    [InlineData(typeof(CommandGetTables), "GetTablesFlightInfo")]
-    [InlineData(typeof(CommandGetTableTypes), "GetTableTypesFlightInfo")]
-    [InlineData(typeof(CommandGetSqlInfo), "GetSqlFlightInfo")]
-    [InlineData(typeof(CommandGetPrimaryKeys), "GetPrimaryKeysFlightInfo")]
-    [InlineData(typeof(CommandGetExportedKeys), "GetExportedKeysFlightInfo")]
-    [InlineData(typeof(CommandGetImportedKeys), "GetImportedKeysFlightInfo")]
-    [InlineData(typeof(CommandGetCrossReference), "GetCrossReferenceFlightInfo")]
-    [InlineData(typeof(CommandGetXdbcTypeInfo), "GetXdbcTypeFlightInfo")]
-    public async Task EnsureGetFlightInfoIsCorrectlyRoutedForCommand(Type commandType, string expectedResult)
-    {
-        //Given
-        var command = (IMessage) Activator.CreateInstance(commandType)!;
-        var producer = new TestFlightSqlSever();
-        var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize().ToArray());
-
-        //When
-        var flightInfo = await producer.GetFlightInfo(descriptor, new MockServerCallContext());
-
-        //Then
-        Assert.Equal(expectedResult, flightInfo.Descriptor.Paths.First());
-    }
-
-
-    [Fact]
-    public async Task EnsureAnInvalidOperationExceptionIsThrownWhenACommandIsNotSupportedAndHasNoDescriptor()
-    {
-        //Given
-        var producer = new TestFlightSqlSever();
-
-        //When
-        async Task<FlightInfo> Act() => await producer.GetFlightInfo(FlightDescriptor.CreatePathDescriptor(""), new MockServerCallContext());
-        var exception = await Record.ExceptionAsync(Act);
-
-        //Then
-        Assert.Equal("command type  not supported", exception?.Message);
-    }
-
-    [Fact]
-    public async Task EnsureAnInvalidOperationExceptionIsThrownWhenACommandIsNotSupported()
-    {
-        //Given
-        var producer = new TestFlightSqlSever();
-        var command = new CommandPreparedStatementUpdate();
-        var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize().ToArray());
-
-        //When
-        async Task<FlightInfo> Act() => await producer.GetFlightInfo(descriptor, new MockServerCallContext());
-        var exception = await Record.ExceptionAsync(Act);
-
-        //Then
-        Assert.Equal("command type CommandPreparedStatementUpdate not supported", exception?.Message);
-    }
-    #endregion
-
-    #region DoGetTests
-
-    [Theory]
-    [InlineData(typeof(CommandPreparedStatementQuery), "DoGetPreparedStatementQuery")]
-    [InlineData(typeof(CommandGetSqlInfo), "DoGetSqlInfo")]
-    [InlineData(typeof(CommandGetCatalogs), "DoGetCatalog")]
-    [InlineData(typeof(CommandGetTableTypes), "DoGetTableType")]
-    [InlineData(typeof(CommandGetTables), "DoGetTables")]
-    [InlineData(typeof(CommandGetDbSchemas), "DoGetDbSchema")]
-    [InlineData(typeof(CommandGetPrimaryKeys), "DoGetPrimaryKeys")]
-    [InlineData(typeof(CommandGetExportedKeys), "DoGetExportedKeys")]
-    [InlineData(typeof(CommandGetImportedKeys), "DoGetImportedKeys")]
-    [InlineData(typeof(CommandGetCrossReference), "DoGetCrossReference")]
-    [InlineData(typeof(CommandGetXdbcTypeInfo), "DoGetXbdcTypeInfo")]
-    public async Task EnsureDoGetIsCorrectlyRoutedForADoGetCommand(Type commandType, string expectedResult)
-    {
-        //Given
-        var producer = new TestFlightSqlSever();
-        var command = (IMessage) Activator.CreateInstance(commandType)!;
-        var ticket = new FlightTicket(command.PackAndSerialize());
-        var streamWriter = new MockServerStreamWriter<FlightData>();
-
-        //When
-        await producer.DoGet(ticket, new FlightServerRecordBatchStreamWriter(streamWriter), new MockServerCallContext());
-        var schema = await streamWriter.Messages.GetSchema();
-
-        //Then
-        Assert.Equal(expectedResult, schema.FieldsList[0].Name);
-    }
-
-    [Fact]
-    public async Task EnsureAnInvalidOperationExceptionIsThrownWhenADoGetCommandIsNotSupported()
-    {
-        //Given
-        var producer = new TestFlightSqlSever();
-        var ticket = new FlightTicket("");
-        var streamWriter = new MockServerStreamWriter<FlightData>();
-
-        //When
-        async Task Act() => await producer.DoGet(ticket, new FlightServerRecordBatchStreamWriter(streamWriter), new MockServerCallContext());
-        var exception = await Record.ExceptionAsync(Act);
-
-        //Then
-        Assert.Equal("Status(StatusCode=\"InvalidArgument\", Detail=\"DoGet command  is not supported.\")", exception?.Message);
-    }
-    #endregion
-
-    #region DoActionTests
-    [Theory]
-    [InlineData(SqlAction.CloseRequest, typeof(ActionClosePreparedStatementRequest), "ClosePreparedStatement")]
-    [InlineData(SqlAction.CreateRequest, typeof(ActionCreatePreparedStatementRequest), "CreatePreparedStatement")]
-    [InlineData("BadCommand", typeof(ActionCreatePreparedStatementRequest), "Action type BadCommand not supported", true)]
-    public async Task EnsureDoActionIsCorrectlyRoutedForAnActionRequest(string actionType, Type actionBodyType, string expectedResponse, bool isException = false)
-    {
-        //Given
-        var producer = new TestFlightSqlSever();
-        var actionBody = (IMessage) Activator.CreateInstance(actionBodyType)!;
-        var action = new FlightAction(actionType, actionBody.PackAndSerialize());
-        var mockStreamWriter = new MockStreamWriter<FlightResult>();
-
-        //When
-        async Task Act() => await producer.DoAction(action, mockStreamWriter, new MockServerCallContext());
-        var exception = await Record.ExceptionAsync(Act);
-        string? actualMessage = isException ? exception?.Message : mockStreamWriter.Messages[0].Body.ToStringUtf8();
-
-        //Then
-        Assert.Equal(expectedResponse, actualMessage);
-    }
-    #endregion
-
-    #region DoPutTests
-    [Theory]
-    [InlineData(typeof(CommandStatementUpdate), "PutStatementUpdate")]
-    [InlineData(typeof(CommandPreparedStatementQuery), "PutPreparedStatementQuery")]
-    [InlineData(typeof(CommandPreparedStatementUpdate), "PutPreparedStatementUpdate")]
-    [InlineData(typeof(CommandGetXdbcTypeInfo), "Command CommandGetXdbcTypeInfo not supported", true)]
-    public async Task EnsureDoPutIsCorrectlyRoutedForTheCommand(Type commandType, string expectedResponse, bool isException = false)
-    {
-        //Given
-        var command = (IMessage) Activator.CreateInstance(commandType)!;
-        var producer = new TestFlightSqlSever();
-        var descriptor = FlightDescriptor.CreateCommandDescriptor(command.PackAndSerialize().ToArray());
-        var recordBatch = new RecordBatch(new Schema(new List<Field>(), null), System.Array.Empty<Int8Array>(), 0);
-        var reader = new MockStreamReader<FlightData>(await recordBatch.ToFlightData(descriptor));
-        var batchReader = new FlightServerRecordBatchStreamReader(reader);
-        var mockStreamWriter = new MockServerStreamWriter<FlightPutResult>();
-
-        //When
-        async Task Act() => await producer.DoPut(batchReader, mockStreamWriter, new MockServerCallContext());
-        var exception = await Record.ExceptionAsync(Act);
-        string? actualMessage = isException ? exception?.Message : mockStreamWriter.Messages[0].ApplicationMetadata.ToStringUtf8();
-
-        //Then
-        Assert.Equal(expectedResponse, actualMessage);
-    }
-    #endregion
-
-    private class MockServerCallContext : ServerCallContext
-    {
-        protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) => throw new NotImplementedException();
-
-        protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions? options) => throw new NotImplementedException();
-        protected override string MethodCore => "";
-        protected override string HostCore => "";
-        protected override string PeerCore => "";
-        protected override DateTime DeadlineCore => new();
-        protected override Metadata RequestHeadersCore => new();
-        protected override CancellationToken CancellationTokenCore => default;
-        protected override Metadata ResponseTrailersCore => new();
-        protected override Status StatusCore { get; set; }
-        protected override WriteOptions? WriteOptionsCore { get; set; } = WriteOptions.Default;
-        protected override AuthContext AuthContextCore => new("", new Dictionary<string, List<AuthProperty>>());
-    }
-}
-
-internal class MockStreamWriter<T> : IServerStreamWriter<T>
-{
-    public Task WriteAsync(T message)
-    {
-        _messages.Add(message);
-        return Task.FromResult(message);
-    }
-
-    public IReadOnlyList<T> Messages => new ReadOnlyCollection<T>(_messages);
-    public WriteOptions? WriteOptions { get; set; }
-    private readonly List<T> _messages = new();
-}
-
-internal class MockServerStreamWriter<T> : IServerStreamWriter<T>
-{
-    public Task WriteAsync(T message)
-    {
-        _messages.Add(message);
-        return Task.FromResult(message);
-    }
-
-    public IReadOnlyList<T> Messages => new ReadOnlyCollection<T>(_messages);
-    public WriteOptions? WriteOptions { get; set; }
-    private readonly List<T> _messages = new();
-}
-
-internal static class MockStreamReaderWriterExtensions
-{
-    public static async Task<List<RecordBatch>> GetRecordBatches(this IReadOnlyList<FlightData> flightDataList)
-    {
-        var list = new List<RecordBatch>();
-        var recordBatchReader = new FlightServerRecordBatchStreamReader(new MockStreamReader<FlightData>(flightDataList));
-        while (await recordBatchReader.MoveNext().ConfigureAwait(false))
-        {
-            list.Add(recordBatchReader.Current);
-        }
-
-        return list;
-    }
-
-    public static async Task<Schema> GetSchema(this IEnumerable<FlightData> flightDataList)
-    {
-        var recordBatchReader = new FlightServerRecordBatchStreamReader(new MockStreamReader<FlightData>(flightDataList));
-        return await recordBatchReader.Schema;
-    }
-
-    public static async Task<IEnumerable<FlightData>> ToFlightData(this RecordBatch recordBatch, FlightDescriptor? descriptor = null)
-    {
-        var responseStream = new MockFlightServerRecordBatchStreamWriter();
-        await responseStream.WriteRecordBatchAsync(recordBatch);
-        if (descriptor == null)
-        {
-            return responseStream.FlightData;
-        }
-
-        return responseStream.FlightData.Select(
-            flightData => new FlightData(descriptor, flightData.DataBody, flightData.DataHeader, flightData.AppMetadata)
-            );
-    }
-}
-
-internal class MockStreamReader<T>: IAsyncStreamReader<T>
-{
-    private readonly IEnumerator<T> _flightActions;
-
-    public MockStreamReader(IEnumerable<T> flightActions)
-    {
-        _flightActions = flightActions.GetEnumerator();
-    }
-
-    public Task<bool> MoveNext(CancellationToken cancellationToken)
-    {
-        return Task.FromResult(_flightActions.MoveNext());
-    }
-
-    public T Current => _flightActions.Current;
-}
-
-internal class MockFlightServerRecordBatchStreamWriter : FlightServerRecordBatchStreamWriter
-{
-    private readonly MockStreamWriter<FlightData> _streamWriter;
-    public MockFlightServerRecordBatchStreamWriter() : this(new MockStreamWriter<FlightData>()) { }
-
-    private MockFlightServerRecordBatchStreamWriter(MockStreamWriter<FlightData> clientStreamWriter) : base(clientStreamWriter)
-    {
-        _streamWriter = clientStreamWriter;
-    }
-
-    public IEnumerable<FlightData> FlightData => _streamWriter.Messages;
-
-    public async Task WriteRecordBatchAsync(RecordBatch recordBatch)
-    {
-        await WriteAsync(recordBatch).ConfigureAwait(false);
-    }
-}
-
-
diff --git a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlTestExtensions.cs b/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlTestExtensions.cs
deleted file mode 100644
index c1cd8f2..0000000
--- a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlTestExtensions.cs
+++ /dev/null
@@ -1,267 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-using Google.Protobuf;
-using Google.Protobuf.WellKnownTypes;
-using Type = System.Type;
-
-namespace Apache.Arrow.Flight.Sql.Tests;
-
-public static class FlightSqlTestExtensions
-{
-    public static ByteString PackAndSerialize(this IMessage command)
-    {
-        return Any.Pack(command).Serialize();
-    }
-}
-
-internal static class TestSchemaExtensions
-{
-    public static void PrintSchema(this RecordBatch recordBatchResult)
-    {
-        // Display column headers
-        foreach (var field in recordBatchResult.Schema.FieldsList)
-        {
-            Console.Write($"{field.Name}\t");
-        }
-
-        Console.WriteLine();
-
-        int rowCount = recordBatchResult.Length;
-
-        for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
-        {
-            foreach (var array in recordBatchResult.Arrays)
-            {
-                // Retrieve value based on array type
-                if (array is Int32Array intArray)
-                {
-                    Console.Write($"{intArray.GetValue(rowIndex)}\t");
-                }
-                else if (array is StringArray stringArray)
-                {
-                    Console.Write($"{stringArray.GetString(rowIndex)}\t");
-                }
-                else if (array is Int64Array longArray)
-                {
-                    Console.Write($"{longArray.GetValue(rowIndex)}\t");
-                }
-                else if (array is FloatArray floatArray)
-                {
-                    Console.Write($"{floatArray.GetValue(rowIndex)}\t");
-                }
-                else if (array is BooleanArray boolArray)
-                {
-                    Console.Write($"{boolArray.GetValue(rowIndex)}\t");
-                }
-                else
-                {
-                    Console.Write("N/A\t"); // Fallback for unsupported types
-                }
-            }
-
-            Console.WriteLine(); // Move to the next row
-        }
-    }
-
-    public static RecordBatch CreateRecordBatch(int[] values)
-    {
-        var paramsList = new List<IArrowArray>();
-        var schema = new Schema.Builder();
-        for (var index = 0; index < values.Length; index++)
-        {
-            var val = values[index];
-            var builder = new Int32Array.Builder();
-            builder.Append(val);
-            var paramsArray = builder.Build();
-            paramsList.Add(paramsArray);
-            schema.Field(f => f.Name($"param{index}").DataType(Int32Type.Default).Nullable(false));
-        }
-
-        return new RecordBatch(schema.Build(), paramsList, values.Length);
-    }
-    
-    public static void PrintSchema(this Schema schema)
-    {
-        Console.WriteLine("Schema Fields:");
-        Console.WriteLine("{0,-20} {1,-20} {2,-20}", "Field Name", "Field Type", "Is Nullable");
-        Console.WriteLine(new string('-', 60));
-    
-        foreach (var field in schema.FieldsLookup)
-        {
-            string fieldName = field.First().Name;
-            string fieldType = field.First().DataType.TypeId.ToString();
-            string isNullable = field.First().IsNullable ? "Yes" : "No";
-
-            Console.WriteLine("{0,-20} {1,-20} {2,-20}", fieldName, fieldType, isNullable);
-        }
-    }
-
-    public static string GetStringValue(IArrowArray array, int index)
-    {
-        return array switch
-        {
-            StringArray stringArray => stringArray.GetString(index),
-            Int32Array intArray => intArray.GetValue(index).ToString(),
-            Int64Array longArray => longArray.GetValue(index).ToString(),
-            BooleanArray boolArray => boolArray.GetValue(index).Value ? "true" : "false",
-            _ => "Unsupported Type"
-        };
-    }
-    
-    public static void PrintRecordBatch(RecordBatch recordBatch)
-    {
-        int rowCount = recordBatch.Length;
-        for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
-        {
-            string catalogName = GetStringValue(recordBatch.Column(0), rowIndex);
-            string schemaName = GetStringValue(recordBatch.Column(1), rowIndex);
-            string tableName = GetStringValue(recordBatch.Column(2), rowIndex);
-            string tableType = GetStringValue(recordBatch.Column(3), rowIndex);
-
-            Console.WriteLine("{0,-20} {1,-20} {2,-20} {3,-20}", catalogName, schemaName, tableName, tableType);
-        }
-    }
-
-    public static RecordBatch CreateRecordBatch(int[] ids, string[] values)
-    {
-        var idArrayBuilder = new Int32Array.Builder();
-        var valueArrayBuilder = new StringArray.Builder();
-
-        for (int i = 0; i < ids.Length; i++)
-        {
-            idArrayBuilder.Append(ids[i]);
-            valueArrayBuilder.Append(values[i]);
-        }
-
-        var schema = new Schema.Builder()
-            .Field(f => f.Name("Id").DataType(Int32Type.Default).Nullable(false))
-            .Field(f => f.Name("Value").DataType(StringType.Default).Nullable(false))
-            .Build();
-
-        return new RecordBatch(schema, [idArrayBuilder.Build(), valueArrayBuilder.Build()], ids.Length);
-    }
-    
-    public static RecordBatch CreateRecordBatch<T>(T[] items)
-    {
-        if (items is null || items.Length == 0)
-        {
-            throw new ArgumentException("Items array cannot be null or empty.");
-        }
-
-        var schema = BuildSchema(typeof(T));
-        
-        var arrays = new List<IArrowArray>();
-        foreach (var field in schema.FieldsList)
-        {
-            var property = typeof(T).GetProperty(field.Name);
-            if (property is null)
-            {
-                throw new InvalidOperationException($"Property {field.Name} not found in type {typeof(T).Name}.");
-            }
-            
-            // extract values and build the array
-            var values = items.Select(item => property.GetValue(item, null)).ToArray();
-            var array = BuildArrowArray(field.DataType, values);
-            arrays.Add(array);
-        }
-        return new RecordBatch(schema, arrays, items.Length);
-    }
-    private static Schema BuildSchema(Type type)
-    {
-        var builder = new Schema.Builder();
-
-        foreach (var property in type.GetProperties())
-        {
-            var fieldType = InferArrowType(property.PropertyType);
-            builder.Field(f => f.Name(property.Name).DataType(fieldType).Nullable(true));
-        }
-
-        return builder.Build();
-    }
-    
-    private static IArrowType InferArrowType(Type type)
-    {
-        return type switch
-        {
-            { } t when t == typeof(string) => StringType.Default,
-            { } t when t == typeof(int) => Int32Type.Default,
-            { } t when t == typeof(float) => FloatType.Default,
-            { } t when t == typeof(bool) => BooleanType.Default,
-            { } t when t == typeof(long) => Int64Type.Default,
-            _ => throw new NotSupportedException($"Unsupported type: {type}")
-        };
-    }
-    
-    private static IArrowArray BuildArrowArray(IArrowType dataType, object[] values, MemoryAllocator allocator = default)
-    {
-        allocator ??= MemoryAllocator.Default.Value;
-
-        return dataType switch
-        {
-            StringType => BuildStringArray(values),
-            Int32Type => BuildArray<int, Int32Array, Int32Array.Builder>(values, allocator),
-            FloatType => BuildArray<float, FloatArray, FloatArray.Builder>(values, allocator),
-            BooleanType => BuildArray<bool, BooleanArray, BooleanArray.Builder>(values, allocator),
-            Int64Type => BuildArray<long, Int64Array, Int64Array.Builder>(values, allocator),
-            _ => throw new NotSupportedException($"Unsupported Arrow type: {dataType}")
-        };
-    }
-    
-    private static IArrowArray BuildStringArray(object[] values)
-    {
-        var builder = new StringArray.Builder();
-
-        foreach (var value in values)
-        {
-            if (value is null)
-            {
-                builder.AppendNull();
-            }
-            else
-            {
-                builder.Append(value.ToString());
-            }
-        }
-
-        return builder.Build();
-    }
-    
-    private static IArrowArray BuildArray<T, TArray, TBuilder>(object[] values, MemoryAllocator allocator)
-        where TArray : IArrowArray
-        where TBuilder : IArrowArrayBuilder<T, TArray, TBuilder>, new()
-    {
-        var builder = new TBuilder();
-
-        foreach (var value in values)
-        {
-            if (value == null)
-            {
-                builder.AppendNull();
-            }
-            else
-            {
-                builder.Append((T)value);
-            }
-        }
-
-        return builder.Build(allocator);
-    }
-}
\ No newline at end of file
diff --git a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlTestUtils.cs b/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlTestUtils.cs
deleted file mode 100644
index e32cc19..0000000
--- a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlTestUtils.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Linq;
-using Apache.Arrow.Flight.Tests;
-using Apache.Arrow.Flight.TestWeb;
-
-namespace Apache.Arrow.Flight.Sql.Tests;
-
-public class FlightSqlTestUtils
-{
-    private readonly TestFlightSqlWebFactory _testWebFactory;
-    private readonly FlightStore _flightStore;
-
-    public FlightSqlTestUtils(TestFlightSqlWebFactory testWebFactory, FlightStore flightStore)
-    {
-        _testWebFactory = testWebFactory;
-        _flightStore = flightStore;
-    }
-
-    public RecordBatch CreateTestBatch(int startValue, int length) 
-    {
-        var batchBuilder = new RecordBatch.Builder();
-        Int32Array.Builder builder = new();
-        for (int i = 0; i < length; i++)
-        {
-            builder.Append(startValue + i);
-        }
-
-        batchBuilder.Append("test", true, builder.Build());
-        return batchBuilder.Build();
-    }
-
-    public FlightInfo GivenStoreBatches(FlightDescriptor flightDescriptor,
-        params RecordBatchWithMetadata[] batches)
-    {
-        var initialBatch = batches.FirstOrDefault();
-
-        var flightHolder = new FlightHolder(flightDescriptor, initialBatch.RecordBatch.Schema,
-            _testWebFactory.GetAddress());
-
-        foreach (var batch in batches)
-        {
-            flightHolder.AddBatch(batch);
-        }
-
-        _flightStore.Flights.Add(flightDescriptor, flightHolder);
-
-        return flightHolder.GetFlightInfo();
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlUtilsTests.cs b/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlUtilsTests.cs
deleted file mode 100644
index 3ea7a8d..0000000
--- a/csharp/test/Apache.Arrow.Flight.Sql.Tests/FlightSqlUtilsTests.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Arrow.Flight.Protocol.Sql;
-using Google.Protobuf;
-using Google.Protobuf.WellKnownTypes;
-using Xunit;
-
-namespace Apache.Arrow.Flight.Sql.Tests
-{
-    public class FlightSqlUtilsTests
-    {
-        [Fact]
-        public void EnsureParseCanCorrectlyReviveTheCommand()
-        {
-            //Given
-            var expectedCommand = new CommandStatementQuery
-            {
-                Query = "select * from database"
-            };
-
-            //When
-            var command = FlightSqlUtils.Parse(Any.Pack(expectedCommand).ToByteString());
-
-            //Then
-            Assert.Equal(command.Unpack<CommandStatementQuery>(), expectedCommand);
-        }
-
-        [Fact]
-        public void EnsureUnpackCanCreateTheCorrectObject()
-        {
-            //Given
-            var expectedCommand = new CommandPreparedStatementQuery
-            {
-                PreparedStatementHandle = ByteString.Empty
-            };
-
-            //When
-            var command = FlightSqlUtils.Unpack<CommandPreparedStatementQuery>(Any.Pack(expectedCommand));
-
-            //Then
-            Assert.Equal(command, expectedCommand);
-        }
-
-        [Fact]
-        public void EnsureParseAndUnpackProducesTheCorrectObject()
-        {
-            //Given
-            var expectedCommand = new CommandPreparedStatementQuery
-            {
-                PreparedStatementHandle = ByteString.Empty
-            };
-
-            //When
-            var command = FlightSqlUtils.ParseAndUnpack<CommandPreparedStatementQuery>(Any.Pack(expectedCommand).ToByteString());
-
-            //Then
-            Assert.Equal(command, expectedCommand);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.Sql.Tests/Startup.cs b/csharp/test/Apache.Arrow.Flight.Sql.Tests/Startup.cs
deleted file mode 100644
index b99418c..0000000
--- a/csharp/test/Apache.Arrow.Flight.Sql.Tests/Startup.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Flight.TestWeb;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-
-namespace Apache.Arrow.Flight.Sql.Tests;
-
-public class StartupFlightSql
-{
-    // This method gets called by the runtime. Use this method to add services to the container.
-    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
-    public void ConfigureServices(IServiceCollection services)
-    {
-        services.AddGrpc()
-            .AddFlightServer<TestFlightSqlServer>();
-
-        services.AddSingleton(new FlightStore());
-    }
-
-    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
-    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
-    {
-        if (env.IsDevelopment())
-        {
-            app.UseDeveloperExceptionPage();
-        }
-
-        app.UseRouting();
-
-        app.UseEndpoints(endpoints =>
-        {
-            endpoints.MapFlightEndpoint();
-
-            endpoints.MapGet("/", async context =>
-            {
-                await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
-            });
-        });
-    }
-}
\ No newline at end of file
diff --git a/csharp/test/Apache.Arrow.Flight.Sql.Tests/TestFlightSqlSever.cs b/csharp/test/Apache.Arrow.Flight.Sql.Tests/TestFlightSqlSever.cs
deleted file mode 100644
index 3dca632..0000000
--- a/csharp/test/Apache.Arrow.Flight.Sql.Tests/TestFlightSqlSever.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Collections.Generic;
-using System.Reflection;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Server;
-using Apache.Arrow.Types;
-using Arrow.Flight.Protocol.Sql;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.Sql.Tests;
-
-public class TestFlightSqlSever : FlightSqlServer
-{
-    protected override Task<FlightInfo> GetStatementQueryFlightInfo(CommandStatementQuery commandStatementQuery, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override Task<FlightInfo> GetPreparedStatementQueryFlightInfo(CommandPreparedStatementQuery preparedStatementQuery, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override Task<FlightInfo> GetCatalogFlightInfo(CommandGetCatalogs command, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override Task<FlightInfo> GetDbSchemaFlightInfo(CommandGetDbSchemas command, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override Task<FlightInfo> GetTablesFlightInfo(CommandGetTables command, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override Task<FlightInfo> GetTableTypesFlightInfo(CommandGetTableTypes command, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override Task<FlightInfo> GetSqlFlightInfo(CommandGetSqlInfo commandGetSqlInfo, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override Task<FlightInfo> GetPrimaryKeysFlightInfo(CommandGetPrimaryKeys command, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override Task<FlightInfo> GetExportedKeysFlightInfo(CommandGetExportedKeys command, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override Task<FlightInfo> GetImportedKeysFlightInfo(CommandGetImportedKeys command, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override Task<FlightInfo> GetCrossReferenceFlightInfo(CommandGetCrossReference command, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override Task<FlightInfo> GetXdbcTypeFlightInfo(CommandGetXdbcTypeInfo command, FlightDescriptor flightDescriptor, ServerCallContext serverCallContext) => Task.FromResult(new FlightInfo(null, FlightDescriptor.CreatePathDescriptor(MethodBase.GetCurrentMethod().Name), System.Array.Empty<FlightEndpoint>()));
-
-    protected override async Task DoGetPreparedStatementQuery(CommandPreparedStatementQuery preparedStatementQuery, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) => await responseStream.WriteAsync(MockRecordBatch("DoGetPreparedStatementQuery"));
-
-    protected override async Task DoGetSqlInfo(CommandGetSqlInfo getSqlInfo, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) => await responseStream.WriteAsync(MockRecordBatch("DoGetSqlInfo"));
-
-    protected override async Task DoGetCatalog(CommandGetCatalogs command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) => await responseStream.WriteAsync(MockRecordBatch("DoGetCatalog"));
-
-    protected override async Task DoGetTableType(CommandGetTableTypes command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) => await responseStream.WriteAsync(MockRecordBatch("DoGetTableType"));
-
-    protected override async Task DoGetTables(CommandGetTables command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) => await responseStream.WriteAsync(MockRecordBatch("DoGetTables"));
-
-    protected override async Task DoGetPrimaryKeys(CommandGetPrimaryKeys command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) => await responseStream.WriteAsync(MockRecordBatch("DoGetPrimaryKeys"));
-
-    protected override async Task DoGetDbSchema(CommandGetDbSchemas command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) => await responseStream.WriteAsync(MockRecordBatch("DoGetDbSchema"));
-
-    protected override async Task DoGetExportedKeys(CommandGetExportedKeys command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) => await responseStream.WriteAsync(MockRecordBatch("DoGetExportedKeys"));
-
-    protected override async Task DoGetImportedKeys(CommandGetImportedKeys command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) => await responseStream.WriteAsync(MockRecordBatch("DoGetImportedKeys"));
-
-    protected override async Task DoGetCrossReference(CommandGetCrossReference command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) => await responseStream.WriteAsync(MockRecordBatch("DoGetCrossReference"));
-
-    protected override async Task DoGetXbdcTypeInfo(CommandGetXdbcTypeInfo command, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) => await responseStream.WriteAsync(MockRecordBatch("DoGetXbdcTypeInfo"));
-
-    protected override async Task CreatePreparedStatement(ActionCreatePreparedStatementRequest request, FlightAction action, IAsyncStreamWriter<FlightResult> streamWriter, ServerCallContext serverCallContext) => await streamWriter.WriteAsync(new FlightResult("CreatePreparedStatement"));
-
-    protected override async Task ClosePreparedStatement(ActionClosePreparedStatementRequest request, FlightAction action, IAsyncStreamWriter<FlightResult> streamWriter, ServerCallContext serverCallContext) => await streamWriter.WriteAsync(new FlightResult("ClosePreparedStatement"));
-
-    protected override async Task PutPreparedStatementUpdate(CommandPreparedStatementUpdate command, FlightServerRecordBatchStreamReader requestStream, IAsyncStreamWriter<FlightPutResult> responseStream, ServerCallContext context) => await responseStream.WriteAsync(new FlightPutResult("PutPreparedStatementUpdate"));
-
-    protected override async Task PutStatementUpdate(CommandStatementUpdate command, FlightServerRecordBatchStreamReader requestStream, IAsyncStreamWriter<FlightPutResult> responseStream, ServerCallContext context) => await responseStream.WriteAsync(new FlightPutResult("PutStatementUpdate"));
-
-    protected override async Task PutPreparedStatementQuery(CommandPreparedStatementQuery command, FlightServerRecordBatchStreamReader requestStream, IAsyncStreamWriter<FlightPutResult> responseStream, ServerCallContext context) => await responseStream.WriteAsync(new FlightPutResult("PutPreparedStatementQuery"));
-
-    private RecordBatch MockRecordBatch(string name)
-    {
-        var schema = new Schema(new List<Field> {new(name, StringType.Default, false)}, System.Array.Empty<KeyValuePair<string, string>>());
-        return new RecordBatch(schema, new []{ new StringArray.Builder().Append(name).Build() }, 1);
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.Sql.Tests/TestFlightSqlWebFactory.cs b/csharp/test/Apache.Arrow.Flight.Sql.Tests/TestFlightSqlWebFactory.cs
deleted file mode 100644
index 594c5d8..0000000
--- a/csharp/test/Apache.Arrow.Flight.Sql.Tests/TestFlightSqlWebFactory.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Linq;
-using Apache.Arrow.Flight.TestWeb;
-using Grpc.Net.Client;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Hosting.Server;
-using Microsoft.AspNetCore.Hosting.Server.Features;
-using Microsoft.AspNetCore.Server.Kestrel.Core;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-
-namespace Apache.Arrow.Flight.Sql.Tests;
-
-public class TestFlightSqlWebFactory : IDisposable
-{
-    readonly IHost host;
-    private int _port;
-
-    public TestFlightSqlWebFactory(FlightStore flightStore)
-    {
-        host = WebHostBuilder(flightStore).Build();
-        host.Start();
-        var addressInfo = host.Services.GetRequiredService<IServer>().Features.Get<IServerAddressesFeature>();
-        if (addressInfo == null)
-        {
-            throw new Exception("No address info could be found for configured server");
-        }
-
-        var address = addressInfo.Addresses.First();
-        var addressUri = new Uri(address);
-        _port = addressUri.Port;
-        AppContext.SetSwitch(
-            "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
-    }
-
-    private IHostBuilder WebHostBuilder(FlightStore flightStore)
-    {
-        return Host.CreateDefaultBuilder()
-            .ConfigureWebHostDefaults(webBuilder =>
-            {
-                webBuilder
-                    .ConfigureKestrel(c => { c.ListenAnyIP(0, l => l.Protocols = HttpProtocols.Http2); })
-                    .UseStartup<StartupFlightSql>()
-                    .ConfigureServices(services => { services.AddSingleton(flightStore); });
-            });
-    }
-
-    public string GetAddress()
-    {
-        return $"http://127.0.0.1:{_port}";
-    }
-
-    public GrpcChannel GetChannel()
-    {
-        return GrpcChannel.ForAddress(GetAddress());
-    }
-
-    public void Stop()
-    {
-        host.StopAsync().Wait();
-    }
-
-    public void Dispose()
-    {
-        Stop();
-    }
-}
\ No newline at end of file
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/Apache.Arrow.Flight.TestWeb.csproj b/csharp/test/Apache.Arrow.Flight.TestWeb/Apache.Arrow.Flight.TestWeb.csproj
deleted file mode 100644
index df8e6ce..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/Apache.Arrow.Flight.TestWeb.csproj
+++ /dev/null
@@ -1,17 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk.Web">
-
-  <PropertyGroup>
-    <TargetFrameworks>net8.0</TargetFrameworks>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Google.Protobuf" Version="3.32.0" />
-    <PackageReference Include="Grpc.AspNetCore" Version="2.71.0" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\..\src\Apache.Arrow.Flight.AspNetCore\Apache.Arrow.Flight.AspNetCore.csproj" />
-    <ProjectReference Include="..\..\src\Apache.Arrow.Flight.Sql\Apache.Arrow.Flight.Sql.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/Extensions/AsyncStreamExtensions.cs b/csharp/test/Apache.Arrow.Flight.TestWeb/Extensions/AsyncStreamExtensions.cs
deleted file mode 100644
index eeb13a8..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/Extensions/AsyncStreamExtensions.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Grpc.Core.Utils
-{
-    public static class AsyncStreamExtensions
-    {
-        /// <summary>
-        /// Reads the entire stream and creates a list containing all the elements read.
-        /// </summary>
-        public static async Task<List<T>> ToListAsync<T>(this IAsyncStreamReader<T> streamReader)
-            where T : class
-        {
-            var result = new List<T>();
-            while (await streamReader.MoveNext().ConfigureAwait(false))
-            {
-                result.Add(streamReader.Current);
-            }
-            return result;
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/FlightHolder.cs b/csharp/test/Apache.Arrow.Flight.TestWeb/FlightHolder.cs
deleted file mode 100644
index b79edc4..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/FlightHolder.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight.TestWeb
-{
-    public class FlightHolder
-    {
-        private readonly FlightDescriptor _flightDescriptor;
-        private readonly Schema _schema;
-        private readonly string _location;
-
-        //Not thread safe, but only used in tests
-        private readonly List<RecordBatchWithMetadata> _recordBatches = new List<RecordBatchWithMetadata>();
-        
-        public FlightHolder(FlightDescriptor flightDescriptor, Schema schema, string location)
-        {
-            _flightDescriptor = flightDescriptor;
-            _schema = schema;
-            _location = location;
-        }
-
-        public void AddBatch(RecordBatchWithMetadata recordBatchWithMetadata)
-        {
-            //Should validate schema here
-            _recordBatches.Add(recordBatchWithMetadata);
-        }
-
-        public IEnumerable<RecordBatchWithMetadata> GetRecordBatches()
-        {
-            return _recordBatches.ToList();
-        }
-
-        public FlightInfo GetFlightInfo()
-        {
-            int batchArrayLength = _recordBatches.Sum(rb => rb.RecordBatch.Length);
-            int batchBytes = _recordBatches.Sum(rb => rb.RecordBatch.Arrays.Sum(arr => arr.Data.Buffers.Sum(b=>b.Length)));
-            return new FlightInfo(_schema, _flightDescriptor, new List<FlightEndpoint>()
-            {
-                new FlightEndpoint(new FlightTicket(GetTicket(_flightDescriptor)), new List<FlightLocation>(){
-                    new FlightLocation(_location)
-                })
-            }, batchArrayLength, batchBytes);
-        }
-
-        private string GetTicket(FlightDescriptor descriptor)
-        {
-            if (descriptor.Paths.FirstOrDefault() != null)
-            {
-                return descriptor.Paths.FirstOrDefault();
-            }
-            
-            if (descriptor.Command.Length > 0)
-            {
-                return $"{descriptor.Command.ToStringUtf8()}";
-            }
-
-            return "default_custom_ticket";
-        }
-    }
-}
\ No newline at end of file
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/FlightStore.cs b/csharp/test/Apache.Arrow.Flight.TestWeb/FlightStore.cs
deleted file mode 100644
index fe53d88..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/FlightStore.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.Flight.TestWeb
-{
-    public class FlightStore
-    {
-        public Dictionary<FlightDescriptor, FlightHolder> Flights { get; set; } = new Dictionary<FlightDescriptor, FlightHolder>();
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/Program.cs b/csharp/test/Apache.Arrow.Flight.TestWeb/Program.cs
deleted file mode 100644
index 2c5c002..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/Program.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Server.Kestrel.Core;
-using Microsoft.Extensions.Hosting;
-
-namespace Apache.Arrow.Flight.TestWeb
-{
-    public class Program
-    {
-        public static void Main(string[] args)
-        {
-            CreateHostBuilder(args).Build().Run();
-        }
-
-        // Additional configuration is required to successfully run gRPC on macOS.
-        // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
-        public static IHostBuilder CreateHostBuilder(string[] args) =>
-            Host.CreateDefaultBuilder(args)
-                .ConfigureWebHostDefaults(webBuilder =>
-                {
-                    webBuilder
-                        .ConfigureKestrel((context, options) =>
-                        {
-                            if (context.HostingEnvironment.IsDevelopment())
-                            {
-                                options.Listen(IPEndPoint.Parse("0.0.0.0:5001"), l => l.Protocols = HttpProtocols.Http2);
-                            }
-                        })
-                        .UseStartup<Startup>();
-                });
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/Properties/launchSettings.json b/csharp/test/Apache.Arrow.Flight.TestWeb/Properties/launchSettings.json
deleted file mode 100644
index 50e6f3d..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/Properties/launchSettings.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "profiles": {
-    "Apache.Arrow.Flight.TestWeb": {
-      "commandName": "Project",
-      "launchBrowser": false,
-      "applicationUrl": "https://localhost:5001",
-      "environmentVariables": {
-        "ASPNETCORE_ENVIRONMENT": "Development"
-      }
-    }
-  }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/RecordBatchWithMetadata.cs b/csharp/test/Apache.Arrow.Flight.TestWeb/RecordBatchWithMetadata.cs
deleted file mode 100644
index 2a4d7e7..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/RecordBatchWithMetadata.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Google.Protobuf;
-
-namespace Apache.Arrow.Flight.TestWeb
-{
-    public class RecordBatchWithMetadata
-    {
-        public RecordBatch RecordBatch { get; }
-        public ByteString Metadata { get; }
-
-        public RecordBatchWithMetadata(RecordBatch recordBatch, ByteString metadata = null)
-        {
-            RecordBatch = recordBatch;
-            Metadata = metadata;
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/Startup.cs b/csharp/test/Apache.Arrow.Flight.TestWeb/Startup.cs
deleted file mode 100644
index 68ce378..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/Startup.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-
-namespace Apache.Arrow.Flight.TestWeb
-{
-    public class Startup
-    {
-        // This method gets called by the runtime. Use this method to add services to the container.
-        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
-        public void ConfigureServices(IServiceCollection services)
-        {
-            services.AddGrpc()
-                .AddFlightServer<TestFlightServer>();
-
-            services.AddSingleton(new FlightStore());
-        }
-
-        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
-        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
-        {
-            if (env.IsDevelopment())
-            {
-                app.UseDeveloperExceptionPage();
-            }
-
-            app.UseRouting();
-
-            app.UseEndpoints(endpoints =>
-            {
-                endpoints.MapFlightEndpoint();
-
-                endpoints.MapGet("/", async context =>
-                {
-                    await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
-                });
-            });
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/TestFlightServer.cs b/csharp/test/Apache.Arrow.Flight.TestWeb/TestFlightServer.cs
deleted file mode 100644
index 5689b45..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/TestFlightServer.cs
+++ /dev/null
@@ -1,143 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Server;
-using Google.Protobuf;
-using Grpc.Core;
-using Grpc.Core.Utils;
-
-namespace Apache.Arrow.Flight.TestWeb
-{
-    public class TestFlightServer : FlightServer
-    {
-        private readonly FlightStore _flightStore;
-
-        public TestFlightServer(FlightStore flightStore)
-        {
-            _flightStore = flightStore;
-        }
-
-        public override async Task DoAction(FlightAction request, IAsyncStreamWriter<FlightResult> responseStream, ServerCallContext context)
-        {
-            switch (request.Type)
-            {
-                case "test":
-                    await responseStream.WriteAsync(new FlightResult("test data"));
-                    break;
-                default:
-                    throw new NotImplementedException();
-            }
-        }
-
-        public override async Task DoGet(FlightTicket ticket, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context)
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor(ticket.Ticket.ToStringUtf8());
-
-            if(_flightStore.Flights.TryGetValue(flightDescriptor, out var flightHolder))
-            {
-                await responseStream.SetupStream(flightHolder.GetFlightInfo().Schema);
-
-                var batches = flightHolder.GetRecordBatches();
-
-                foreach(var batch in batches)
-                {
-                    await responseStream.WriteAsync(batch.RecordBatch, batch.Metadata);
-                }
-            }
-        }
-
-        public override async Task DoPut(FlightServerRecordBatchStreamReader requestStream, IAsyncStreamWriter<FlightPutResult> responseStream, ServerCallContext context)
-        {
-            var flightDescriptor = await requestStream.FlightDescriptor;
-
-            if(!_flightStore.Flights.TryGetValue(flightDescriptor, out var flightHolder))
-            {
-                flightHolder = new FlightHolder(flightDescriptor, await requestStream.Schema, $"grpc+tcp://{context.Host}");
-                _flightStore.Flights.Add(flightDescriptor, flightHolder);
-            }
-
-            while (await requestStream.MoveNext())
-            {
-                var applicationMetadata = requestStream.ApplicationMetadata.FirstOrDefault();
-                flightHolder.AddBatch(new RecordBatchWithMetadata(requestStream.Current, applicationMetadata));
-                await responseStream.WriteAsync(
-                    applicationMetadata == null ? FlightPutResult.Empty : new FlightPutResult(applicationMetadata));
-            }
-        }
-
-        public override Task<FlightInfo> GetFlightInfo(FlightDescriptor request, ServerCallContext context)
-        {
-            if(_flightStore.Flights.TryGetValue(request, out var flightHolder))
-            {
-                return Task.FromResult(flightHolder.GetFlightInfo());
-            }
-            throw new RpcException(new Status(StatusCode.NotFound, "Flight not found"));
-        }
-
-        public override async Task Handshake(IAsyncStreamReader<FlightHandshakeRequest> requestStream, IAsyncStreamWriter<FlightHandshakeResponse> responseStream, ServerCallContext context)
-        {
-            while (await requestStream.MoveNext().ConfigureAwait(false))
-            {
-                if (requestStream.Current.Payload.ToStringUtf8() == "Hello")
-                {
-                    await responseStream.WriteAsync(new(ByteString.CopyFromUtf8("Hello handshake"))).ConfigureAwait(false);
-                }
-                else
-                {
-                    await responseStream.WriteAsync(new(ByteString.CopyFromUtf8("Done"))).ConfigureAwait(false);
-                }
-            }
-        }
-
-        public override Task<Schema> GetSchema(FlightDescriptor request, ServerCallContext context)
-        {
-            if(_flightStore.Flights.TryGetValue(request, out var flightHolder))
-            {
-                return Task.FromResult(flightHolder.GetFlightInfo().Schema);
-            }
-            throw new RpcException(new Status(StatusCode.NotFound, "Flight not found"));
-        }
-
-        public override async Task ListActions(IAsyncStreamWriter<FlightActionType> responseStream, ServerCallContext context)
-        {
-            await responseStream.WriteAsync(new FlightActionType("get", "get a flight"));
-            await responseStream.WriteAsync(new FlightActionType("put", "add a flight"));
-            await responseStream.WriteAsync(new FlightActionType("delete", "delete a flight"));
-            await responseStream.WriteAsync(new FlightActionType("test", "test action"));
-        }
-
-        public override async Task ListFlights(FlightCriteria request, IAsyncStreamWriter<FlightInfo> responseStream, ServerCallContext context)
-        {
-            var flightInfos = _flightStore.Flights.Select(x => x.Value.GetFlightInfo()).ToList();
-
-            foreach(var flightInfo in flightInfos)
-            {
-                await responseStream.WriteAsync(flightInfo);
-            }
-        }
-
-        public override async Task DoExchange(FlightServerRecordBatchStreamReader requestStream, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context)
-        {
-            while(await requestStream.MoveNext().ConfigureAwait(false))
-            {
-                await responseStream.WriteAsync(requestStream.Current, requestStream.ApplicationMetadata.FirstOrDefault()).ConfigureAwait(false);
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/TestFlightSqlServer.cs b/csharp/test/Apache.Arrow.Flight.TestWeb/TestFlightSqlServer.cs
deleted file mode 100644
index a7aaad4..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/TestFlightSqlServer.cs
+++ /dev/null
@@ -1,162 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Server;
-using Apache.Arrow.Flight.Sql;
-using Apache.Arrow.Types;
-using Arrow.Flight.Protocol.Sql;
-using Google.Protobuf;
-using Google.Protobuf.WellKnownTypes;
-using Grpc.Core;
-
-namespace Apache.Arrow.Flight.TestWeb;
-
-public class TestFlightSqlServer : FlightServer
-{
-    private readonly FlightStore _flightStore;
-
-    public TestFlightSqlServer(FlightStore flightStore)
-    {
-        _flightStore = flightStore;
-    }
-
-    public override async Task DoAction(FlightAction request, IAsyncStreamWriter<FlightResult> responseStream,
-        ServerCallContext context)
-    {
-        switch (request.Type)
-        {
-            case "test":
-                await responseStream.WriteAsync(new FlightResult("test data")).ConfigureAwait(false);
-                break;
-            case SqlAction.GetPrimaryKeysRequest:
-                await responseStream.WriteAsync(new FlightResult("test data")).ConfigureAwait(false);
-                break;
-            case SqlAction.CancelFlightInfoRequest:
-                var cancelRequest = new FlightInfoCancelResult();
-                cancelRequest.SetStatus(1);
-                await responseStream.WriteAsync(new FlightResult(Any.Pack(cancelRequest).Serialize().ToByteArray()))
-                    .ConfigureAwait(false);
-                break;
-            case SqlAction.BeginTransactionRequest:
-            case SqlAction.CommitRequest:
-            case SqlAction.RollbackRequest:
-                await responseStream.WriteAsync(new FlightResult(ByteString.CopyFromUtf8("sample-transaction-id")))
-                    .ConfigureAwait(false);
-                break;
-            case SqlAction.CreateRequest:
-            case SqlAction.CloseRequest:
-                var schema = new Schema.Builder()
-                    .Field(f => f.Name("id").DataType(Int32Type.Default))
-                    .Field(f => f.Name("name").DataType(StringType.Default))
-                    .Build();
-                var datasetSchemaBytes = SchemaExtensions.SerializeSchema(schema);
-                var parameterSchemaBytes = SchemaExtensions.SerializeSchema(schema);
-
-                var preparedStatementResponse = new ActionCreatePreparedStatementResult
-                {
-                    PreparedStatementHandle = ByteString.CopyFromUtf8("sample-testing-prepared-statement"),
-                    DatasetSchema = ByteString.CopyFrom(datasetSchemaBytes),
-                    ParameterSchema = ByteString.CopyFrom(parameterSchemaBytes)
-                };
-                byte[] packedResult = Any.Pack(preparedStatementResponse).Serialize().ToByteArray();
-                var flightResult = new FlightResult(packedResult);
-                await responseStream.WriteAsync(flightResult).ConfigureAwait(false);
-                break;
-            default:
-                throw new NotImplementedException();
-        }
-    }
-
-    public override async Task DoGet(FlightTicket ticket, FlightServerRecordBatchStreamWriter responseStream,
-        ServerCallContext context)
-    {
-        FlightDescriptor flightDescriptor = FlightDescriptor.CreateCommandDescriptor(ticket.Ticket.ToStringUtf8());
-
-        if (_flightStore.Flights.TryGetValue(flightDescriptor, out var flightHolder))
-        {
-            var batches = flightHolder.GetRecordBatches();
-
-            foreach (var batch in batches)
-            {
-                await responseStream.WriteAsync(batch.RecordBatch, batch.Metadata);
-            }
-        }
-    }
-    
-    public override async Task DoPut(FlightServerRecordBatchStreamReader requestStream, IAsyncStreamWriter<FlightPutResult> responseStream, ServerCallContext context)
-    {
-        var flightDescriptor = await requestStream.FlightDescriptor;
-
-        if (!_flightStore.Flights.TryGetValue(flightDescriptor, out var flightHolder))
-        {
-            flightHolder = new FlightHolder(flightDescriptor, await requestStream.Schema, $"http://{context.Host}");
-            _flightStore.Flights.Add(flightDescriptor, flightHolder);
-        }
-        
-        int affectedRows = 0;
-        while (await requestStream.MoveNext())
-        {
-            // Process the record batch (if needed) here
-            // Increment the affected row count for demonstration purposes
-            affectedRows += requestStream.Current.Column(0).Length;  // Example of counting rows in the first column
-        }
-
-        // Create a DoPutUpdateResult with the affected row count
-        var updateResult = new DoPutUpdateResult
-        {
-            RecordCount = affectedRows // Set the actual affected row count
-        };
-
-        // Serialize the DoPutUpdateResult into a ByteString
-        var metadata = updateResult.ToByteString();
-
-        // Send the metadata back as part of the FlightPutResult
-        var flightPutResult = new FlightPutResult(metadata);
-        await responseStream.WriteAsync(flightPutResult);
-    }
-    
-    public override Task<FlightInfo> GetFlightInfo(FlightDescriptor request, ServerCallContext context)
-    {
-        if (_flightStore.Flights.TryGetValue(request, out var flightHolder))
-        {
-            return Task.FromResult(flightHolder.GetFlightInfo());
-        }
-
-        if (_flightStore.Flights.Count > 0)
-        {
-            return Task.FromResult(_flightStore.Flights.First().Value.GetFlightInfo());
-        }
-
-        throw new RpcException(new Status(StatusCode.NotFound, "Flight not found"));
-    }
-    
-    public override Task<Schema> GetSchema(FlightDescriptor request, ServerCallContext context)
-    {
-        if (_flightStore.Flights.TryGetValue(request, out var flightHolder))
-        {
-            return Task.FromResult(flightHolder.GetFlightInfo().Schema);
-        }
-
-        if (_flightStore.Flights.Count > 0)
-        {
-            return Task.FromResult(_flightStore.Flights.First().Value.GetFlightInfo().Schema);
-        }
-
-        throw new RpcException(new Status(StatusCode.NotFound, "Flight not found"));
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/appsettings.Development.json b/csharp/test/Apache.Arrow.Flight.TestWeb/appsettings.Development.json
deleted file mode 100644
index fe20c40..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/appsettings.Development.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "Logging": {
-    "LogLevel": {
-      "Default": "Debug",
-      "System": "Information",
-      "Grpc": "Information",
-      "Microsoft": "Information"
-    }
-  }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.TestWeb/appsettings.json b/csharp/test/Apache.Arrow.Flight.TestWeb/appsettings.json
deleted file mode 100644
index 1f29241..0000000
--- a/csharp/test/Apache.Arrow.Flight.TestWeb/appsettings.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "Logging": {
-    "LogLevel": {
-      "Default": "Information",
-      "Microsoft": "Warning",
-      "Microsoft.Hosting.Lifetime": "Information"
-    }
-  },
-  "AllowedHosts": "*",
-  "Kestrel": {
-    "EndpointDefaults": {
-      "Protocols": "Http2"
-    }
-  }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.Tests/Apache.Arrow.Flight.Tests.csproj b/csharp/test/Apache.Arrow.Flight.Tests/Apache.Arrow.Flight.Tests.csproj
deleted file mode 100644
index 2f44806..0000000
--- a/csharp/test/Apache.Arrow.Flight.Tests/Apache.Arrow.Flight.Tests.csproj
+++ /dev/null
@@ -1,21 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFrameworks>net8.0</TargetFrameworks>
-    <IsPackable>false</IsPackable>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Grpc.Net.ClientFactory" Version="2.71.0" />
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
-    <PackageReference Include="xunit" Version="2.9.3" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
-    <PackageReference Include="coverlet.collector" Version="6.0.4" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\Apache.Arrow.Flight.TestWeb\Apache.Arrow.Flight.TestWeb.csproj" />
-    <ProjectReference Include="..\Apache.Arrow.Tests\Apache.Arrow.Tests.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/test/Apache.Arrow.Flight.Tests/FlightInfoComparer.cs b/csharp/test/Apache.Arrow.Flight.Tests/FlightInfoComparer.cs
deleted file mode 100644
index 8f3af17..0000000
--- a/csharp/test/Apache.Arrow.Flight.Tests/FlightInfoComparer.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Tests;
-using Xunit;
-
-namespace Apache.Arrow.Flight.Tests
-{
-    public static class FlightInfoComparer
-    {
-        public static void Compare(FlightInfo expected, FlightInfo actual)
-        {
-            //Check endpoints
-            Assert.Equal(expected.Endpoints, actual.Endpoints);
-
-            //Check flight descriptor
-            Assert.Equal(expected.Descriptor, actual.Descriptor);
-
-            //Check schema
-            SchemaComparer.Compare(expected.Schema, actual.Schema);
-
-            Assert.Equal(expected.TotalBytes, actual.TotalBytes);
-
-            Assert.Equal(expected.TotalRecords, actual.TotalRecords);
-
-            Assert.Equal(expected.Ordered, actual.Ordered);
-
-            Assert.Equal(expected.AppMetadata, actual.AppMetadata);
-            
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.Tests/FlightTests.cs b/csharp/test/Apache.Arrow.Flight.Tests/FlightTests.cs
deleted file mode 100644
index acdd824..0000000
--- a/csharp/test/Apache.Arrow.Flight.Tests/FlightTests.cs
+++ /dev/null
@@ -1,576 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.Flight.Client;
-using Apache.Arrow.Flight.TestWeb;
-using Apache.Arrow.Tests;
-using Google.Protobuf;
-using Grpc.Core;
-using Grpc.Core.Utils;
-using Microsoft.Extensions.DependencyInjection;
-using Xunit;
-
-namespace Apache.Arrow.Flight.Tests
-{
-    public class FlightTests : IDisposable
-    {
-        readonly TestWebFactory _testWebFactory;
-        readonly FlightClient _flightClient;
-        readonly FlightStore _flightStore;
-        public FlightTests()
-        {
-            _flightStore = new FlightStore();
-            _testWebFactory = new TestWebFactory(_flightStore);
-            _flightClient = new FlightClient(_testWebFactory.GetChannel());
-        }
-
-        public void Dispose()
-        {
-            _testWebFactory.Dispose();
-        }
-
-        private RecordBatch CreateTestBatch(int startValue, int length)
-        {
-            var batchBuilder = new RecordBatch.Builder();
-            Int32Array.Builder builder = new Int32Array.Builder();
-            for (int i = 0; i < length; i++)
-            {
-                builder.Append(startValue + i);
-            }
-            batchBuilder.Append("test", true, builder.Build());
-            return batchBuilder.Build();
-        }
-
-        private Schema GetStoreSchema(FlightDescriptor flightDescriptor)
-        {
-            Assert.Contains(flightDescriptor, (IReadOnlyDictionary<FlightDescriptor, FlightHolder>)_flightStore.Flights);
-
-            var flightHolder = _flightStore.Flights[flightDescriptor];
-            return flightHolder.GetFlightInfo().Schema;
-        }
-
-        private IEnumerable<RecordBatchWithMetadata> GetStoreBatch(FlightDescriptor flightDescriptor)
-        {
-            Assert.Contains(flightDescriptor, (IReadOnlyDictionary<FlightDescriptor, FlightHolder>)_flightStore.Flights);
-
-            var flightHolder = _flightStore.Flights[flightDescriptor];
-            return flightHolder.GetRecordBatches();
-        }
-
-        private FlightInfo GivenStoreBatches(FlightDescriptor flightDescriptor, params RecordBatchWithMetadata[] batches)
-        {
-            var initialBatch = batches.FirstOrDefault();
-
-            var flightHolder = new FlightHolder(flightDescriptor, initialBatch?.RecordBatch.Schema, _testWebFactory.GetAddress());
-
-            foreach (var batch in batches)
-            {
-                flightHolder.AddBatch(batch);
-            }
-
-            _flightStore.Flights[flightDescriptor] = flightHolder;
-
-            return flightHolder.GetFlightInfo();
-        }
-
-        [Fact]
-        public async Task TestPutSingleRecordBatch()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("test");
-            var expectedBatch = CreateTestBatch(0, 100);
-
-            var putStream = await _flightClient.StartPut(flightDescriptor, expectedBatch.Schema);
-            await putStream.RequestStream.WriteAsync(expectedBatch);
-            await putStream.RequestStream.CompleteAsync();
-            var putResults = await putStream.ResponseStream.ToListAsync();
-
-            Assert.Single(putResults);
-
-            var actualBatches = GetStoreBatch(flightDescriptor);
-            Assert.Single(actualBatches);
-
-            ArrowReaderVerifier.CompareBatches(expectedBatch, actualBatches.First().RecordBatch);
-        }
-
-        [Fact]
-        public async Task TestPutTwoRecordBatches()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("test");
-            var expectedBatch1 = CreateTestBatch(0, 100);
-            var expectedBatch2 = CreateTestBatch(0, 100);
-
-            var putStream = await _flightClient.StartPut(flightDescriptor, expectedBatch1.Schema);
-            await putStream.RequestStream.WriteAsync(expectedBatch1);
-            await putStream.RequestStream.WriteAsync(expectedBatch2);
-            await putStream.RequestStream.CompleteAsync();
-            var putResults = await putStream.ResponseStream.ToListAsync();
-
-            Assert.Equal(2, putResults.Count);
-
-            var actualBatches = GetStoreBatch(flightDescriptor).ToList();
-            Assert.Equal(2, actualBatches.Count);
-
-            ArrowReaderVerifier.CompareBatches(expectedBatch1, actualBatches[0].RecordBatch);
-            ArrowReaderVerifier.CompareBatches(expectedBatch2, actualBatches[1].RecordBatch);
-        }
-
-        [Fact]
-        public async Task TestPutZeroRecordBatches()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("test");
-            var schema = CreateTestBatch(0, 1).Schema;
-
-            var putStream = await _flightClient.StartPut(flightDescriptor, schema);
-            await putStream.RequestStream.CompleteAsync();
-            var putResults = await putStream.ResponseStream.ToListAsync();
-
-            Assert.Empty(putResults);
-
-            var actualSchema = GetStoreSchema(flightDescriptor);
-
-            SchemaComparer.Compare(schema, actualSchema);
-        }
-
-        [Fact]
-        public async Task TestGetRecordBatchWithDelayedSchema()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("test");
-            var expectedBatch = CreateTestBatch(0, 100);
-
-            //Add flight info only to the in memory store without schema or batch
-            GivenStoreBatches(flightDescriptor);
-
-            //Get the flight info for the ticket and verify the schema is null
-            var flightInfo = await _flightClient.GetInfo(flightDescriptor);
-            Assert.Single(flightInfo.Endpoints);
-            Assert.Null(flightInfo.Schema);
-
-            var endpoint = flightInfo.Endpoints.FirstOrDefault();
-
-            //Update the store with the batch and schema
-            GivenStoreBatches(flightDescriptor, new RecordBatchWithMetadata(expectedBatch));
-            var getStream = _flightClient.GetStream(endpoint.Ticket);
-            var resultList = await getStream.ResponseStream.ToListAsync();
-
-            Assert.Single(resultList);
-            ArrowReaderVerifier.CompareBatches(expectedBatch, resultList[0]);
-        }
-
-        [Fact]
-        public async Task TestGetSingleRecordBatch()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("test");
-            var expectedBatch = CreateTestBatch(0, 100);
-
-            //Add batch to the in memory store
-            GivenStoreBatches(flightDescriptor, new RecordBatchWithMetadata(expectedBatch));
-
-            //Get the flight info for the ticket
-            var flightInfo = await _flightClient.GetInfo(flightDescriptor);
-            Assert.Single(flightInfo.Endpoints);
-
-            var endpoint = flightInfo.Endpoints.FirstOrDefault();
-
-            var getStream = _flightClient.GetStream(endpoint.Ticket);
-            var resultList = await getStream.ResponseStream.ToListAsync();
-
-            Assert.Single(resultList);
-            ArrowReaderVerifier.CompareBatches(expectedBatch, resultList[0]);
-        }
-
-        [Fact]
-        public async Task TestGetTwoRecordBatch()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("test");
-            var expectedBatch1 = CreateTestBatch(0, 100);
-            var expectedBatch2 = CreateTestBatch(100, 100);
-
-            //Add batch to the in memory store
-            GivenStoreBatches(flightDescriptor, new RecordBatchWithMetadata(expectedBatch1), new RecordBatchWithMetadata(expectedBatch2));
-
-            //Get the flight info for the ticket
-            var flightInfo = await _flightClient.GetInfo(flightDescriptor);
-            Assert.Single(flightInfo.Endpoints);
-
-            var endpoint = flightInfo.Endpoints.FirstOrDefault();
-
-            var getStream = _flightClient.GetStream(endpoint.Ticket);
-            var resultList = await getStream.ResponseStream.ToListAsync();
-
-            Assert.Equal(2, resultList.Count);
-            ArrowReaderVerifier.CompareBatches(expectedBatch1, resultList[0]);
-            ArrowReaderVerifier.CompareBatches(expectedBatch2, resultList[1]);
-        }
-
-        [Fact]
-        public async Task TestGetFlightMetadata()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("test");
-            var expectedBatch1 = CreateTestBatch(0, 100);
-
-            var expectedMetadata = ByteString.CopyFromUtf8("test metadata");
-            var expectedMetadataList = new List<ByteString>() { expectedMetadata };
-
-            //Add batch to the in memory store
-            GivenStoreBatches(flightDescriptor, new RecordBatchWithMetadata(expectedBatch1, expectedMetadata));
-
-            //Get the flight info for the ticket
-            var flightInfo = await _flightClient.GetInfo(flightDescriptor);
-            Assert.Single(flightInfo.Endpoints);
-
-            var endpoint = flightInfo.Endpoints.FirstOrDefault();
-
-            var getStream = _flightClient.GetStream(endpoint.Ticket);
-
-            List<ByteString> actualMetadata = new List<ByteString>();
-            while (await getStream.ResponseStream.MoveNext(default))
-            {
-                actualMetadata.AddRange(getStream.ResponseStream.ApplicationMetadata);
-            }
-
-            Assert.Equal(expectedMetadataList, actualMetadata);
-        }
-
-        [Fact]
-        public async Task TestPutWithMetadata()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("test");
-            var expectedBatch = CreateTestBatch(0, 100);
-            var expectedMetadata = ByteString.CopyFromUtf8("test metadata");
-
-            var putStream = await _flightClient.StartPut(flightDescriptor, expectedBatch.Schema);
-            await putStream.RequestStream.WriteAsync(expectedBatch, expectedMetadata);
-            await putStream.RequestStream.CompleteAsync();
-            var putResults = await putStream.ResponseStream.ToListAsync();
-
-            Assert.Single(putResults);
-
-            var actualBatches = GetStoreBatch(flightDescriptor);
-            Assert.Single(actualBatches);
-
-            ArrowReaderVerifier.CompareBatches(expectedBatch, actualBatches.First().RecordBatch);
-            Assert.Equal(expectedMetadata, actualBatches.First().Metadata);
-        }
-
-        [Fact]
-        public async Task TestGetSchema()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("test");
-            var expectedBatch = CreateTestBatch(0, 100);
-            var expectedSchema = expectedBatch.Schema;
-
-            GivenStoreBatches(flightDescriptor, new RecordBatchWithMetadata(expectedBatch));
-
-            var actualSchema = await _flightClient.GetSchema(flightDescriptor);
-
-            SchemaComparer.Compare(expectedSchema, actualSchema);
-        }
-
-        [Fact]
-        public async Task TestDoAction()
-        {
-            var expectedResult = new List<FlightResult>()
-            {
-                new FlightResult("test data")
-            };
-
-            var resultStream = _flightClient.DoAction(new FlightAction("test"));
-            var actualResult = await resultStream.ResponseStream.ToListAsync();
-
-            Assert.Equal(expectedResult, actualResult);
-        }
-
-        [Fact]
-        public async Task TestListActions()
-        {
-            var expected = new List<FlightActionType>()
-            {
-                new FlightActionType("get", "get a flight"),
-                new FlightActionType("put", "add a flight"),
-                new FlightActionType("delete", "delete a flight"),
-                new FlightActionType("test", "test action")
-            };
-
-            var actual = await _flightClient.ListActions().ResponseStream.ToListAsync();
-
-            Assert.Equal(expected, actual);
-        }
-
-        [Fact]
-        public async Task TestListFlights()
-        {
-            var flightDescriptor1 = FlightDescriptor.CreatePathDescriptor("test1");
-            var flightDescriptor2 = FlightDescriptor.CreatePathDescriptor("test2");
-            var expectedBatch = CreateTestBatch(0, 100);
-
-            List<FlightInfo> expectedFlightInfo = new List<FlightInfo>();
-
-            expectedFlightInfo.Add(GivenStoreBatches(flightDescriptor1, new RecordBatchWithMetadata(expectedBatch)));
-            expectedFlightInfo.Add(GivenStoreBatches(flightDescriptor2, new RecordBatchWithMetadata(expectedBatch)));
-
-            var listFlightStream = _flightClient.ListFlights();
-
-            var actualFlights = await listFlightStream.ResponseStream.ToListAsync();
-
-            for (int i = 0; i < expectedFlightInfo.Count; i++)
-            {
-                FlightInfoComparer.Compare(expectedFlightInfo[i], actualFlights[i]);
-            }
-        }
-
-        [Fact]
-        public async Task TestHandshake()
-        {
-            var duplexStreamingCall = _flightClient.Handshake();
-
-            await duplexStreamingCall.RequestStream.WriteAsync(new FlightHandshakeRequest(ByteString.Empty));
-            await duplexStreamingCall.RequestStream.CompleteAsync();
-            var results = await duplexStreamingCall.ResponseStream.ToListAsync();
-
-            Assert.Single(results);
-            Assert.Equal("Done", results.First().Payload.ToStringUtf8());
-        }
-
-        [Fact]
-        public async Task TestSingleExchange()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("single_exchange");
-            var duplexStreamingCall = _flightClient.DoExchange(flightDescriptor);
-            var expectedBatch = CreateTestBatch(0, 100);
-
-            await duplexStreamingCall.RequestStream.WriteAsync(expectedBatch);
-            await duplexStreamingCall.RequestStream.CompleteAsync();
-
-            var results = await duplexStreamingCall.ResponseStream.ToListAsync();
-
-            Assert.Single(results);
-            ArrowReaderVerifier.CompareBatches(expectedBatch, results.FirstOrDefault());
-        }
-
-        [Fact]
-        public async Task TestMultipleExchange()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("multiple_exchange");
-            var duplexStreamingCall = _flightClient.DoExchange(flightDescriptor);
-            var expectedBatch1 = CreateTestBatch(0, 100);
-            var expectedBatch2 = CreateTestBatch(100, 100);
-
-            await duplexStreamingCall.RequestStream.WriteAsync(expectedBatch1);
-            await duplexStreamingCall.RequestStream.WriteAsync(expectedBatch2);
-            await duplexStreamingCall.RequestStream.CompleteAsync();
-
-            var results = await duplexStreamingCall.ResponseStream.ToListAsync();
-
-            ArrowReaderVerifier.CompareBatches(expectedBatch1, results[0]);
-            ArrowReaderVerifier.CompareBatches(expectedBatch2, results[1]);
-        }
-
-        [Fact]
-        public async Task TestExchangeWithMetadata()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("metadata_exchange");
-            var duplexStreamingCall = _flightClient.DoExchange(flightDescriptor);
-            var expectedBatch = CreateTestBatch(0, 100);
-            var expectedMetadata = ByteString.CopyFromUtf8("test metadata");
-
-            await duplexStreamingCall.RequestStream.WriteAsync(expectedBatch, expectedMetadata);
-            await duplexStreamingCall.RequestStream.CompleteAsync();
-
-            List<ByteString> actualMetadata = new List<ByteString>();
-            List<RecordBatch> actualBatch = new List<RecordBatch>();
-            while (await duplexStreamingCall.ResponseStream.MoveNext(default))
-            {
-                actualBatch.Add(duplexStreamingCall.ResponseStream.Current);
-                actualMetadata.AddRange(duplexStreamingCall.ResponseStream.ApplicationMetadata);
-            }
-
-            ArrowReaderVerifier.CompareBatches(expectedBatch, actualBatch.FirstOrDefault());
-            Assert.Equal(expectedMetadata, actualMetadata.FirstOrDefault());
-        }
-
-        [Fact]
-        public async Task TestHandshakeWithSpecificMessage()
-        {
-            var duplexStreamingCall = _flightClient.Handshake();
-
-            await duplexStreamingCall.RequestStream.WriteAsync(new FlightHandshakeRequest(ByteString.CopyFromUtf8("Hello")));
-            await duplexStreamingCall.RequestStream.CompleteAsync();
-            var results = await duplexStreamingCall.ResponseStream.ToListAsync();
-
-            Assert.Single(results);
-            Assert.Equal("Hello handshake", results.First().Payload.ToStringUtf8());
-        }
-
-        [Fact]
-        public async Task TestGetBatchesWithAsyncEnumerable()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("test");
-            var expectedBatch1 = CreateTestBatch(0, 100);
-            var expectedBatch2 = CreateTestBatch(100, 100);
-
-            //Add batch to the in memory store
-            GivenStoreBatches(flightDescriptor, new RecordBatchWithMetadata(expectedBatch1), new RecordBatchWithMetadata(expectedBatch2));
-
-            //Get the flight info for the ticket
-            var flightInfo = await _flightClient.GetInfo(flightDescriptor);
-            Assert.Single(flightInfo.Endpoints);
-
-            var endpoint = flightInfo.Endpoints.FirstOrDefault();
-
-            var getStream = _flightClient.GetStream(endpoint.Ticket);
-
-
-            List<RecordBatch> resultList = new List<RecordBatch>();
-            await foreach (var recordBatch in getStream.ResponseStream)
-            {
-                resultList.Add(recordBatch);
-            }
-
-            Assert.Equal(2, resultList.Count);
-            ArrowReaderVerifier.CompareBatches(expectedBatch1, resultList[0]);
-            ArrowReaderVerifier.CompareBatches(expectedBatch2, resultList[1]);
-        }
-
-        [Fact]
-        public async Task EnsureTheSerializedBatchContainsTheProperTotalRecordsAndTotalBytesProperties()
-        {
-            var flightDescriptor1 = FlightDescriptor.CreatePathDescriptor("test1");
-            var expectedBatch = CreateTestBatch(0, 100);
-            var expectedTotalBytes = expectedBatch.Arrays.Sum(arr => arr.Data.Buffers.Sum(b => b.Length));
-
-            List<FlightInfo> expectedFlightInfo = new List<FlightInfo>();
-
-            expectedFlightInfo.Add(GivenStoreBatches(flightDescriptor1, new RecordBatchWithMetadata(expectedBatch)));
-
-            var listFlightStream = _flightClient.ListFlights();
-
-            var actualFlights = await listFlightStream.ResponseStream.ToListAsync();
-            var result = actualFlights.First();
-
-            Assert.Equal(expectedBatch.Length, result.TotalRecords);
-            Assert.Equal(expectedTotalBytes, result.TotalBytes);
-        }
-
-        [Fact]
-        public async Task EnsureCallRaisesDeadlineExceeded()
-        {
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("raise_deadline");
-            var deadline = DateTime.UtcNow;
-            var batch = CreateTestBatch(0, 100);
-
-            RpcException exception = null;
-
-            var asyncServerStreamingCallFlights = _flightClient.ListFlights(null, null, deadline);
-            Assert.Equal(StatusCode.DeadlineExceeded, asyncServerStreamingCallFlights.GetStatus().StatusCode);
-
-            var asyncServerStreamingCallActions = _flightClient.ListActions(null, deadline);
-            Assert.Equal(StatusCode.DeadlineExceeded, asyncServerStreamingCallFlights.GetStatus().StatusCode);
-
-            GivenStoreBatches(flightDescriptor, new RecordBatchWithMetadata(batch));
-            exception = await Assert.ThrowsAsync<RpcException>(async () => await _flightClient.GetInfo(flightDescriptor, null, deadline));
-            Assert.Equal(StatusCode.DeadlineExceeded, exception.StatusCode);
-
-            var flightInfo = await _flightClient.GetInfo(flightDescriptor);
-            var endpoint = flightInfo.Endpoints.FirstOrDefault();
-            var getStream = _flightClient.GetStream(endpoint.Ticket, null, deadline);
-            Assert.Equal(StatusCode.DeadlineExceeded, getStream.GetStatus().StatusCode);
-
-            var duplexStreamingCall = _flightClient.DoExchange(flightDescriptor, null, deadline);
-            exception = await Assert.ThrowsAsync<RpcException>(async () => await duplexStreamingCall.RequestStream.WriteAsync(batch));
-            Assert.Equal(StatusCode.DeadlineExceeded, exception.StatusCode);
-
-            exception = await Assert.ThrowsAsync<RpcException>(async () => await _flightClient.StartPut(flightDescriptor, batch.Schema, null, deadline));
-            Assert.Equal(StatusCode.DeadlineExceeded, exception.StatusCode);
-
-            exception = await Assert.ThrowsAsync<RpcException>(async () => await _flightClient.GetSchema(flightDescriptor, null, deadline));
-            Assert.Equal(StatusCode.DeadlineExceeded, exception.StatusCode);
-
-            var handshakeStreamingCall = _flightClient.Handshake(null, deadline);
-            exception = await Assert.ThrowsAsync<RpcException>(async () => await handshakeStreamingCall.RequestStream.WriteAsync(new FlightHandshakeRequest(ByteString.Empty)));
-            Assert.Equal(StatusCode.DeadlineExceeded, exception.StatusCode);
-        }
-
-        [Fact]
-        public async Task EnsureCallRaisesRequestCancelled()
-        {
-            var cts = new CancellationTokenSource();
-            cts.CancelAfter(1);
-            
-            var batch = CreateTestBatch(0, 100);
-            var metadata = new Metadata();
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("raise_cancelled");
-            await Task.Delay(5);
-            RpcException exception = null;
-
-            var asyncServerStreamingCallFlights = _flightClient.ListFlights(null, null, null, cts.Token);
-            Assert.Equal(StatusCode.Cancelled, asyncServerStreamingCallFlights.GetStatus().StatusCode);
-
-            var asyncServerStreamingCallActions = _flightClient.ListActions(null, null, cts.Token);
-            Assert.Equal(StatusCode.Cancelled, asyncServerStreamingCallFlights.GetStatus().StatusCode);
-
-            GivenStoreBatches(flightDescriptor, new RecordBatchWithMetadata(batch));
-            exception = await Assert.ThrowsAsync<RpcException>(async () => await _flightClient.GetInfo(flightDescriptor, null, null, cts.Token));
-            Assert.Equal(StatusCode.Cancelled, exception.StatusCode);
-
-            var flightInfo = await _flightClient.GetInfo(flightDescriptor);
-            var endpoint = flightInfo.Endpoints.FirstOrDefault();
-            var getStream = _flightClient.GetStream(endpoint.Ticket, null, null, cts.Token);
-            Assert.Equal(StatusCode.Cancelled, getStream.GetStatus().StatusCode);
-
-            var duplexStreamingCall = _flightClient.DoExchange(flightDescriptor, null, null, cts.Token);
-            exception = await Assert.ThrowsAsync<RpcException>(async () => await duplexStreamingCall.RequestStream.WriteAsync(batch));
-            Assert.Equal(StatusCode.Cancelled, exception.StatusCode);
-
-            exception = await Assert.ThrowsAsync<RpcException>(async () => await _flightClient.StartPut(flightDescriptor, batch.Schema, null, null, cts.Token));
-            Assert.Equal(StatusCode.Cancelled, exception.StatusCode);
-
-            exception = await Assert.ThrowsAsync<RpcException>(async () => await _flightClient.GetSchema(flightDescriptor, null, null, cts.Token));
-            Assert.Equal(StatusCode.Cancelled, exception.StatusCode);
-
-            var handshakeStreamingCall = _flightClient.Handshake(null, null, cts.Token);
-            exception = await Assert.ThrowsAsync<RpcException>(async () => await handshakeStreamingCall.RequestStream.WriteAsync(new FlightHandshakeRequest(ByteString.Empty)));
-            Assert.Equal(StatusCode.Cancelled, exception.StatusCode);
-        }
-
-        [Fact]
-        public async Task TestIntegrationWithGrpcNetClientFactory()
-        {
-            IServiceCollection services = new ServiceCollection();
-
-            services.AddGrpcClient<FlightClient>(grpc => grpc.Address = new Uri(_testWebFactory.GetAddress()));
-
-            IServiceProvider provider = services.BuildServiceProvider();
-
-            // Test that an instance of the FlightClient can be resolved whilst using the Grpc.Net.ClientFactory library.
-            FlightClient flightClient = provider.GetRequiredService<FlightClient>();
-
-            // Test that the resolved client is functional.
-            var flightDescriptor = FlightDescriptor.CreatePathDescriptor("test");
-            var expectedBatch = CreateTestBatch(0, 100);
-            var expectedSchema = expectedBatch.Schema;
-
-            GivenStoreBatches(flightDescriptor, new RecordBatchWithMetadata(expectedBatch));
-
-            var actualSchema = await flightClient.GetSchema(flightDescriptor);
-
-            SchemaComparer.Compare(expectedSchema, actualSchema);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Flight.Tests/TestWebFactory.cs b/csharp/test/Apache.Arrow.Flight.Tests/TestWebFactory.cs
deleted file mode 100644
index 74873e7..0000000
--- a/csharp/test/Apache.Arrow.Flight.Tests/TestWebFactory.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Text;
-using Apache.Arrow.Flight.TestWeb;
-using Grpc.Net.Client;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Hosting.Server;
-using Microsoft.AspNetCore.Hosting.Server.Features;
-using Microsoft.AspNetCore.Server.Kestrel.Core;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-
-namespace Apache.Arrow.Flight.Tests
-{
-    public class TestWebFactory : IDisposable
-    {
-        readonly IHost host;
-        private int _port;
-
-        public TestWebFactory(FlightStore flightStore)
-        {
-            host = WebHostBuilder(flightStore).Build(); //Create the server
-            host.Start();
-            var addressInfo = host.Services.GetRequiredService<IServer>().Features.Get<IServerAddressesFeature>();
-            if (addressInfo == null)
-            {
-                throw new Exception("No address info could be found for configured server");
-            }
-            var address = addressInfo.Addresses.First();
-            var addressUri = new Uri(address);
-            _port = addressUri.Port;
-            AppContext.SetSwitch(
-                "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
-        }
-
-        private IHostBuilder WebHostBuilder(FlightStore flightStore)
-        {
-            return Host.CreateDefaultBuilder()
-                        .ConfigureWebHostDefaults(webBuilder =>
-                        {
-                            webBuilder
-                            .ConfigureKestrel(c =>
-                            {
-                                c.ListenAnyIP(0, l => l.Protocols = HttpProtocols.Http2);
-                            })
-                            .UseStartup<Startup>()
-                            .ConfigureServices(services =>
-                            {
-                                services.AddSingleton(flightStore);
-                            });
-                        });
-        }
-
-        public string GetAddress()
-        {
-            return $"http://127.0.0.1:{_port}";
-        }
-
-        public GrpcChannel GetChannel()
-        {
-            return GrpcChannel.ForAddress(GetAddress());
-        }
-
-        public void Stop()
-        {
-            host.StopAsync().Wait();
-        }
-
-        public void Dispose()
-        {
-            Stop();
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.IntegrationTest/Apache.Arrow.IntegrationTest.csproj b/csharp/test/Apache.Arrow.IntegrationTest/Apache.Arrow.IntegrationTest.csproj
deleted file mode 100644
index 2445151..0000000
--- a/csharp/test/Apache.Arrow.IntegrationTest/Apache.Arrow.IntegrationTest.csproj
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <TargetFrameworks>net8.0</TargetFrameworks>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="System.CommandLine" Version="2.0.0-beta1.21216.1" />
-    <PackageReference Include="System.Text.Json" Version="8.0.5" />
-    <ProjectReference Include="..\..\src\Apache.Arrow.Compression\Apache.Arrow.Compression.csproj" />
-    <ProjectReference Include="..\..\src\Apache.Arrow\Apache.Arrow.csproj" />
-    <ProjectReference Include="..\Apache.Arrow.Tests\Apache.Arrow.Tests.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/test/Apache.Arrow.IntegrationTest/CDataInterface.cs b/csharp/test/Apache.Arrow.IntegrationTest/CDataInterface.cs
deleted file mode 100644
index 2fabae1..0000000
--- a/csharp/test/Apache.Arrow.IntegrationTest/CDataInterface.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Diagnostics;
-using System.IO;
-using Apache.Arrow.C;
-using Apache.Arrow.Arrays;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow.IntegrationTest
-{
-    /// <summary>
-    /// Bridge for C Data Interface integration testing.
-    /// These methods are called from the Python integration testing
-    /// harness provided by Archery.
-    /// </summary>
-    public static class CDataInterface
-    {
-        // Archery uses the `pythonnet` library (*) to invoke .Net DLLs.
-        // `pythonnet` is only able to marshal simple types such as int and
-        // str, which is why we provide trivial wrappers around other APIs.
-        //
-        // (*) https://pythonnet.github.io/
-
-        public static void Initialize()
-        {
-            // Allow debugging using Debug.WriteLine()
-            Trace.Listeners.Add(new ConsoleTraceListener());
-        }
-
-        public static unsafe Schema ImportSchema(long ptr)
-        {
-            return CArrowSchemaImporter.ImportSchema((CArrowSchema*) ptr);
-        }
-
-        public static unsafe void ExportSchema(Schema schema, long ptr)
-        {
-            CArrowSchemaExporter.ExportSchema(schema, (CArrowSchema*) ptr);
-        }
-
-        public static unsafe RecordBatch ImportRecordBatch(long ptr, Schema schema)
-        {
-            return CArrowArrayImporter.ImportRecordBatch((CArrowArray*) ptr, schema);
-        }
-
-        public static unsafe void ExportRecordBatch(RecordBatch batch, long ptr)
-        {
-            CArrowArrayExporter.ExportRecordBatch(batch, (CArrowArray*) ptr);
-        }
-
-        public static JsonFile ParseJsonFile(string jsonPath)
-        {
-            return JsonFile.Parse(new FileInfo(jsonPath));
-        }
-
-        public static void RunGC()
-        {
-            GC.Collect();
-            GC.WaitForPendingFinalizers();
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.IntegrationTest/IntegrationCommand.cs b/csharp/test/Apache.Arrow.IntegrationTest/IntegrationCommand.cs
deleted file mode 100644
index 3886846..0000000
--- a/csharp/test/Apache.Arrow.IntegrationTest/IntegrationCommand.cs
+++ /dev/null
@@ -1,176 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-using System.Threading.Tasks;
-using Apache.Arrow.Compression;
-using Apache.Arrow.Ipc;
-using Apache.Arrow.Tests;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow.IntegrationTest
-{
-    public class IntegrationCommand
-    {
-        public string Mode { get; set; }
-        public FileInfo JsonFileInfo { get; set; }
-        public FileInfo ArrowFileInfo { get; set; }
-
-        public IntegrationCommand(string mode, FileInfo jsonFileInfo, FileInfo arrowFileInfo)
-        {
-            Mode = mode;
-            JsonFileInfo = jsonFileInfo;
-            ArrowFileInfo = arrowFileInfo;
-        }
-
-        public async Task<int> Execute()
-        {
-            Func<Task<int>> commandDelegate = Mode switch
-            {
-                "validate" => Validate,
-                "json-to-arrow" => JsonToArrow,
-                "stream-to-file" => StreamToFile,
-                "file-to-stream" => FileToStream,
-                "round-trip-json-arrow" => RoundTripJsonArrow,
-                _ => () =>
-                {
-                    Console.WriteLine($"Mode '{Mode}' is not supported.");
-                    return Task.FromResult(-1);
-                }
-            };
-            return await commandDelegate();
-        }
-
-        private async Task<int> RoundTripJsonArrow()
-        {
-            int status = await JsonToArrow();
-            if (status != 0) { return status; }
-
-            return await Validate();
-        }
-
-        private async Task<int> Validate()
-        {
-            JsonFile jsonFile = await ParseJsonFile();
-
-            var compressionFactory = new CompressionCodecFactory();
-            using FileStream arrowFileStream = ArrowFileInfo.OpenRead();
-            using ArrowFileReader reader = new ArrowFileReader(arrowFileStream, compressionCodecFactory: compressionFactory);
-            int batchCount = await reader.RecordBatchCountAsync();
-
-            if (batchCount != jsonFile.Batches.Count)
-            {
-                Console.WriteLine($"Incorrect batch count. JsonFile: {jsonFile.Batches.Count}, ArrowFile: {batchCount}");
-                return -1;
-            }
-
-            Schema jsonFileSchema = jsonFile.GetSchemaAndDictionaries(out Func<DictionaryType, IArrowArray> dictionaries);
-            Schema arrowFileSchema = reader.Schema;
-
-            SchemaComparer.Compare(jsonFileSchema, arrowFileSchema);
-
-            for (int i = 0; i < batchCount; i++)
-            {
-                RecordBatch arrowFileRecordBatch = reader.ReadNextRecordBatch();
-                RecordBatch jsonFileRecordBatch = jsonFile.Batches[i].ToArrow(jsonFileSchema, dictionaries);
-
-                ArrowReaderVerifier.CompareBatches(jsonFileRecordBatch, arrowFileRecordBatch, strictCompare: false);
-            }
-
-            // ensure there are no more batches in the file
-            if (reader.ReadNextRecordBatch() != null)
-            {
-                Console.WriteLine($"The ArrowFile has more RecordBatches than it should.");
-                return -1;
-            }
-
-            return 0;
-        }
-
-        private async Task<int> JsonToArrow()
-        {
-            JsonFile jsonFile = await ParseJsonFile();
-            Schema schema = jsonFile.GetSchemaAndDictionaries(out Func<DictionaryType, IArrowArray> dictionaries);
-
-            using (FileStream fs = ArrowFileInfo.Create())
-            {
-                ArrowFileWriter writer = new ArrowFileWriter(fs, schema);
-                await writer.WriteStartAsync();
-
-                foreach (var jsonRecordBatch in jsonFile.Batches)
-                {
-                    RecordBatch batch = jsonRecordBatch.ToArrow(schema, dictionaries);
-                    await writer.WriteRecordBatchAsync(batch);
-                }
-                await writer.WriteEndAsync();
-                await fs.FlushAsync();
-            }
-
-            return 0;
-        }
-
-        private async Task<int> StreamToFile()
-        {
-            var compressionFactory = new CompressionCodecFactory();
-            using ArrowStreamReader reader = new ArrowStreamReader(Console.OpenStandardInput(), compressionCodecFactory: compressionFactory);
-
-            RecordBatch batch = await reader.ReadNextRecordBatchAsync();
-
-            using FileStream fileStream = ArrowFileInfo.OpenWrite();
-            using ArrowFileWriter writer = new ArrowFileWriter(fileStream, reader.Schema);
-            await writer.WriteStartAsync();
-
-            while (batch != null)
-            {
-                await writer.WriteRecordBatchAsync(batch);
-
-                batch = await reader.ReadNextRecordBatchAsync();
-            }
-
-            await writer.WriteEndAsync();
-
-            return 0;
-        }
-
-        private async Task<int> FileToStream()
-        {
-            using FileStream fileStream = ArrowFileInfo.OpenRead();
-            var compressionFactory = new CompressionCodecFactory();
-            using ArrowFileReader fileReader = new ArrowFileReader(fileStream, compressionCodecFactory: compressionFactory);
-
-            // read the record batch count to initialize the Schema
-            await fileReader.RecordBatchCountAsync();
-
-            using ArrowStreamWriter writer = new ArrowStreamWriter(Console.OpenStandardOutput(), fileReader.Schema);
-            await writer.WriteStartAsync();
-
-            RecordBatch batch;
-            while ((batch = fileReader.ReadNextRecordBatch()) != null)
-            {
-                await writer.WriteRecordBatchAsync(batch);
-            }
-
-            await writer.WriteEndAsync();
-
-            return 0;
-        }
-
-        private async ValueTask<JsonFile> ParseJsonFile()
-        {
-            return await JsonFile.ParseAsync(JsonFileInfo);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.IntegrationTest/JsonFile.cs b/csharp/test/Apache.Arrow.IntegrationTest/JsonFile.cs
deleted file mode 100644
index a75c419..0000000
--- a/csharp/test/Apache.Arrow.IntegrationTest/JsonFile.cs
+++ /dev/null
@@ -1,1264 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Numerics;
-using System.Text;
-using System.Text.Json;
-using System.Text.Json.Nodes;
-using System.Text.Json.Serialization;
-using System.Threading.Tasks;
-using Apache.Arrow.Arrays;
-using Apache.Arrow.Scalars;
-using Apache.Arrow.Types;
-
-namespace Apache.Arrow.IntegrationTest
-{
-    public class JsonFile
-    {
-        public JsonSchema Schema { get; set; }
-
-        public List<JsonDictionary> Dictionaries { get; set; }
-
-        public List<JsonRecordBatch> Batches { get; set; }
-
-        public static async ValueTask<JsonFile> ParseAsync(FileInfo fileInfo)
-        {
-            using var fileStream = fileInfo.OpenRead();
-            var options = GetJsonOptions();
-            return await JsonSerializer.DeserializeAsync<JsonFile>(fileStream, options);
-        }
-
-        public static JsonFile Parse(FileInfo fileInfo)
-        {
-            using var fileStream = fileInfo.OpenRead();
-            var options = GetJsonOptions();
-            return JsonSerializer.Deserialize<JsonFile>(fileStream, options);
-        }
-
-        public Schema GetSchemaAndDictionaries(out Func<DictionaryType, IArrowArray> dictionaries)
-        {
-            Schema schema = Schema.ToArrow(out Dictionary<DictionaryType, int> dictionaryIndexes);
-
-            Func<DictionaryType, IArrowArray> lookup = null;
-            lookup = type => Dictionaries.Single(d => d.Id == dictionaryIndexes[type]).Data.ToArrow(type.ValueType, lookup);
-            dictionaries = lookup;
-
-            return schema;
-        }
-
-        /// <summary>
-        /// Return both the schema and a specific batch number.
-        /// This method is used by C Data Interface integration testing.
-        /// </summary>
-        public Schema ToArrow(int batchNumber, out RecordBatch batch)
-        {
-            Schema schema = Schema.ToArrow(out Dictionary<DictionaryType, int> dictionaryIndexes);
-
-            Func<DictionaryType, IArrowArray> lookup = null;
-            lookup = type => Dictionaries.Single(d => d.Id == dictionaryIndexes[type]).Data.ToArrow(type.ValueType, lookup);
-
-            batch = Batches[batchNumber].ToArrow(schema, lookup);
-
-            return schema;
-        }
-
-        private static JsonSerializerOptions GetJsonOptions()
-        {
-            JsonSerializerOptions options = new JsonSerializerOptions()
-            {
-                PropertyNamingPolicy = JsonFileNamingPolicy.Instance,
-            };
-            options.Converters.Add(new ValidityConverter());
-            return options;
-        }
-    }
-
-    public class JsonSchema
-    {
-        public List<JsonField> Fields { get; set; }
-        public JsonMetadata Metadata { get; set; }
-
-        /// <summary>
-        /// Decode this JSON schema as a Schema instance.
-        /// </summary>
-        public Schema ToArrow(out Dictionary<DictionaryType, int> dictionaryIndexes)
-        {
-            dictionaryIndexes = new Dictionary<DictionaryType, int>();
-            return CreateSchema(this, dictionaryIndexes);
-        }
-
-        /// <summary>
-        /// Decode this JSON schema as a Schema instance without computing dictionaries.
-        /// This method is used by C Data Interface integration testing.
-        /// </summary>
-        public Schema ToArrow()
-        {
-            Dictionary<DictionaryType, int> dictionaryIndexes = new Dictionary<DictionaryType, int>();
-            return CreateSchema(this, dictionaryIndexes);
-        }
-
-        private static Schema CreateSchema(JsonSchema jsonSchema, Dictionary<DictionaryType, int> dictionaryIndexes)
-        {
-            Schema.Builder builder = new Schema.Builder();
-            for (int i = 0; i < jsonSchema.Fields.Count; i++)
-            {
-                builder.Field(f => CreateField(f, jsonSchema.Fields[i], dictionaryIndexes));
-            }
-
-            if (jsonSchema.Metadata != null)
-            {
-                builder.Metadata(jsonSchema.Metadata);
-            }
-
-            return builder.Build();
-        }
-
-        private static void CreateField(Field.Builder builder, JsonField jsonField, Dictionary<DictionaryType, int> dictionaryIndexes)
-        {
-            Field[] children = null;
-            if (jsonField.Children?.Count > 0)
-            {
-                children = new Field[jsonField.Children.Count];
-                for (int i = 0; i < jsonField.Children.Count; i++)
-                {
-                    Field.Builder field = new Field.Builder();
-                    CreateField(field, jsonField.Children[i], dictionaryIndexes);
-                    children[i] = field.Build();
-                }
-            }
-
-            IArrowType type = ToArrowType(jsonField.Type, children);
-
-            if (jsonField.Dictionary != null)
-            {
-                DictionaryType dictType = new DictionaryType(
-                    ToArrowType(jsonField.Dictionary.IndexType, new Field[0]),
-                    type,
-                    jsonField.Dictionary.IsOrdered);
-
-                dictionaryIndexes[dictType] = jsonField.Dictionary.Id;
-                type = dictType;
-            }
-
-            builder.Name(jsonField.Name)
-                .DataType(type)
-                .Nullable(jsonField.Nullable);
-
-            if (jsonField.Metadata != null)
-            {
-                builder.Metadata(jsonField.Metadata);
-            }
-        }
-
-        private static IArrowType ToArrowType(JsonArrowType type, Field[] children)
-        {
-            return type.Name switch
-            {
-                "bool" => BooleanType.Default,
-                "int" => ToIntArrowType(type),
-                "floatingpoint" => ToFloatingPointArrowType(type),
-                "decimal" => ToDecimalArrowType(type),
-                "binary" => BinaryType.Default,
-                "binaryview" => BinaryViewType.Default,
-                "largebinary" => LargeBinaryType.Default,
-                "utf8" => StringType.Default,
-                "utf8view" => StringViewType.Default,
-                "largeutf8" => LargeStringType.Default,
-                "fixedsizebinary" => new FixedSizeBinaryType(type.ByteWidth),
-                "date" => ToDateArrowType(type),
-                "time" => ToTimeArrowType(type),
-                "duration" => ToDurationArrowType(type),
-                "interval" => ToIntervalArrowType(type),
-                "interval_mdn" => ToIntervalArrowType(type),
-                "timestamp" => ToTimestampArrowType(type),
-                "list" => ToListArrowType(type, children),
-                "listview" => ToListViewArrowType(type, children),
-                "largelist" => ToLargeListArrowType(type, children),
-                "fixedsizelist" => ToFixedSizeListArrowType(type, children),
-                "struct" => ToStructArrowType(type, children),
-                "union" => ToUnionArrowType(type, children),
-                "map" => ToMapArrowType(type, children),
-                "null" => NullType.Default,
-                _ => throw new NotSupportedException($"JsonArrowType not supported: {type.Name}")
-            };
-        }
-
-        private static IArrowType ToIntArrowType(JsonArrowType type)
-        {
-            return (type.BitWidth, type.IsSigned) switch
-            {
-                (8, true) => Int8Type.Default,
-                (8, false) => UInt8Type.Default,
-                (16, true) => Int16Type.Default,
-                (16, false) => UInt16Type.Default,
-                (32, true) => Int32Type.Default,
-                (32, false) => UInt32Type.Default,
-                (64, true) => Int64Type.Default,
-                (64, false) => UInt64Type.Default,
-                _ => throw new NotSupportedException($"Int type not supported: {type.BitWidth}, {type.IsSigned}")
-            };
-        }
-
-        private static IArrowType ToFloatingPointArrowType(JsonArrowType type)
-        {
-            return type.FloatingPointPrecision switch
-            {
-                "SINGLE" => FloatType.Default,
-                "DOUBLE" => DoubleType.Default,
-                _ => throw new NotSupportedException($"FloatingPoint type not supported: {type.FloatingPointPrecision}")
-            };
-        }
-
-        private static IArrowType ToDecimalArrowType(JsonArrowType type)
-        {
-            return type.BitWidth switch
-            {
-                256 => new Decimal256Type(type.DecimalPrecision, type.Scale),
-                128 => new Decimal128Type(type.DecimalPrecision, type.Scale),
-                64 => new Decimal64Type(type.DecimalPrecision, type.Scale),
-                32 => new Decimal32Type(type.DecimalPrecision, type.Scale),
-                0 => new Decimal128Type(type.DecimalPrecision, type.Scale),
-                _ => throw new NotSupportedException($"Decimal type not supported. BitWidth: {type.BitWidth}"),
-            };
-        }
-
-        private static IArrowType ToDateArrowType(JsonArrowType type)
-        {
-            return type.Unit switch
-            {
-                "DAY" => Date32Type.Default,
-                "MILLISECOND" => Date64Type.Default,
-                _ => throw new NotSupportedException($"Date type not supported: {type.Unit}")
-            };
-        }
-
-        private static IArrowType ToTimeArrowType(JsonArrowType type)
-        {
-            return (type.Unit, type.BitWidth) switch
-            {
-                ("SECOND", 32) => new Time32Type(TimeUnit.Second),
-                ("SECOND", 64) => new Time64Type(TimeUnit.Second),
-                ("MILLISECOND", 32) => new Time32Type(TimeUnit.Millisecond),
-                ("MILLISECOND", 64) => new Time64Type(TimeUnit.Millisecond),
-                ("MICROSECOND", 32) => new Time32Type(TimeUnit.Microsecond),
-                ("MICROSECOND", 64) => new Time64Type(TimeUnit.Microsecond),
-                ("NANOSECOND", 32) => new Time32Type(TimeUnit.Nanosecond),
-                ("NANOSECOND", 64) => new Time64Type(TimeUnit.Nanosecond),
-                _ => throw new NotSupportedException($"Time type not supported: {type.Unit}, {type.BitWidth}")
-            };
-        }
-
-        private static IArrowType ToDurationArrowType(JsonArrowType type)
-        {
-            return type.Unit switch
-            {
-                "SECOND" => DurationType.Second,
-                "MILLISECOND" => DurationType.Millisecond,
-                "MICROSECOND" => DurationType.Microsecond,
-                "NANOSECOND" => DurationType.Nanosecond,
-                _ => throw new NotSupportedException($"Time type not supported: {type.Unit}, {type.BitWidth}")
-            };
-        }
-
-        private static IArrowType ToIntervalArrowType(JsonArrowType type)
-        {
-            return type.Unit switch
-            {
-                "YEAR_MONTH" => IntervalType.YearMonth,
-                "DAY_TIME" => IntervalType.DayTime,
-                "MONTH_DAY_NANO" => IntervalType.MonthDayNanosecond,
-                _ => throw new NotSupportedException($"Interval type not supported: {type.Unit}")
-            };
-        }
-
-        private static IArrowType ToTimestampArrowType(JsonArrowType type)
-        {
-            return type.Unit switch
-            {
-                "SECOND" => new TimestampType(TimeUnit.Second, type.Timezone),
-                "MILLISECOND" => new TimestampType(TimeUnit.Millisecond, type.Timezone),
-                "MICROSECOND" => new TimestampType(TimeUnit.Microsecond, type.Timezone),
-                "NANOSECOND" => new TimestampType(TimeUnit.Nanosecond, type.Timezone),
-                _ => throw new NotSupportedException($"Time type not supported: {type.Unit}, {type.BitWidth}")
-            };
-        }
-
-        private static IArrowType ToListArrowType(JsonArrowType type, Field[] children)
-        {
-            return new ListType(children[0]);
-        }
-
-        private static IArrowType ToListViewArrowType(JsonArrowType type, Field[] children)
-        {
-            return new ListViewType(children[0]);
-        }
-
-        private static IArrowType ToLargeListArrowType(JsonArrowType type, Field[] children)
-        {
-            return new LargeListType(children[0]);
-        }
-
-        private static IArrowType ToFixedSizeListArrowType(JsonArrowType type, Field[] children)
-        {
-            return new FixedSizeListType(children[0], type.ListSize);
-        }
-
-        private static IArrowType ToStructArrowType(JsonArrowType type, Field[] children)
-        {
-            return new StructType(children);
-        }
-
-        private static IArrowType ToUnionArrowType(JsonArrowType type, Field[] children)
-        {
-            UnionMode mode = type.Mode switch
-            {
-                "SPARSE" => UnionMode.Sparse,
-                "DENSE" => UnionMode.Dense,
-                _ => throw new NotSupportedException($"Union mode not supported: {type.Mode}"),
-            };
-            return new UnionType(children, type.TypeIds, mode);
-        }
-
-        private static IArrowType ToMapArrowType(JsonArrowType type, Field[] children)
-        {
-            return new MapType(children[0], type.KeysSorted);
-        }
-    }
-
-    public class JsonField
-    {
-        public string Name { get; set; }
-        public bool Nullable { get; set; }
-        public JsonArrowType Type { get; set; }
-        public List<JsonField> Children { get; set; }
-        public JsonDictionaryIndex Dictionary { get; set; }
-        public JsonMetadata Metadata { get; set; }
-    }
-
-    public class JsonArrowType
-    {
-        public string Name { get; set; }
-
-        // int fields
-        public int BitWidth { get; set; }
-        public bool IsSigned { get; set; }
-
-        // floating point fields
-        [JsonIgnore]
-        public string FloatingPointPrecision => ExtensionData["precision"].GetString();
-
-        // decimal fields
-        [JsonIgnore]
-        public int DecimalPrecision => ExtensionData["precision"].GetInt32();
-        public int Scale { get; set; }
-
-        // date and time fields
-        public string Unit { get; set; }
-        // timestamp fields
-        public string Timezone { get; set; }
-
-        // FixedSizeBinary fields
-        public int ByteWidth { get; set; }
-
-        // FixedSizeList fields
-        public int ListSize { get; set; }
-
-        // union fields
-        public string Mode { get; set; }
-        public int[] TypeIds { get; set; }
-
-        // map fields
-        public bool KeysSorted { get; set; }
-
-        [JsonExtensionData]
-        public Dictionary<string, JsonElement> ExtensionData { get; set; }
-    }
-
-    public class JsonDictionaryIndex
-    {
-        public int Id { get; set; }
-        public JsonArrowType IndexType { get; set; }
-        public bool IsOrdered { get; set; }
-    }
-
-    public class JsonDictionary
-    {
-        public int Id { get; set; }
-
-        [JsonPropertyName("data")]
-        public JsonRecordBatch Data { get; set; }
-    }
-
-    public class JsonMetadata : List<KeyValuePair<string, string>>
-    {
-    }
-
-    public class JsonRecordBatch
-    {
-        public int Count { get; set; }
-        public List<JsonFieldData> Columns { get; set; }
-
-        /// <summary>
-        /// Decode this JSON record batch as a RecordBatch instance.
-        /// </summary>
-        public RecordBatch ToArrow(Schema schema, Func<DictionaryType, IArrowArray> dictionaries)
-        {
-            return CreateRecordBatch(schema, dictionaries, this);
-        }
-
-        public IArrowArray ToArrow(IArrowType arrowType, Func<DictionaryType, IArrowArray> dictionaries)
-        {
-            ArrayCreator creator = new ArrayCreator(this.Columns[0], dictionaries);
-            arrowType.Accept(creator);
-            return creator.Array;
-        }
-
-        private RecordBatch CreateRecordBatch(Schema schema, Func<DictionaryType, IArrowArray> dictionaries, JsonRecordBatch jsonRecordBatch)
-        {
-            if (schema.FieldsList.Count != jsonRecordBatch.Columns.Count)
-            {
-                throw new NotSupportedException($"jsonRecordBatch.Columns.Count '{jsonRecordBatch.Columns.Count}' doesn't match schema field count '{schema.FieldsList.Count}'");
-            }
-
-            List<IArrowArray> arrays = new List<IArrowArray>(jsonRecordBatch.Columns.Count);
-            for (int i = 0; i < jsonRecordBatch.Columns.Count; i++)
-            {
-                JsonFieldData data = jsonRecordBatch.Columns[i];
-                Field field = schema.FieldsList[i];
-                ArrayCreator creator = new ArrayCreator(data, dictionaries);
-                field.DataType.Accept(creator);
-                arrays.Add(creator.Array);
-            }
-
-            return new RecordBatch(schema, arrays, jsonRecordBatch.Count);
-        }
-
-        private class ArrayCreator :
-            IArrowTypeVisitor<BooleanType>,
-            IArrowTypeVisitor<Int8Type>,
-            IArrowTypeVisitor<Int16Type>,
-            IArrowTypeVisitor<Int32Type>,
-            IArrowTypeVisitor<Int64Type>,
-            IArrowTypeVisitor<UInt8Type>,
-            IArrowTypeVisitor<UInt16Type>,
-            IArrowTypeVisitor<UInt32Type>,
-            IArrowTypeVisitor<UInt64Type>,
-            IArrowTypeVisitor<FloatType>,
-            IArrowTypeVisitor<DoubleType>,
-            IArrowTypeVisitor<Decimal32Type>,
-            IArrowTypeVisitor<Decimal64Type>,
-            IArrowTypeVisitor<Decimal128Type>,
-            IArrowTypeVisitor<Decimal256Type>,
-            IArrowTypeVisitor<Date32Type>,
-            IArrowTypeVisitor<Date64Type>,
-            IArrowTypeVisitor<Time32Type>,
-            IArrowTypeVisitor<Time64Type>,
-            IArrowTypeVisitor<DurationType>,
-            IArrowTypeVisitor<IntervalType>,
-            IArrowTypeVisitor<TimestampType>,
-            IArrowTypeVisitor<StringType>,
-            IArrowTypeVisitor<StringViewType>,
-            IArrowTypeVisitor<LargeStringType>,
-            IArrowTypeVisitor<BinaryType>,
-            IArrowTypeVisitor<BinaryViewType>,
-            IArrowTypeVisitor<LargeBinaryType>,
-            IArrowTypeVisitor<FixedSizeBinaryType>,
-            IArrowTypeVisitor<ListType>,
-            IArrowTypeVisitor<ListViewType>,
-            IArrowTypeVisitor<LargeListType>,
-            IArrowTypeVisitor<FixedSizeListType>,
-            IArrowTypeVisitor<StructType>,
-            IArrowTypeVisitor<UnionType>,
-            IArrowTypeVisitor<MapType>,
-            IArrowTypeVisitor<DictionaryType>,
-            IArrowTypeVisitor<NullType>
-        {
-            private JsonFieldData JsonFieldData { get; set; }
-            public IArrowArray Array { get; private set; }
-
-            private readonly Func<DictionaryType, IArrowArray> dictionaries;
-
-            public ArrayCreator(JsonFieldData jsonFieldData, Func<DictionaryType, IArrowArray> dictionaries)
-            {
-                JsonFieldData = jsonFieldData;
-                this.dictionaries = dictionaries;
-            }
-
-            public void Visit(BooleanType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-                ArrowBuffer.BitmapBuilder valueBuilder = new ArrowBuffer.BitmapBuilder(validityBuffer.Length);
-
-                var json = JsonFieldData.Data.GetRawText();
-                bool[] values = JsonSerializer.Deserialize<bool[]>(json);
-
-                foreach (bool value in values)
-                {
-                    valueBuilder.Append(value);
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build();
-
-                Array = new BooleanArray(
-                    valueBuffer, validityBuffer,
-                    JsonFieldData.Count, nullCount, 0);
-            }
-
-            public void Visit(Int8Type type) => GenerateArray<sbyte, Int8Array>((v, n, c, nc, o) => new Int8Array(v, n, c, nc, o));
-            public void Visit(Int16Type type) => GenerateArray<short, Int16Array>((v, n, c, nc, o) => new Int16Array(v, n, c, nc, o));
-            public void Visit(Int32Type type) => GenerateArray<int, Int32Array>((v, n, c, nc, o) => new Int32Array(v, n, c, nc, o));
-            public void Visit(Int64Type type) => GenerateLongArray<long, Int64Array>((v, n, c, nc, o) => new Int64Array(v, n, c, nc, o), s => long.Parse(s));
-            public void Visit(UInt8Type type) => GenerateArray<byte, UInt8Array>((v, n, c, nc, o) => new UInt8Array(v, n, c, nc, o));
-            public void Visit(UInt16Type type) => GenerateArray<ushort, UInt16Array>((v, n, c, nc, o) => new UInt16Array(v, n, c, nc, o));
-            public void Visit(UInt32Type type) => GenerateArray<uint, UInt32Array>((v, n, c, nc, o) => new UInt32Array(v, n, c, nc, o));
-            public void Visit(UInt64Type type) => GenerateLongArray<ulong, UInt64Array>((v, n, c, nc, o) => new UInt64Array(v, n, c, nc, o), s => ulong.Parse(s));
-            public void Visit(FloatType type) => GenerateArray<float, FloatArray>((v, n, c, nc, o) => new FloatArray(v, n, c, nc, o));
-            public void Visit(DoubleType type) => GenerateArray<double, DoubleArray>((v, n, c, nc, o) => new DoubleArray(v, n, c, nc, o));
-            public void Visit(Time32Type type) => GenerateArray<int, Time32Array>((v, n, c, nc, o) => new Time32Array(type, v, n, c, nc, o));
-            public void Visit(Time64Type type) => GenerateLongArray<long, Time64Array>((v, n, c, nc, o) => new Time64Array(type, v, n, c, nc, o), s => long.Parse(s));
-            public void Visit(DurationType type) => GenerateLongArray<long, DurationArray>((v, n, c, nc, o) => new DurationArray(type, v, n, c, nc, o), s => long.Parse(s));
-
-            public void Visit(IntervalType type)
-            {
-                switch (type.Unit)
-                {
-                    case IntervalUnit.YearMonth:
-                        GenerateArray((v, n, c, nc, o) => new YearMonthIntervalArray(v, n, c, nc, o), e => new YearMonthInterval(e.GetInt32()));
-                        break;
-                    case IntervalUnit.DayTime:
-                        GenerateArray(
-                            (v, n, c, nc, o) => new DayTimeIntervalArray(v, n, c, nc, o),
-                            e => new DayTimeInterval(e.GetProperty("days").GetInt32(), e.GetProperty("milliseconds").GetInt32()));
-                        break;
-                    case IntervalUnit.MonthDayNanosecond:
-                        GenerateArray(
-                            (v, n, c, nc, o) => new MonthDayNanosecondIntervalArray(v, n, c, nc, o),
-                            e => new MonthDayNanosecondInterval(
-                                e.GetProperty("months").GetInt32(),
-                                e.GetProperty("days").GetInt32(),
-                                e.GetProperty("nanoseconds").GetInt64()));
-                        break;
-                    default:
-                        throw new InvalidOperationException($"unsupported interval unit <{type.Unit}>");
-                }
-            }
-
-            public void Visit(Decimal32Type type)
-            {
-                Array = new Decimal32Array(GetDecimalArrayData(type));
-            }
-
-            public void Visit(Decimal64Type type)
-            {
-                Array = new Decimal64Array(GetDecimalArrayData(type));
-            }
-
-            public void Visit(Decimal128Type type)
-            {
-                Array = new Decimal128Array(GetDecimalArrayData(type));
-            }
-
-            public void Visit(Decimal256Type type)
-            {
-                Array = new Decimal256Array(GetDecimalArrayData(type));
-            }
-
-            public void Visit(NullType type)
-            {
-                Array = new NullArray(JsonFieldData.Count);
-            }
-
-            private ArrayData GetDecimalArrayData(FixedSizeBinaryType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                var json = JsonFieldData.Data.GetRawText();
-                string[] values = JsonSerializer.Deserialize<string[]>(json, s_options);
-
-                Span<byte> buffer = stackalloc byte[type.ByteWidth];
-
-                ArrowBuffer.Builder<byte> valueBuilder = new ArrowBuffer.Builder<byte>();
-                foreach (string value in values)
-                {
-                    buffer.Fill(0);
-
-                    BigInteger bigInteger = BigInteger.Parse(value);
-                    if (!bigInteger.TryWriteBytes(buffer, out int bytesWritten, false, !BitConverter.IsLittleEndian))
-                    {
-                        throw new InvalidDataException($"Decimal data was too big to fit into {type.BitWidth} bits.");
-                    }
-
-                    if (bigInteger.Sign == -1)
-                    {
-                        buffer.Slice(bytesWritten).Fill(255);
-                    }
-
-                    valueBuilder.Append(buffer);
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build(default);
-
-                return new ArrayData(type, JsonFieldData.Count, nullCount, 0, new[] { validityBuffer, valueBuffer });
-            }
-
-            public void Visit(Date32Type type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                ArrowBuffer.Builder<int> valueBuilder = new ArrowBuffer.Builder<int>(JsonFieldData.Count);
-                var json = JsonFieldData.Data.GetRawText();
-                int[] values = JsonSerializer.Deserialize<int[]>(json, s_options);
-
-                foreach (int value in values)
-                {
-                    valueBuilder.Append(value);
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build();
-
-                Array = new Date32Array(
-                    valueBuffer, validityBuffer,
-                    JsonFieldData.Count, nullCount, 0);
-            }
-
-            public void Visit(Date64Type type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                ArrowBuffer.Builder<long> valueBuilder = new ArrowBuffer.Builder<long>(JsonFieldData.Count);
-                var json = JsonFieldData.Data.GetRawText();
-                string[] values = JsonSerializer.Deserialize<string[]>(json, s_options);
-
-                foreach (string value in values)
-                {
-                    valueBuilder.Append(long.Parse(value));
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build();
-
-                Array = new Date64Array(
-                    valueBuffer, validityBuffer,
-                    JsonFieldData.Count, nullCount, 0);
-            }
-
-            public void Visit(TimestampType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                ArrowBuffer.Builder<long> valueBuilder = new ArrowBuffer.Builder<long>(JsonFieldData.Count);
-                var json = JsonFieldData.Data.GetRawText();
-                string[] values = JsonSerializer.Deserialize<string[]>(json, s_options);
-
-                foreach (string value in values)
-                {
-                    valueBuilder.Append(long.Parse(value));
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build();
-
-                Array = new TimestampArray(
-                    type, valueBuffer, validityBuffer,
-                    JsonFieldData.Count, nullCount, 0);
-            }
-
-            public void Visit(StringType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-                ArrowBuffer offsetBuffer = GetOffsetBuffer();
-
-                var json = JsonFieldData.Data.GetRawText();
-                string[] values = JsonSerializer.Deserialize<string[]>(json, s_options);
-
-                ArrowBuffer.Builder<byte> valueBuilder = new ArrowBuffer.Builder<byte>();
-                foreach (string value in values)
-                {
-                    valueBuilder.Append(Encoding.UTF8.GetBytes(value));
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build(default);
-
-                Array = new StringArray(JsonFieldData.Count, offsetBuffer, valueBuffer, validityBuffer, nullCount);
-            }
-
-            public void Visit(StringViewType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                // ArrowBuffer viewsBuffer = GetViewsBuffer();
-                ArrowBuffer viewsBuffer = ArrowBuffer.Empty;
-                if (JsonFieldData.Views != null)
-                {
-                    ArrowBuffer.Builder<BinaryView> viewBuilder = new ArrowBuffer.Builder<BinaryView>(JsonFieldData.Views.Count);
-                    foreach (JsonView jsonView in JsonFieldData.Views)
-                    {
-                        BinaryView view = (jsonView.BufferIndex == null) ?
-                            new BinaryView(Encoding.UTF8.GetBytes(jsonView.Inlined)) :
-                            new BinaryView(jsonView.Size, Convert.FromHexString(jsonView.PrefixHex), jsonView.BufferIndex.Value, jsonView.Offset.Value);
-                        viewBuilder.Append(view);
-                    }
-                    viewsBuffer = viewBuilder.Build();
-                }
-
-                int bufferCount = JsonFieldData.VariadicDataBuffers?.Count ?? 0;
-                ArrowBuffer[] buffers = new ArrowBuffer[2 + bufferCount];
-                buffers[0] = validityBuffer;
-                buffers[1] = viewsBuffer;
-                for (int i = 0; i < bufferCount; i++)
-                {
-                    buffers[i + 2] = new ArrowBuffer(Convert.FromHexString(JsonFieldData.VariadicDataBuffers[i])).Clone();
-                }
-
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0, buffers);
-                Array = new StringViewArray(arrayData);
-            }
-
-            public void Visit(LargeStringType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-                ArrowBuffer offsetBuffer = GetLargeOffsetBuffer();
-
-                var json = JsonFieldData.Data.GetRawText();
-                string[] values = JsonSerializer.Deserialize<string[]>(json, s_options);
-
-                ArrowBuffer.Builder<byte> valueBuilder = new ArrowBuffer.Builder<byte>();
-                foreach (string value in values)
-                {
-                    valueBuilder.Append(Encoding.UTF8.GetBytes(value));
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build(default);
-
-                Array = new LargeStringArray(JsonFieldData.Count, offsetBuffer, valueBuffer, validityBuffer, nullCount);
-            }
-
-            public void Visit(BinaryType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-                ArrowBuffer offsetBuffer = GetOffsetBuffer();
-
-                var json = JsonFieldData.Data.GetRawText();
-                string[] values = JsonSerializer.Deserialize<string[]>(json, s_options);
-
-                ArrowBuffer.Builder<byte> valueBuilder = new ArrowBuffer.Builder<byte>();
-                foreach (string value in values)
-                {
-                    valueBuilder.Append(ConvertHexStringToByteArray(value));
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build(default);
-
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0, new[] { validityBuffer, offsetBuffer, valueBuffer });
-                Array = new BinaryArray(arrayData);
-            }
-
-            public void Visit(BinaryViewType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                // ArrowBuffer viewsBuffer = GetViewsBuffer();
-                ArrowBuffer viewsBuffer = ArrowBuffer.Empty;
-                if (JsonFieldData.Views != null)
-                {
-                    ArrowBuffer.Builder<BinaryView> viewBuilder = new ArrowBuffer.Builder<BinaryView>(JsonFieldData.Views.Count);
-                    foreach (JsonView jsonView in JsonFieldData.Views)
-                    {
-                        BinaryView view = (jsonView.BufferIndex == null) ?
-                            new BinaryView(Convert.FromHexString(jsonView.Inlined)) :
-                            new BinaryView(jsonView.Size, Convert.FromHexString(jsonView.PrefixHex), jsonView.BufferIndex.Value, jsonView.Offset.Value);
-                        viewBuilder.Append(view);
-                    }
-                    viewsBuffer = viewBuilder.Build();
-                }
-
-                int bufferCount = JsonFieldData.VariadicDataBuffers?.Count ?? 0;
-                ArrowBuffer[] buffers = new ArrowBuffer[2 + bufferCount];
-                buffers[0] = validityBuffer;
-                buffers[1] = viewsBuffer;
-                for (int i = 0; i < bufferCount; i++)
-                {
-                    buffers[i + 2] = new ArrowBuffer(Convert.FromHexString(JsonFieldData.VariadicDataBuffers[i])).Clone();
-                }
-
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0, buffers);
-                Array = new BinaryViewArray(arrayData);
-            }
-
-            public void Visit(LargeBinaryType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-                ArrowBuffer offsetBuffer = GetLargeOffsetBuffer();
-
-                var json = JsonFieldData.Data.GetRawText();
-                string[] values = JsonSerializer.Deserialize<string[]>(json, s_options);
-
-                ArrowBuffer.Builder<byte> valueBuilder = new ArrowBuffer.Builder<byte>();
-                foreach (string value in values)
-                {
-                    valueBuilder.Append(ConvertHexStringToByteArray(value));
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build(default);
-
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0, new[] { validityBuffer, offsetBuffer, valueBuffer });
-                Array = new LargeBinaryArray(arrayData);
-            }
-
-            public void Visit(FixedSizeBinaryType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                var json = JsonFieldData.Data.GetRawText();
-                string[] values = JsonSerializer.Deserialize<string[]>(json, s_options);
-
-                ArrowBuffer.Builder<byte> valueBuilder = new ArrowBuffer.Builder<byte>();
-                foreach (string value in values)
-                {
-                    valueBuilder.Append(ConvertHexStringToByteArray(value));
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build(default);
-
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0, new[] { validityBuffer, valueBuffer });
-                Array = new FixedSizeBinaryArray(arrayData);
-            }
-
-            public void Visit(ListType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-                ArrowBuffer offsetBuffer = GetOffsetBuffer();
-
-                var data = JsonFieldData;
-                JsonFieldData = data.Children[0];
-                type.ValueDataType.Accept(this);
-                JsonFieldData = data;
-
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0,
-                    new[] { validityBuffer, offsetBuffer }, new[] { Array.Data });
-                Array = new ListArray(arrayData);
-            }
-
-            public void Visit(ListViewType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-                ArrowBuffer offsetBuffer = GetOffsetBuffer();
-                ArrowBuffer sizeBuffer = GetSizeBuffer();
-
-                var data = JsonFieldData;
-                JsonFieldData = data.Children[0];
-                type.ValueDataType.Accept(this);
-                JsonFieldData = data;
-
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0,
-                    new[] { validityBuffer, offsetBuffer, sizeBuffer }, new[] { Array.Data });
-                Array = new ListViewArray(arrayData);
-            }
-
-            public void Visit(LargeListType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-                ArrowBuffer offsetBuffer = GetLargeOffsetBuffer();
-
-                var data = JsonFieldData;
-                JsonFieldData = data.Children[0];
-                type.ValueDataType.Accept(this);
-                JsonFieldData = data;
-
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0,
-                    new[] { validityBuffer, offsetBuffer }, new[] { Array.Data });
-                Array = new LargeListArray(arrayData);
-            }
-
-            public void Visit(FixedSizeListType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                var data = JsonFieldData;
-                JsonFieldData = data.Children[0];
-                type.ValueDataType.Accept(this);
-                JsonFieldData = data;
-
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0,
-                    new[] { validityBuffer }, new[] { Array.Data });
-                Array = new FixedSizeListArray(arrayData);
-            }
-
-            public void Visit(StructType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                ArrayData[] children = new ArrayData[type.Fields.Count];
-
-                var data = JsonFieldData;
-                for (int i = 0; i < children.Length; i++)
-                {
-                    JsonFieldData = data.Children[i];
-                    type.Fields[i].DataType.Accept(this);
-                    children[i] = Array.Data;
-                }
-                JsonFieldData = data;
-
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0,
-                    new[] { validityBuffer }, children);
-                Array = new StructArray(arrayData);
-            }
-
-            public void Visit(UnionType type)
-            {
-                ArrowBuffer[] buffers;
-                if (type.Mode == UnionMode.Dense)
-                {
-                    buffers = new ArrowBuffer[2];
-                    buffers[1] = GetOffsetBuffer();
-                }
-                else
-                {
-                    buffers = new ArrowBuffer[1];
-                }
-                buffers[0] = GetTypeIdBuffer();
-
-                ArrayData[] children = GetChildren(type);
-
-                int nullCount = 0;
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0, buffers, children);
-                Array = UnionArray.Create(arrayData);
-            }
-
-            public void Visit(MapType type)
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-                ArrowBuffer offsetBuffer = GetOffsetBuffer();
-
-                var data = JsonFieldData;
-                JsonFieldData = data.Children[0];
-                type.KeyValueType.Accept(this);
-                JsonFieldData = data;
-
-                ArrayData arrayData = new ArrayData(type, JsonFieldData.Count, nullCount, 0,
-                    new[] { validityBuffer, offsetBuffer }, new[] { Array.Data });
-                Array = new MapArray(arrayData);
-            }
-
-            public void Visit(DictionaryType type)
-            {
-                type.IndexType.Accept(this);
-                Array = new DictionaryArray(type, Array, this.dictionaries(type));
-            }
-
-            private ArrayData[] GetChildren(NestedType type)
-            {
-                ArrayData[] children = new ArrayData[type.Fields.Count];
-
-                var data = JsonFieldData;
-                for (int i = 0; i < children.Length; i++)
-                {
-                    JsonFieldData = data.Children[i];
-                    type.Fields[i].DataType.Accept(this);
-                    children[i] = Array.Data;
-                }
-                JsonFieldData = data;
-
-                return children;
-            }
-
-            private static byte[] ConvertHexStringToByteArray(string hexString)
-            {
-                byte[] data = new byte[hexString.Length / 2];
-                for (int index = 0; index < data.Length; index++)
-                {
-                    data[index] = byte.Parse(hexString.AsSpan(index * 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
-                }
-
-                return data;
-            }
-
-            private static readonly JsonSerializerOptions s_options = new JsonSerializerOptions()
-            {
-                Converters =
-                {
-                    new ByteArrayConverter()
-                }
-            };
-
-            private void GenerateArray<T, TArray>(Func<ArrowBuffer, ArrowBuffer, int, int, int, TArray> createArray)
-                where T : struct, IEquatable<T>
-                where TArray : PrimitiveArray<T>
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                ArrowBuffer.Builder<T> valueBuilder = new ArrowBuffer.Builder<T>(JsonFieldData.Count);
-                var json = JsonFieldData.Data.GetRawText();
-                T[] values = JsonSerializer.Deserialize<T[]>(json, s_options);
-
-                foreach (T value in values)
-                {
-                    valueBuilder.Append(value);
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build();
-
-                Array = createArray(
-                    valueBuffer, validityBuffer,
-                    JsonFieldData.Count, nullCount, 0);
-            }
-
-            private void GenerateLongArray<T, TArray>(Func<ArrowBuffer, ArrowBuffer, int, int, int, TArray> createArray, Func<string, T> parse)
-                where T : struct, IEquatable<T>
-                where TArray : PrimitiveArray<T>
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                ArrowBuffer.Builder<T> valueBuilder = new ArrowBuffer.Builder<T>(JsonFieldData.Count);
-                var json = JsonFieldData.Data.GetRawText();
-                string[] values = JsonSerializer.Deserialize<string[]>(json);
-
-                foreach (string value in values)
-                {
-                    valueBuilder.Append(parse(value));
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build();
-
-                Array = createArray(
-                    valueBuffer, validityBuffer,
-                    JsonFieldData.Count, nullCount, 0);
-            }
-
-            private void GenerateArray<T, TArray>(Func<ArrowBuffer, ArrowBuffer, int, int, int, TArray> createArray, Func<JsonElement, T> construct)
-                where T : struct, IEquatable<T>
-                where TArray : PrimitiveArray<T>
-            {
-                ArrowBuffer validityBuffer = GetValidityBuffer(out int nullCount);
-
-                ArrowBuffer.Builder<T> valueBuilder = new ArrowBuffer.Builder<T>(JsonFieldData.Count);
-
-                foreach (JsonElement element in JsonFieldData.Data.EnumerateArray())
-                {
-                    valueBuilder.Append(construct(element));
-                }
-                ArrowBuffer valueBuffer = valueBuilder.Build();
-
-                Array = createArray(
-                    valueBuffer, validityBuffer,
-                    JsonFieldData.Count, nullCount, 0);
-            }
-
-            private ArrowBuffer GetOffsetBuffer()
-            {
-                ArrowBuffer.Builder<int> valueOffsets = new ArrowBuffer.Builder<int>(JsonFieldData.Offset.Count);
-                valueOffsets.AppendRange(JsonFieldData.IntOffset);
-                return valueOffsets.Build(default);
-            }
-
-            private ArrowBuffer GetLargeOffsetBuffer()
-            {
-                ArrowBuffer.Builder<long> valueOffsets = new ArrowBuffer.Builder<long>(JsonFieldData.Offset.Count);
-                valueOffsets.AppendRange(JsonFieldData.LongOffset);
-                return valueOffsets.Build(default);
-            }
-
-            private ArrowBuffer GetSizeBuffer()
-            {
-                ArrowBuffer.Builder<int> valueSizes = new ArrowBuffer.Builder<int>(JsonFieldData.Size.Count);
-                valueSizes.AppendRange(JsonFieldData.IntSize);
-                return valueSizes.Build(default);
-            }
-
-            private ArrowBuffer GetTypeIdBuffer()
-            {
-                ArrowBuffer.Builder<byte> typeIds = new ArrowBuffer.Builder<byte>(JsonFieldData.TypeId.Length);
-                for (int i = 0; i < JsonFieldData.TypeId.Length; i++)
-                {
-                    typeIds.Append(checked((byte)JsonFieldData.TypeId[i]));
-                }
-                return typeIds.Build(default);
-            }
-
-            private ArrowBuffer GetValidityBuffer(out int nullCount)
-            {
-                if (JsonFieldData.Validity == null)
-                {
-                    nullCount = 0;
-                    return ArrowBuffer.Empty;
-                }
-
-                ArrowBuffer.BitmapBuilder validityBuilder = new ArrowBuffer.BitmapBuilder(JsonFieldData.Validity.Length);
-                validityBuilder.AppendRange(JsonFieldData.Validity);
-
-                nullCount = validityBuilder.UnsetBitCount;
-                return validityBuilder.Build();
-            }
-
-            public void Visit(IArrowType type)
-            {
-                throw new NotImplementedException($"{type.Name} not implemented");
-            }
-        }
-    }
-
-    public class JsonFieldData
-    {
-        public string Name { get; set; }
-        public int Count { get; set; }
-        public bool[] Validity { get; set; }
-        public JsonArray Offset { get; set; }
-
-        [JsonPropertyName("SIZE")]
-        public JsonArray Size { get; set; }
-        public int[] TypeId { get; set; }
-        public JsonElement Data { get; set; }
-        public List<JsonFieldData> Children { get; set; }
-
-        [JsonPropertyName("VIEWS")]
-        public List<JsonView> Views { get; set; }
-
-        [JsonPropertyName("VARIADIC_DATA_BUFFERS")]
-        public List<string> VariadicDataBuffers { get; set; }
-
-        [JsonIgnore]
-        public IEnumerable<int> IntOffset
-        {
-            get { return Offset.Select(GetInt); }
-        }
-
-        [JsonIgnore]
-        public IEnumerable<long> LongOffset
-        {
-            get { return Offset.Select(GetLong); }
-        }
-
-        [JsonIgnore]
-        public IEnumerable<int> IntSize
-        {
-            get { return Size.Select(GetInt); }
-        }
-
-        static int GetInt(JsonNode node)
-        {
-            try
-            {
-                return node.GetValue<int>();
-            }
-            catch
-            {
-                return int.Parse(node.GetValue<string>());
-            }
-        }
-
-        static long GetLong(JsonNode node)
-        {
-            try
-            {
-                return node.GetValue<long>();
-            }
-            catch
-            {
-                return long.Parse(node.GetValue<string>());
-            }
-        }
-    }
-
-    public class JsonView
-    {
-        [JsonPropertyName("SIZE")]
-        public int Size { get; set; }
-
-        [JsonPropertyName("INLINED")]
-        public string Inlined { get; set; }
-
-        [JsonPropertyName("PREFIX_HEX")]
-        public string PrefixHex { get; set; }
-
-        [JsonPropertyName("BUFFER_INDEX")]
-        public int? BufferIndex { get; set; }
-
-        [JsonPropertyName("OFFSET")]
-        public int? Offset { get; set; }
-    }
-
-    internal sealed class ValidityConverter : JsonConverter<bool>
-    {
-        public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
-        {
-            if (reader.TokenType == JsonTokenType.True) return true;
-            if (reader.TokenType == JsonTokenType.False) return false;
-
-            if (typeToConvert != typeof(bool) || reader.TokenType != JsonTokenType.Number)
-            {
-                throw new InvalidOperationException($"Unexpected bool data: {reader.TokenType}");
-            }
-
-            int value = reader.GetInt32();
-            if (value == 0) return false;
-            if (value == 1) return true;
-
-            throw new InvalidOperationException($"Unexpected bool value: {value}");
-        }
-
-        public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options) => throw new NotImplementedException();
-    }
-
-    internal sealed class ByteArrayConverter : JsonConverter<byte[]>
-    {
-        public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
-        {
-            if (reader.TokenType != JsonTokenType.StartArray)
-            {
-                throw new InvalidOperationException($"Unexpected byte[] token: {reader.TokenType}");
-            }
-
-            List<byte> values = new List<byte>();
-            while (reader.Read())
-            {
-                if (reader.TokenType == JsonTokenType.EndArray)
-                {
-                    return values.ToArray();
-                }
-
-                if (reader.TokenType != JsonTokenType.Number)
-                {
-                    throw new InvalidOperationException($"Unexpected byte token: {reader.TokenType}");
-                }
-
-                values.Add(reader.GetByte());
-            }
-
-            throw new InvalidOperationException("Unexpectedly reached the end of the reader");
-        }
-
-        public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options) => throw new NotImplementedException();
-    }
-
-    internal sealed class JsonFileNamingPolicy : JsonNamingPolicy
-    {
-        public static JsonFileNamingPolicy Instance { get; } = new JsonFileNamingPolicy();
-
-        public override string ConvertName(string name)
-        {
-            if (name == "Validity")
-            {
-                return "VALIDITY";
-            }
-            else if (name == "Offset")
-            {
-                return "OFFSET";
-            }
-            else if (name == "TypeId")
-            {
-                return "TYPE_ID";
-            }
-            else if (name == "Data")
-            {
-                return "DATA";
-            }
-            else
-            {
-                return CamelCase.ConvertName(name);
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.IntegrationTest/Program.cs b/csharp/test/Apache.Arrow.IntegrationTest/Program.cs
deleted file mode 100644
index 2432693..0000000
--- a/csharp/test/Apache.Arrow.IntegrationTest/Program.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.CommandLine;
-using System.CommandLine.Invocation;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Apache.Arrow.IntegrationTest
-{
-    public class Program
-    {
-        public static async Task<int> Main(string[] args)
-        {
-            var integrationTestCommand = new RootCommand
-            {
-                new Option<string>(
-                    "--mode",
-                    description: "Which command to run"),
-                new Option<FileInfo>(
-                    new[] { "--json-file", "-j" },
-                    "The JSON file to interact with"),
-                new Option<FileInfo>(
-                    new[] { "--arrow-file", "-a" },
-                    "The arrow file to interact with")
-            };
-
-            integrationTestCommand.Description = "Integration test app for Apache.Arrow .NET Library.";
-
-            integrationTestCommand.Handler = CommandHandler.Create<string, FileInfo, FileInfo>(async (mode, j, a) =>
-            {
-                var integrationCommand = new IntegrationCommand(mode, j, a);
-                await integrationCommand.Execute();
-            });
-            return await integrationTestCommand.InvokeAsync(args);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/Apache.Arrow.Tests.csproj b/csharp/test/Apache.Arrow.Tests/Apache.Arrow.Tests.csproj
deleted file mode 100644
index 3b3224f..0000000
--- a/csharp/test/Apache.Arrow.Tests/Apache.Arrow.Tests.csproj
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <!-- Required for PythonNET -->
-    <EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
-  </PropertyGroup>
-
-  <PropertyGroup Condition="'$(IsWindows)'=='true'">
-    <TargetFrameworks>net8.0;net472;net462</TargetFrameworks>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(IsWindows)'!='true'">
-    <TargetFrameworks>net8.0</TargetFrameworks>
-  </PropertyGroup>
-
-  <ItemGroup Condition="'$(TargetFramework)' == 'net462'">
-    <PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
-      <PrivateAssets>all</PrivateAssets>
-      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
-    </PackageReference>
-  </ItemGroup>
-  <ItemGroup Condition="'$(TargetFramework)' != 'net462'">
-    <PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">
-      <PrivateAssets>all</PrivateAssets>
-      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
-    </PackageReference>
-  </ItemGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
-    <PackageReference Include="xunit" Version="2.9.3" />
-    <PackageReference Include="xunit.skippablefact" Version="1.5.23" />
-    <PackageReference Include="pythonnet" Version="3.0.5" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\..\src\Apache.Arrow\Apache.Arrow.csproj" />
-  </ItemGroup>
-
-  <ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible($(TargetFramework), 'net6.0'))">
-    <Compile Remove="TimeOnlyTests.cs" />
-  </ItemGroup>
-
-  <ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible($(TargetFramework), 'net5.0'))">
-    <Compile Remove="Extensions\Net472Extensions.cs" />
-  </ItemGroup>
-
-</Project>
diff --git a/csharp/test/Apache.Arrow.Tests/ArrayBuilderTests.cs b/csharp/test/Apache.Arrow.Tests/ArrayBuilderTests.cs
deleted file mode 100644
index f789d6a..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrayBuilderTests.cs
+++ /dev/null
@@ -1,456 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ArrayBuilderTests
-    {
-        // TODO: Test various builder invariants (Append, AppendRange, Clear, Resize, Reserve, etc)
-
-#if NET5_0_OR_GREATER
-        [Fact]
-        public void PrimitiveArrayBuildersProduceExpectedArray()
-        {
-            Test<sbyte, Int8Array, Int8Array.Builder>();
-            Test<short, Int16Array, Int16Array.Builder>();
-            Test<int, Int32Array, Int32Array.Builder>();
-            Test<long, Int64Array, Int64Array.Builder>();
-            Test<byte, UInt8Array, UInt8Array.Builder>();
-            Test<ushort, UInt16Array, UInt16Array.Builder>();
-            Test<uint, UInt32Array, UInt32Array.Builder>();
-            Test<ulong, UInt64Array, UInt64Array.Builder>();
-            Test<Half, HalfFloatArray, HalfFloatArray.Builder>();
-            Test<float, FloatArray, FloatArray.Builder>();
-            Test<double, DoubleArray, DoubleArray.Builder>();
-            TestArrayBuilder<Time32Array, Time32Array.Builder>(x => x.Append(10).Append(20).Append(30));
-            TestArrayBuilder<Time64Array, Time64Array.Builder>(x => x.Append(10).Append(20).Append(30));
-
-            static void Test<T, TArray, TBuilder>()
-                where T : struct, INumber<T>
-                where TArray : PrimitiveArray<T>
-                where TBuilder : PrimitiveArrayBuilder<T, TArray, TBuilder>, new() =>
-                TestArrayBuilder<TArray, TBuilder>(x => x.Append(T.CreateChecked(10)).Append(T.CreateChecked(20)).Append(T.CreateChecked(30)));
-        }
-
-        [Fact]
-        public void PrimitiveArrayBuildersProduceExpectedArrayWithNulls()
-        {
-            Test<sbyte, Int8Array, Int8Array.Builder>();
-            Test<short, Int16Array, Int16Array.Builder>();
-            Test<int, Int32Array, Int32Array.Builder>();
-            Test<long, Int64Array, Int64Array.Builder>();
-            Test<byte, UInt8Array, UInt8Array.Builder>();
-            Test<ushort, UInt16Array, UInt16Array.Builder>();
-            Test<uint, UInt32Array, UInt32Array.Builder>();
-            Test<ulong, UInt64Array, UInt64Array.Builder>();
-            Test<Half, HalfFloatArray, HalfFloatArray.Builder>();
-            Test<float, FloatArray, FloatArray.Builder>();
-            Test<double, DoubleArray, DoubleArray.Builder>();
-            TestArrayBuilder<Time32Array, Time32Array.Builder>(x => x.Append(123).AppendNull().AppendNull().Append(127), 4, 2, 0x9);
-            TestArrayBuilder<Time64Array, Time64Array.Builder>(x => x.Append(123).AppendNull().AppendNull().Append(127), 4, 2, 0x9);
-
-            static void Test<T, TArray, TBuilder>()
-                where T : struct, INumber<T>
-                where TArray : PrimitiveArray<T>
-                where TBuilder : PrimitiveArrayBuilder<T, TArray, TBuilder>, new() =>
-                TestArrayBuilder<TArray, TBuilder>(x => x.Append(T.CreateChecked(123)).AppendNull().AppendNull().Append(T.CreateChecked(127)), 4, 2, 0x09);
-        }
-#endif
-
-        [Fact]
-        public void BooleanArrayBuilderProducersExpectedArray()
-        {
-            TestArrayBuilder<BooleanArray, BooleanArray.Builder>(x => x.Append(true).Append(false).Append(true));
-            TestArrayBuilder<BooleanArray, BooleanArray.Builder>(x => x.Append(true).AppendNull().Append(false).Append(true), 4, 1, 0x0D);
-        }
-
-        [Fact]
-        public void StringArrayBuilderHandlesNullsAndEmptyStrings()
-        {
-            var stringArray = TestArrayBuilder<StringArray, StringArray.Builder>(x => x.Append("123").Append(null).AppendNull().Append(string.Empty), 4, 2, 0x09);
-            Assert.Equal("123", stringArray.GetString(0));
-            Assert.Null(stringArray.GetString(1));
-            Assert.Null(stringArray.GetString(2));
-            Assert.Equal(string.Empty, stringArray.GetString(3));
-        }
-
-
-        [Fact]
-        public void ListArrayBuilder()
-        {
-            var listBuilder = new ListArray.Builder(StringType.Default);
-            var valueBuilder = listBuilder.ValueBuilder as StringArray.Builder;
-            Assert.NotNull(valueBuilder);
-            listBuilder.Append();
-            valueBuilder.Append("1");
-            listBuilder.AppendNull();
-            listBuilder.Append();
-            valueBuilder.Append("22").Append("33");
-            listBuilder.Append();
-            valueBuilder.Append("444").AppendNull().Append("555").Append("666");
-
-            var list = listBuilder.Build();
-
-            Assert.Equal(
-                new List<string> { "1" },
-                ConvertStringArrayToList(list.GetSlicedValues(0) as StringArray));
-            Assert.Null(list.GetSlicedValues(1));
-            Assert.Equal(
-                new List<string> { "22", "33" },
-                ConvertStringArrayToList(list.GetSlicedValues(2) as StringArray));
-            Assert.Equal(
-                new List<string> { "444", null, "555", "666" },
-                ConvertStringArrayToList(list.GetSlicedValues(3) as StringArray));
-
-            Assert.Throws<ArgumentOutOfRangeException>(() => list.GetValueLength(-1));
-            Assert.Throws<ArgumentOutOfRangeException>(() => list.GetValueLength(4));
-
-            listBuilder.Resize(2);
-            var truncatedList = listBuilder.Build();
-
-            Assert.Equal(
-                new List<string> { "22", "33", "444", null, "555", "666" },
-                ConvertStringArrayToList(truncatedList.GetSlicedValues(2) as StringArray));
-
-            Assert.Throws<ArgumentOutOfRangeException>(() => truncatedList.GetSlicedValues(-1));
-            Assert.Throws<ArgumentOutOfRangeException>(() => truncatedList.GetSlicedValues(3));
-
-            listBuilder.Clear();
-            var emptyList = listBuilder.Build();
-
-            Assert.Equal(0, emptyList.Length);
-
-            List<string> ConvertStringArrayToList(StringArray array)
-            {
-                var length = array.Length;
-                var resultList = new List<string>(length);
-                for (var index = 0; index < length; index++)
-                {
-                    resultList.Add(array.GetString(index));
-                }
-                return resultList;
-            }
-        }
-
-        [Fact]
-        public void ListArrayBuilderValidityBuffer()
-        {
-            ListArray listArray = new ListArray.Builder(Int64Type.Default).Append().AppendNull().Build();
-            Assert.False(listArray.IsValid(2));
-        }
-
-        [Fact]
-        public void NestedListArrayBuilder()
-        {
-            var childListType = new ListType(Int64Type.Default);
-            var parentListBuilder = new ListArray.Builder((IArrowType)childListType);
-            var childListBuilder = parentListBuilder.ValueBuilder as ListArray.Builder;
-            Assert.NotNull(childListBuilder);
-            var valueBuilder = childListBuilder.ValueBuilder as Int64Array.Builder;
-            Assert.NotNull(valueBuilder);
-
-            parentListBuilder.Append();
-            childListBuilder.Append();
-            valueBuilder.Append(1);
-            childListBuilder.Append();
-            valueBuilder.Append(2).Append(3);
-            parentListBuilder.Append();
-            childListBuilder.Append();
-            valueBuilder.Append(4).Append(5).Append(6).Append(7);
-            parentListBuilder.Append();
-            childListBuilder.Append();
-            valueBuilder.Append(8).Append(9).Append(10).Append(11).Append(12);
-
-            var parentList = parentListBuilder.Build();
-
-            var childList1 = (ListArray)parentList.GetSlicedValues(0);
-            var childList2 = (ListArray)parentList.GetSlicedValues(1);
-            var childList3 = (ListArray)parentList.GetSlicedValues(2);
-
-            Assert.Equal(2, childList1.Length);
-            Assert.Equal(1, childList2.Length);
-            Assert.Equal(1, childList3.Length);
-            Assert.Equal(
-                new List<long?> { 1 },
-                ((Int64Array)childList1.GetSlicedValues(0)).ToList());
-            Assert.Equal(
-                new List<long?> { 2, 3 },
-                ((Int64Array)childList1.GetSlicedValues(1)).ToList());
-            Assert.Equal(
-                new List<long?> { 4, 5, 6, 7 },
-                ((Int64Array)childList2.GetSlicedValues(0)).ToList());
-            Assert.Equal(
-                new List<long?> { 8, 9, 10, 11, 12 },
-                ((Int64Array)childList3.GetSlicedValues(0)).ToList());
-        }
-
-        [Fact]
-        public void FixedSizeListArrayBuilder()
-        {
-            var listBuilder = new FixedSizeListArray.Builder(StringType.Default, 4);
-            var valueBuilder = listBuilder.ValueBuilder as StringArray.Builder;
-            Assert.NotNull(valueBuilder);
-            listBuilder.Append();
-
-            Assert.Throws<ArgumentOutOfRangeException>(listBuilder.Append);
-
-            valueBuilder.Append("1");
-            valueBuilder.Append("2");
-            valueBuilder.Append("3");
-            valueBuilder.Append("4");
-            listBuilder.AppendNull();
-            listBuilder.Append();
-            valueBuilder.Append("5").Append("6").Append("7").Append("8");
-            listBuilder.Append();
-            valueBuilder.Append("444").AppendNull().Append("555").Append("666");
-
-            var list = listBuilder.Build();
-
-            Assert.Equal(
-                new List<string> { "1", "2", "3", "4" },
-                ConvertStringArrayToList(list.GetSlicedValues(0) as StringArray));
-            Assert.Null(list.GetSlicedValues(1));
-            Assert.Equal(
-                new List<string> { "5", "6", "7", "8" },
-                ConvertStringArrayToList(list.GetSlicedValues(2) as StringArray));
-            Assert.Equal(
-                new List<string> { "444", null, "555", "666" },
-                ConvertStringArrayToList(list.GetSlicedValues(3) as StringArray));
-
-            Assert.Throws<ArgumentOutOfRangeException>(() => list.GetSlicedValues(-1));
-            Assert.Throws<ArgumentOutOfRangeException>(() => list.GetSlicedValues(4));
-
-            listBuilder.Resize(3);
-            var truncatedList = listBuilder.Build();
-
-            Assert.Equal(
-                new List<string> { "5", "6", "7", "8" },
-                ConvertStringArrayToList(truncatedList.GetSlicedValues(2) as StringArray));
-
-            Assert.Throws<ArgumentOutOfRangeException>(() => truncatedList.GetSlicedValues(-1));
-            Assert.Throws<ArgumentOutOfRangeException>(() => truncatedList.GetSlicedValues(3));
-
-            listBuilder.Clear();
-            var emptyList = listBuilder.Build();
-
-            Assert.Equal(0, emptyList.Length);
-
-            List<string> ConvertStringArrayToList(StringArray array)
-            {
-                var length = array.Length;
-                var resultList = new List<string>(length);
-                for (var index = 0; index < length; index++)
-                {
-                    resultList.Add(array.GetString(index));
-                }
-                return resultList;
-            }
-        }
-
-        [Fact]
-        public void FixedSizeListArrayBuilderValidityBuffer()
-        {
-            FixedSizeListArray.Builder builder = new FixedSizeListArray.Builder(Int64Type.Default, 2).Append();
-            ((Int64Array.Builder)builder.ValueBuilder).Append(1).Append(2);
-            FixedSizeListArray listArray = builder.AppendNull().Build();
-            Assert.False(listArray.IsValid(2));
-        }
-
-        [Fact]
-        public void NestedFixedSizeListArrayBuilder()
-        {
-            var childListType = new FixedSizeListType(Int64Type.Default, 2);
-            var parentListBuilder = new FixedSizeListArray.Builder(childListType, 3);
-            var childListBuilder = parentListBuilder.ValueBuilder as FixedSizeListArray.Builder;
-            Assert.NotNull(childListBuilder);
-            var valueBuilder = childListBuilder.ValueBuilder as Int64Array.Builder;
-            Assert.NotNull(valueBuilder);
-
-            parentListBuilder.Append();
-            childListBuilder.Append();
-            valueBuilder.Append(1);
-            valueBuilder.Append(2);
-            childListBuilder.Append();
-            valueBuilder.Append(3).Append(4);
-            childListBuilder.AppendNull();
-            parentListBuilder.Append();
-            childListBuilder.Append();
-            valueBuilder.Append(4).Append(5);
-            childListBuilder.Append();
-            valueBuilder.Append(6).Append(7);
-            childListBuilder.Append();
-            valueBuilder.Append(8).Append(9);
-            parentListBuilder.Append();
-            childListBuilder.Append();
-            valueBuilder.Append(10).Append(11);
-            childListBuilder.AppendNull();
-            childListBuilder.Append();
-            valueBuilder.Append(12).AppendNull();
-
-            var parentList = parentListBuilder.Build();
-
-            var childList1 = (FixedSizeListArray)parentList.GetSlicedValues(0);
-            var childList2 = (FixedSizeListArray)parentList.GetSlicedValues(1);
-            var childList3 = (FixedSizeListArray)parentList.GetSlicedValues(2);
-
-            Assert.Equal(3, childList1.Length);
-            Assert.Equal(3, childList2.Length);
-            Assert.Equal(3, childList3.Length);
-            Assert.Equal(
-                new List<long?> { 1, 2 },
-                ((Int64Array)childList1.GetSlicedValues(0)).ToList());
-            Assert.Equal(
-                new List<long?> { 3, 4 },
-                ((Int64Array)childList1.GetSlicedValues(1)).ToList());
-            Assert.Equal(
-                new List<long?> { 4, 5 },
-                ((Int64Array)childList2.GetSlicedValues(0)).ToList());
-            Assert.Equal(
-                new List<long?> { 12, null },
-                ((Int64Array)childList3.GetSlicedValues(2)).ToList(includeNulls: true));
-        }
-
-        public class TimestampArrayBuilder
-        {
-            [Fact]
-            public void ProducesExpectedArray()
-            {
-                var now = DateTimeOffset.UtcNow.ToLocalTime();
-                var timestampType = new TimestampType(TimeUnit.Nanosecond, TimeZoneInfo.Local);
-                var array = new TimestampArray.Builder(timestampType)
-                    .Append(now)
-                    .Build();
-
-                Assert.Equal(1, array.Length);
-                var value = array.GetTimestamp(0);
-                Assert.NotNull(value);
-                Assert.Equal(now, value.Value);
-
-                timestampType = new TimestampType(TimeUnit.Microsecond, TimeZoneInfo.Local);
-                array = new TimestampArray.Builder(timestampType)
-                    .Append(now)
-                    .Build();
-
-                Assert.Equal(1, array.Length);
-                value = array.GetTimestamp(0);
-                Assert.NotNull(value);
-                Assert.Equal(now.Truncate(TimeSpan.FromTicks(10)), value.Value);
-
-                timestampType = new TimestampType(TimeUnit.Millisecond, TimeZoneInfo.Local);
-                array = new TimestampArray.Builder(timestampType)
-                    .Append(now)
-                    .Build();
-
-                Assert.Equal(1, array.Length);
-                value = array.GetTimestamp(0);
-                Assert.NotNull(value);
-                Assert.Equal(now.Truncate(TimeSpan.FromTicks(TimeSpan.TicksPerMillisecond)), value.Value);
-            }
-        }
-
-        public class Time32ArrayBuilder
-        {
-            [Fact]
-            public void ProducesExpectedArray()
-            {
-                var time32Type = new Time32Type(TimeUnit.Second);
-                var array = new Time32Array.Builder(time32Type)
-                    .Append(1)
-                    .Build();
-
-                Assert.Equal(1, array.Length);
-                var valueSeconds = array.GetSeconds(0);
-                Assert.NotNull(valueSeconds);
-                Assert.Equal(1, valueSeconds.Value);
-                var valueMilliSeconds = array.GetMilliSeconds(0);
-                Assert.NotNull(valueMilliSeconds);
-                Assert.Equal(1_000, valueMilliSeconds.Value);
-
-                time32Type = new Time32Type(TimeUnit.Millisecond);
-                array = new Time32Array.Builder(time32Type)
-                    .Append(1_000)
-                    .Build();
-
-                Assert.Equal(1, array.Length);
-                valueSeconds = array.GetSeconds(0);
-                Assert.NotNull(valueSeconds);
-                Assert.Equal(1, valueSeconds.Value);
-                valueMilliSeconds = array.GetMilliSeconds(0);
-                Assert.NotNull(valueMilliSeconds);
-                Assert.Equal(1_000, valueMilliSeconds.Value);
-            }
-        }
-
-        public class Time64ArrayBuilder
-        {
-            [Fact]
-            public void ProducesExpectedArray()
-            {
-                var time64Type = new Time64Type(TimeUnit.Microsecond);
-                var array = new Time64Array.Builder(time64Type)
-                    .Append(1_000_000)
-                    .Build();
-
-                Assert.Equal(1, array.Length);
-                var valueMicroSeconds = array.GetMicroSeconds(0);
-                Assert.NotNull(valueMicroSeconds);
-                Assert.Equal(1_000_000, valueMicroSeconds.Value);
-                var valueNanoSeconds = array.GetNanoSeconds(0);
-                Assert.NotNull(valueNanoSeconds);
-                Assert.Equal(1_000_000_000, valueNanoSeconds.Value);
-
-                time64Type = new Time64Type(TimeUnit.Nanosecond);
-                array = new Time64Array.Builder(time64Type)
-                    .Append(1_000_000_000)
-                    .Build();
-
-                Assert.Equal(1, array.Length);
-                valueMicroSeconds = array.GetMicroSeconds(0);
-                Assert.NotNull(valueMicroSeconds);
-                Assert.Equal(1_000_000, valueMicroSeconds.Value);
-                valueNanoSeconds = array.GetNanoSeconds(0);
-                Assert.NotNull(valueNanoSeconds);
-                Assert.Equal(1_000_000_000, valueNanoSeconds.Value);
-            }
-        }
-
-        private static TArray TestArrayBuilder<TArray, TArrayBuilder>(Action<TArrayBuilder> action, int expectedLength = 3, int expectedNullCount = 0, int expectedNulls = 0)
-            where TArray : IArrowArray
-            where TArrayBuilder : IArrowArrayBuilder<TArray>, new()
-        {
-            var builder = new TArrayBuilder();
-            action(builder);
-            var array = builder.Build(default);
-
-            Assert.IsAssignableFrom<TArray>(array);
-            Assert.NotNull(array);
-            Assert.Equal(expectedLength, array.Length);
-            Assert.Equal(expectedNullCount, array.NullCount);
-            if (expectedNulls != 0)
-            {
-                Assert.True(array.Data.Buffers[0].Span.Slice(0, 1).SequenceEqual(new ReadOnlySpan<byte>(BitConverter.GetBytes(expectedNulls).Take(1).ToArray())));
-            }
-            return array;
-        }
-
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ArrayDataConcatenatorTests.cs b/csharp/test/Apache.Arrow.Tests/ArrayDataConcatenatorTests.cs
deleted file mode 100644
index 86719f3..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrayDataConcatenatorTests.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using Apache.Arrow.Memory;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ArrayDataConcatenatorTests
-    {
-        [Fact]
-        public void TestNullOrEmpty()
-        {
-            Assert.Null(ArrayDataConcatenator.Concatenate(null));
-            Assert.Null(ArrayDataConcatenator.Concatenate(new List<ArrayData>()));
-        }
-
-        [Fact]
-        public void TestSingleElement()
-        {
-            Int32Array array = new Int32Array.Builder().Append(1).Append(2).Build();
-            ArrayData actualArray = ArrayDataConcatenator.Concatenate(new[] { array.Data });
-            ArrowReaderVerifier.CompareArrays(array, ArrowArrayFactory.BuildArray(actualArray));
-        }
-
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ArrayTypeComparer.cs b/csharp/test/Apache.Arrow.Tests/ArrayTypeComparer.cs
deleted file mode 100644
index ceeffe4..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrayTypeComparer.cs
+++ /dev/null
@@ -1,152 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Diagnostics;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ArrayTypeComparer :
-        IArrowTypeVisitor<TimestampType>,
-        IArrowTypeVisitor<Date32Type>,
-        IArrowTypeVisitor<Date64Type>,
-        IArrowTypeVisitor<TimeBasedType>,
-        IArrowTypeVisitor<FixedSizeBinaryType>,
-        IArrowTypeVisitor<ListType>,
-        IArrowTypeVisitor<FixedSizeListType>,
-        IArrowTypeVisitor<StructType>,
-        IArrowTypeVisitor<UnionType>,
-        IArrowTypeVisitor<MapType>
-    {
-        private readonly IArrowType _expectedType;
-
-        public ArrayTypeComparer(IArrowType expectedType)
-        {
-            Debug.Assert(expectedType != null);
-            _expectedType = expectedType;
-        }
-
-        public void Visit(TimestampType actualType)
-        {
-            Assert.IsAssignableFrom<TimestampType>(_expectedType);
-
-            var expectedType = (TimestampType)_expectedType;
-
-            Assert.Equal(expectedType.Timezone, actualType.Timezone);
-            Assert.Equal(expectedType.Unit, actualType.Unit);
-        }
-
-        public void Visit(Date32Type actualType)
-        {
-            Assert.IsAssignableFrom<Date32Type>(_expectedType);
-            var expectedType = (Date32Type)_expectedType;
-
-            Assert.Equal(expectedType.Unit, actualType.Unit);
-        }
-
-        public void Visit(Date64Type actualType)
-        {
-            Assert.IsAssignableFrom<Date64Type>(_expectedType);
-            var expectedType = (Date64Type)_expectedType;
-
-            Assert.Equal(expectedType.Unit, actualType.Unit);
-        }
-
-        public void Visit(TimeBasedType actualType)
-        {
-            Assert.IsAssignableFrom<TimeBasedType>(_expectedType);
-            Assert.Equal(_expectedType.TypeId, actualType.TypeId);
-            var expectedType = (TimeBasedType)_expectedType;
-
-            Assert.Equal(expectedType.Unit, actualType.Unit);
-        }
-
-        public void Visit(FixedSizeBinaryType actualType)
-        {
-            Assert.IsAssignableFrom<FixedSizeBinaryType>(_expectedType);
-            var expectedType = (FixedSizeBinaryType)_expectedType;
-
-            Assert.Equal(expectedType.ByteWidth, actualType.ByteWidth);
-        }
-
-        public void Visit(ListType actualType)
-        {
-            Assert.IsAssignableFrom<ListType>(_expectedType);
-            var expectedType = (ListType)_expectedType;
-
-            CompareNested(expectedType, actualType);
-        }
-
-        public void Visit(FixedSizeListType actualType)
-        {
-            Assert.IsAssignableFrom<FixedSizeListType>(_expectedType);
-            var expectedType = (FixedSizeListType)_expectedType;
-
-            Assert.Equal(expectedType.ListSize, actualType.ListSize);
-
-            CompareNested(expectedType, actualType);
-        }
-
-        public void Visit(StructType actualType)
-        {
-            Assert.IsAssignableFrom<StructType>(_expectedType);
-            var expectedType = (StructType)_expectedType;
-
-            CompareNested(expectedType, actualType);
-        }
-
-        public void Visit(UnionType actualType)
-        {
-            Assert.IsAssignableFrom<UnionType>(_expectedType);
-            UnionType expectedType = (UnionType)_expectedType;
-
-            Assert.Equal(expectedType.Mode, actualType.Mode);
-
-            Assert.Equal(expectedType.TypeIds.Length, actualType.TypeIds.Length);
-            for (int i = 0; i < expectedType.TypeIds.Length; i++)
-            {
-                Assert.Equal(expectedType.TypeIds[i], actualType.TypeIds[i]);
-            }
-
-            CompareNested(expectedType, actualType);
-        }
-
-        public void Visit(MapType actualType)
-        {
-            Assert.IsAssignableFrom<MapType>(_expectedType);
-            var expectedType = (MapType)_expectedType;
-
-            Assert.Equal(expectedType.KeySorted, actualType.KeySorted);
-
-            CompareNested(expectedType, actualType);
-        }
-
-        private static void CompareNested(NestedType expectedType, NestedType actualType)
-        {
-            Assert.Equal(expectedType.Fields.Count, actualType.Fields.Count);
-
-            for (int i = 0; i < expectedType.Fields.Count; i++)
-            {
-                FieldComparer.Compare(expectedType.Fields[i], actualType.Fields[i]);
-            }
-        }
-
-        public void Visit(IArrowType actualType)
-        {
-            Assert.IsAssignableFrom(actualType.GetType(), _expectedType);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowArrayConcatenatorTests.cs b/csharp/test/Apache.Arrow.Tests/ArrowArrayConcatenatorTests.cs
deleted file mode 100644
index a45a50c..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrowArrayConcatenatorTests.cs
+++ /dev/null
@@ -1,607 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Apache.Arrow.Scalars;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ArrowArrayConcatenatorTests
-    {
-        [Fact]
-        public void TestStandardCases()
-        {
-            foreach ((List<IArrowArray> testTargetArrayList, IArrowArray expectedArray) in GenerateTestData())
-            {
-                IArrowArray actualArray = ArrowArrayConcatenator.Concatenate(testTargetArrayList);
-                ArrowReaderVerifier.CompareArrays(expectedArray, actualArray);
-            }
-        }
-
-        [Fact]
-        public void TestConcatenateSlices()
-        {
-            foreach ((List<IArrowArray> testTargetArrayList, IArrowArray expectedArray) in GenerateTestData(slicedArrays: true))
-            {
-                IArrowArray actualArray = ArrowArrayConcatenator.Concatenate(testTargetArrayList);
-                ArrowReaderVerifier.CompareArrays(expectedArray, actualArray, strictCompare: false);
-            }
-        }
-
-        [Fact]
-        public void TestNullOrEmpty()
-        {
-            Assert.Null(ArrowArrayConcatenator.Concatenate(null));
-            Assert.Null(ArrowArrayConcatenator.Concatenate(new List<IArrowArray>()));
-        }
-
-        [Fact]
-        public void TestSingleElement()
-        {
-            Int32Array array = new Int32Array.Builder().Append(1).Append(2).Build();
-            IArrowArray actualArray = ArrowArrayConcatenator.Concatenate(new[] { array });
-            ArrowReaderVerifier.CompareArrays(array, actualArray);
-        }
-
-        private static IEnumerable<Tuple<List<IArrowArray>, IArrowArray>> GenerateTestData(bool slicedArrays = false)
-        {
-            var targetTypes = new List<IArrowType>() {
-                    BooleanType.Default,
-                    Int8Type.Default,
-                    Int16Type.Default,
-                    Int32Type.Default,
-                    Int64Type.Default,
-                    UInt8Type.Default,
-                    UInt16Type.Default,
-                    UInt32Type.Default,
-                    UInt64Type.Default,
-                    FloatType.Default,
-                    DoubleType.Default,
-                    BinaryType.Default,
-                    BinaryViewType.Default,
-                    StringType.Default,
-                    StringViewType.Default,
-                    Date32Type.Default,
-                    Date64Type.Default,
-                    TimestampType.Default,
-                    new Decimal32Type(7, 3),
-                    new Decimal64Type(14, 4),
-                    new Decimal128Type(14, 10),
-                    new Decimal256Type(14, 10),
-                    new ListType(Int64Type.Default),
-                    new ListViewType(Int64Type.Default),
-                    new StructType(new List<Field>{
-                        new Field.Builder().Name("Strings").DataType(StringType.Default).Nullable(true).Build(),
-                        new Field.Builder().Name("Ints").DataType(Int32Type.Default).Nullable(true).Build()
-                    }),
-                    new FixedSizeListType(Int32Type.Default, 2),
-                    new UnionType(
-                        new List<Field>{
-                            new Field.Builder().Name("Strings").DataType(StringType.Default).Nullable(true).Build(),
-                            new Field.Builder().Name("Ints").DataType(Int32Type.Default).Nullable(true).Build()
-                        },
-                        new[] { 0, 1 },
-                        UnionMode.Sparse
-                    ),
-                    new UnionType(
-                        new List<Field>{
-                            new Field.Builder().Name("Strings").DataType(StringType.Default).Nullable(true).Build(),
-                            new Field.Builder().Name("Ints").DataType(Int32Type.Default).Nullable(true).Build()
-                        },
-                        new[] { 0, 1 },
-                        UnionMode.Dense
-                    ),
-                    new MapType(
-                        new Field.Builder().Name("key").DataType(StringType.Default).Nullable(false).Build(),
-                        new Field.Builder().Name("value").DataType(Int32Type.Default).Nullable(true).Build(),
-                        keySorted: false),
-                    IntervalType.YearMonth,
-                    IntervalType.DayTime,
-                    IntervalType.MonthDayNanosecond,
-                };
-
-            foreach (IArrowType type in targetTypes)
-            {
-                var creator = new TestDataGenerator(slicedArrays);
-                type.Accept(creator);
-                yield return Tuple.Create(creator.TestTargetArrayList, creator.ExpectedArray);
-            }
-        }
-
-        private class TestDataGenerator :
-            IArrowTypeVisitor<BooleanType>,
-            IArrowTypeVisitor<Int8Type>,
-            IArrowTypeVisitor<Int16Type>,
-            IArrowTypeVisitor<Int32Type>,
-            IArrowTypeVisitor<Int64Type>,
-            IArrowTypeVisitor<UInt8Type>,
-            IArrowTypeVisitor<UInt16Type>,
-            IArrowTypeVisitor<UInt32Type>,
-            IArrowTypeVisitor<UInt64Type>,
-            IArrowTypeVisitor<FloatType>,
-            IArrowTypeVisitor<DoubleType>,
-            IArrowTypeVisitor<BinaryType>,
-            IArrowTypeVisitor<BinaryViewType>,
-            IArrowTypeVisitor<StringType>,
-            IArrowTypeVisitor<StringViewType>,
-            IArrowTypeVisitor<Decimal32Type>,
-            IArrowTypeVisitor<Decimal64Type>,
-            IArrowTypeVisitor<Decimal128Type>,
-            IArrowTypeVisitor<Decimal256Type>,
-            IArrowTypeVisitor<Date32Type>,
-            IArrowTypeVisitor<Date64Type>,
-            IArrowTypeVisitor<DurationType>,
-            IArrowTypeVisitor<IntervalType>,
-            IArrowTypeVisitor<TimestampType>,
-            IArrowTypeVisitor<ListType>,
-            IArrowTypeVisitor<ListViewType>,
-            IArrowTypeVisitor<FixedSizeListType>,
-            IArrowTypeVisitor<StructType>,
-            IArrowTypeVisitor<UnionType>,
-            IArrowTypeVisitor<MapType>
-        {
-            private readonly List<List<int?>> _baseData;
-
-            private readonly int _baseDataListCount;
-
-            private readonly int _resultTotalElementCount;
-
-            private readonly List<(int Offset, int Length)> _sliceParameters = null;
-
-            public List<IArrowArray> TestTargetArrayList { get; }
-            public IArrowArray ExpectedArray { get; private set; }
-
-            public TestDataGenerator(bool slicedArrays)
-            {
-                _baseData = new List<List<int?>> {
-                    new List<int?> { 1, 2, 3, 4, 5, 6 },
-                    new List<int?> { 100, 101, null, 102, null, 103 },
-                    new List<int?> { null, null },
-                    new List<int?> { },
-                    new List<int?> { 11, null, 12, 13, 14 },
-                };
-
-                if (slicedArrays)
-                {
-                    _sliceParameters = new List<(int, int)>
-                    {
-                        (2, 3),
-                        (0, 5),
-                        (0, 2),
-                        (0, 0),
-                        (1, 4),
-                    };
-                }
-
-                _baseDataListCount = _baseData.Count;
-                _resultTotalElementCount = slicedArrays
-                    ? _sliceParameters.Sum(p => p.Length)
-                    : _baseData.Sum(baseList => baseList.Count);
-
-                TestTargetArrayList = new List<IArrowArray>(_baseDataListCount);
-            }
-
-            public void Visit(BooleanType type) => GenerateTestData<bool, BooleanArray, BooleanArray.Builder>(type, x => x % 2 == 0);
-            public void Visit(Int8Type type) => GenerateTestData<sbyte, Int8Array, Int8Array.Builder>(type, x => (sbyte)x);
-            public void Visit(Int16Type type) => GenerateTestData<short, Int16Array, Int16Array.Builder>(type, x => (short)x);
-            public void Visit(Int32Type type) => GenerateTestData<int, Int32Array, Int32Array.Builder>(type, x => x);
-            public void Visit(Int64Type type) => GenerateTestData<long, Int64Array, Int64Array.Builder>(type, x => x);
-            public void Visit(UInt8Type type) => GenerateTestData<byte, UInt8Array, UInt8Array.Builder>(type, x => (byte)x);
-            public void Visit(UInt16Type type) => GenerateTestData<ushort, UInt16Array, UInt16Array.Builder>(type, x => (ushort)x);
-            public void Visit(UInt32Type type) => GenerateTestData<uint, UInt32Array, UInt32Array.Builder>(type, x => (uint)x);
-            public void Visit(UInt64Type type) => GenerateTestData<ulong, UInt64Array, UInt64Array.Builder>(type, x => (ulong)x);
-            public void Visit(FloatType type) => GenerateTestData<float, FloatArray, FloatArray.Builder>(type, x => x);
-            public void Visit(DoubleType type) => GenerateTestData<double, DoubleArray, DoubleArray.Builder>(type, x => x);
-            public void Visit(Date32Type type) => GenerateTestData<DateTime, Date32Array, Date32Array.Builder>(type, x => DateTime.MinValue.AddDays(x));
-            public void Visit(Date64Type type) => GenerateTestData<DateTime, Date64Array, Date64Array.Builder>(type, x => DateTime.MinValue.AddDays(x));
-
-            public void Visit(Decimal32Type type) => GenerateTestData<Decimal32Array, Decimal32Array.Builder>(type, (builder, x) => builder.Append(x));
-            public void Visit(Decimal64Type type) => GenerateTestData<Decimal64Array, Decimal64Array.Builder>(type, (builder, x) => builder.Append(x));
-            public void Visit(Decimal128Type type) => GenerateTestData<Decimal128Array, Decimal128Array.Builder>(type, (builder, x) => builder.Append(x));
-            public void Visit(Decimal256Type type) => GenerateTestData<Decimal256Array, Decimal256Array.Builder>(type, (builder, x) => builder.Append(x));
-
-            public void Visit(TimestampType type)
-            {
-                DateTimeOffset basis = DateTimeOffset.UtcNow;
-                GenerateTestData<TimestampArray, TimestampArray.Builder>(type, (builder, x) => builder.Append(basis.AddMilliseconds(x)));
-            }
-
-            public void Visit(DurationType type) => GenerateTestData<long, DurationArray, DurationArray.Builder>(type, x => (long)x);
-
-            public void Visit(IntervalType type)
-            {
-                switch (type.Unit)
-                {
-                    case IntervalUnit.YearMonth:
-                        GenerateTestData<YearMonthInterval, YearMonthIntervalArray, YearMonthIntervalArray.Builder>(
-                            type, x => new YearMonthInterval(x));
-                        break;
-
-                    case IntervalUnit.DayTime:
-                        GenerateTestData<DayTimeInterval, DayTimeIntervalArray, DayTimeIntervalArray.Builder>(
-                            type, x => new DayTimeInterval(100 - 50 * x, 100 * x));
-                        break;
-
-                    case IntervalUnit.MonthDayNanosecond:
-                        GenerateTestData<MonthDayNanosecondInterval, MonthDayNanosecondIntervalArray, MonthDayNanosecondIntervalArray.Builder>(
-                            type, x => new MonthDayNanosecondInterval(x, 5 - x, 100 * x));
-                        break;
-
-                    default:
-                        throw new InvalidOperationException($"unsupported interval unit <{type.Unit}>");
-                }
-            }
-
-            public void Visit(BinaryType type) =>
-                GenerateTestData<BinaryArray, BinaryArray.Builder>(type, (builder, x) =>
-                {
-                    if (x % 2 == 0)
-                    {
-                        builder.Append((byte)x);
-                    }
-                    else
-                    {
-                        builder.Append(new byte[] {(byte)x, (byte)(x + 1)}.AsSpan());
-                    }
-                });
-
-            public void Visit(BinaryViewType type) =>
-                GenerateTestData<BinaryViewArray, BinaryViewArray.Builder>(type, (builder, x) =>
-                {
-                    if (x % 2 == 0)
-                    {
-                        builder.Append((byte)x);
-                    }
-                    else
-                    {
-                        builder.Append(new byte[] {(byte)x, (byte)(x + 1)}.AsSpan());
-                    }
-                });
-
-            public void Visit(StringType type) =>
-                GenerateTestData<StringArray, StringArray.Builder>(type, (builder, x) => builder.Append(x.ToString()));
-
-            public void Visit(StringViewType type) =>
-                GenerateTestData<StringViewArray, StringViewArray.Builder>(type, (builder, x) => builder.Append(x.ToString()));
-
-            public void Visit(ListType type) =>
-                GenerateTestData<ListArray, ListArray.Builder>(type, (builder, x) =>
-                {
-                    builder.Append();
-                    ((Int64Array.Builder)builder.ValueBuilder).Append(x);
-                }, initAction: (builder, length) =>
-                {
-                    builder.Reserve(length);
-                    builder.ValueBuilder.Reserve(length);
-                });
-
-            public void Visit(ListViewType type) =>
-                GenerateTestData<ListViewArray, ListViewArray.Builder>(type, (builder, x) =>
-                {
-                    builder.Append();
-                    ((Int64Array.Builder)builder.ValueBuilder).Append(x);
-                }, initAction: (builder, length) =>
-                {
-                    builder.Reserve(length);
-                    builder.ValueBuilder.Reserve(length);
-                });
-
-            public void Visit(FixedSizeListType type) =>
-                GenerateTestData<FixedSizeListArray, FixedSizeListArray.Builder>(type, (builder, x) =>
-                {
-                    builder.Append();
-                    var valueBuilder = (Int32Array.Builder)builder.ValueBuilder;
-                    for (int i = 0; i < type.ListSize; ++i)
-                    {
-                        valueBuilder.Append(x);
-                    }
-                }, initAction: (builder, length) =>
-                {
-                    builder.Reserve(length);
-                    builder.ValueBuilder.Reserve(length * type.ListSize);
-                });
-
-            public void Visit(StructType type)
-            {
-                // TODO: Make data from type fields.
-
-                // The following can be improved with a Builder class for StructArray.
-                StringArray.Builder resultStringBuilder = new StringArray.Builder().Reserve(_resultTotalElementCount);
-                Int32Array.Builder resultInt32Builder = new Int32Array.Builder().Reserve(_resultTotalElementCount);
-                ArrowBuffer.BitmapBuilder resultNullBitmapBuilder = new ArrowBuffer.BitmapBuilder().Reserve(_resultTotalElementCount);
-                int resultNullCount = 0;
-
-                for (int i = 0; i < _baseData.Count; i++)
-                {
-                    List<int?> dataList = _baseData[i];
-                    StringArray.Builder stringBuilder = new StringArray.Builder().Reserve(dataList.Count);
-                    Int32Array.Builder int32Builder = new Int32Array.Builder().Reserve(dataList.Count);
-                    ArrowBuffer.BitmapBuilder nullBitmapBuilder = new ArrowBuffer.BitmapBuilder().Reserve(dataList.Count);
-                    int nullCount = 0;
-
-                    for (int j = 0; j < dataList.Count; ++j)
-                    {
-                        var value = dataList[j];
-                        if (value.HasValue)
-                        {
-                            nullBitmapBuilder.Append(true);
-                            stringBuilder.Append(value.Value.ToString());
-                            int32Builder.Append(value.Value);
-
-                            if (IncludeInResult(i, j))
-                            {
-                                resultNullBitmapBuilder.Append(true);
-                                resultStringBuilder.Append(value.Value.ToString());
-                                resultInt32Builder.Append(value.Value);
-                            }
-                        }
-                        else
-                        {
-                            nullCount++;
-                            nullBitmapBuilder.Append(false);
-                            stringBuilder.Append("");
-                            int32Builder.Append(0);
-
-                            if (IncludeInResult(i, j))
-                            {
-                                resultNullCount++;
-                                resultNullBitmapBuilder.Append(false);
-                                resultStringBuilder.Append("");
-                                resultInt32Builder.Append(0);
-                            }
-                        }
-                    }
-
-                    var arrays = new List<Array>
-                    {
-                        stringBuilder.Build(),
-                        int32Builder.Build(),
-                    };
-
-                    TestTargetArrayList.Add(SliceTargetArray(
-                        new StructArray(type, dataList.Count, arrays, nullBitmapBuilder.Build(), nullCount), i));
-                }
-
-                var resultArrays = new List<Array>
-                {
-                    resultStringBuilder.Build(),
-                    resultInt32Builder.Build(),
-                };
-
-                ExpectedArray = new StructArray(
-                    type, _resultTotalElementCount, resultArrays, resultNullBitmapBuilder.Build(), resultNullCount);
-            }
-
-            public void Visit(UnionType type)
-            {
-                bool isDense = type.Mode == UnionMode.Dense;
-
-                StringArray.Builder stringResultBuilder = new StringArray.Builder().Reserve(_resultTotalElementCount);
-                Int32Array.Builder intResultBuilder = new Int32Array.Builder().Reserve(_resultTotalElementCount);
-                ArrowBuffer.Builder<byte> typeResultBuilder = new ArrowBuffer.Builder<byte>().Reserve(_resultTotalElementCount);
-                ArrowBuffer.Builder<int> offsetResultBuilder = new ArrowBuffer.Builder<int>().Reserve(_resultTotalElementCount);
-                int resultNullCount = 0;
-
-                for (int i = 0; i < _baseDataListCount; i++)
-                {
-                    List<int?> dataList = _baseData[i];
-                    StringArray.Builder stringBuilder = new StringArray.Builder().Reserve(dataList.Count);
-                    Int32Array.Builder intBuilder = new Int32Array.Builder().Reserve(dataList.Count);
-                    ArrowBuffer.Builder<byte> typeBuilder = new ArrowBuffer.Builder<byte>().Reserve(dataList.Count);
-                    ArrowBuffer.Builder<int> offsetBuilder = new ArrowBuffer.Builder<int>().Reserve(dataList.Count);
-                    int nullCount = 0;
-
-                    for (int j = 0; j < dataList.Count; j++)
-                    {
-                        bool includeInResult = IncludeInResult(i, j);
-                        byte index = (byte)Math.Min(j % 3, 1);
-                        int? intValue = (index == 1) ? dataList[j] : null;
-                        string stringValue = (index == 1) ? null : dataList[j]?.ToString();
-                        typeBuilder.Append(index);
-                        if (includeInResult)
-                        {
-                            typeResultBuilder.Append(index);
-                        }
-
-                        if (isDense)
-                        {
-                            if (index == 0)
-                            {
-                                offsetBuilder.Append(stringBuilder.Length);
-                                stringBuilder.Append(stringValue);
-                                if (includeInResult)
-                                {
-                                    offsetResultBuilder.Append(stringResultBuilder.Length);
-                                }
-                                // For dense mode, concatenation doesn't slice the child arrays, so always
-                                // add the value to the result.
-                                stringResultBuilder.Append(stringValue);
-                            }
-                            else
-                            {
-                                offsetBuilder.Append(intBuilder.Length);
-                                intBuilder.Append(intValue);
-                                if (includeInResult)
-                                {
-                                    offsetResultBuilder.Append(intResultBuilder.Length);
-                                }
-                                intResultBuilder.Append(intValue);
-                            }
-                        }
-                        else
-                        {
-                            stringBuilder.Append(stringValue);
-                            intBuilder.Append(intValue);
-                            if (includeInResult)
-                            {
-                                stringResultBuilder.Append(stringValue);
-                                intResultBuilder.Append(intValue);
-                            }
-                        }
-
-                        if (dataList[j] == null)
-                        {
-                            nullCount++;
-                            if (includeInResult)
-                            {
-                                resultNullCount++;
-                            }
-                        }
-                    }
-
-                    ArrowBuffer[] buffers;
-                    if (isDense)
-                    {
-                        buffers = new[] { typeBuilder.Build(), offsetBuilder.Build() };
-                    }
-                    else
-                    {
-                        buffers = new[] { typeBuilder.Build() };
-                    }
-
-                    var unionArray = UnionArray.Create(new ArrayData(
-                        type, dataList.Count, nullCount, 0, buffers,
-                        new[] { stringBuilder.Build().Data, intBuilder.Build().Data }));
-                    TestTargetArrayList.Add(SliceTargetArray(unionArray, i));
-                }
-
-                ArrowBuffer[] resultBuffers;
-                if (isDense)
-                {
-                    resultBuffers = new[] { typeResultBuilder.Build(), offsetResultBuilder.Build() };
-                }
-                else
-                {
-                    resultBuffers = new[] { typeResultBuilder.Build() };
-                }
-
-                ExpectedArray = UnionArray.Create(new ArrayData(
-                    type, _resultTotalElementCount, resultNullCount, 0, resultBuffers,
-                        new[] { stringResultBuilder.Build().Data, intResultBuilder.Build().Data }));
-            }
-
-            public void Visit(MapType type) =>
-                GenerateTestData<MapArray, MapArray.Builder>(type, (builder, x) =>
-                {
-                    var keyBuilder = (StringArray.Builder)builder.KeyBuilder;
-                    var valueBuilder = (Int32Array.Builder)builder.ValueBuilder;
-
-                    builder.Append();
-                    keyBuilder.Append(x.ToString());
-                    valueBuilder.Append(x);
-                }, initAction: (builder, length) =>
-                {
-                    builder.Reserve(length);
-                    builder.KeyBuilder.Reserve(length);
-                    builder.ValueBuilder.Reserve(length);
-                });
-
-            public void Visit(IArrowType type)
-            {
-                throw new NotImplementedException();
-            }
-
-            private void GenerateTestData<T, TArray, TArrayBuilder>(IArrowType type, Func<int, T> generator)
-                where TArrayBuilder : IArrowArrayBuilder<T, TArray, TArrayBuilder>
-                where TArray : IArrowArray
-            {
-                GenerateTestData<TArray, TArrayBuilder>(type, (builder, x) => builder.Append(generator(x)));
-            }
-
-            private void GenerateTestData<TArray, TArrayBuilder>(
-                IArrowType type, Action<TArrayBuilder, int> buildAction, Action<TArrayBuilder, int> initAction=null)
-                where TArrayBuilder : IArrowArrayBuilder<TArray, TArrayBuilder>
-                where TArray : IArrowArray
-            {
-                var resultBuilder = (TArrayBuilder)ArrowArrayBuilderFactory.Build(type);
-                if (initAction != null)
-                {
-                    initAction(resultBuilder, _resultTotalElementCount);
-                }
-                else
-                {
-                    resultBuilder.Reserve(_resultTotalElementCount);
-                }
-
-                for (int i = 0; i < _baseDataListCount; i++)
-                {
-                    List<int?> dataList = _baseData[i];
-                    var builder = (TArrayBuilder)ArrowArrayBuilderFactory.Build(type);
-                    if (initAction != null)
-                    {
-                        initAction(builder, dataList.Count);
-                    }
-                    else
-                    {
-                        builder.Reserve(dataList.Count);
-                    }
-
-                    for (int j = 0; j < dataList.Count; ++j)
-                    {
-                        var value = dataList[j];
-                        if (value.HasValue)
-                        {
-                            buildAction(builder, value.Value);
-                            if (IncludeInResult(i, j))
-                            {
-                                buildAction(resultBuilder, value.Value);
-                            }
-                        }
-                        else
-                        {
-                            builder.AppendNull();
-                            if (IncludeInResult(i, j))
-                            {
-                                resultBuilder.AppendNull();
-                            }
-                        }
-                    }
-
-                    TestTargetArrayList.Add(SliceTargetArray(builder.Build(default), i));
-                }
-
-                ExpectedArray = resultBuilder.Build(default);
-            }
-
-            private bool IncludeInResult(int listIndex, int itemIndex)
-            {
-                if (_sliceParameters == null)
-                {
-                    // Unsliced arrays, all values are expected in the result
-                    return true;
-                }
-
-                var sliceParameters = _sliceParameters[listIndex];
-                return itemIndex >= sliceParameters.Offset &&
-                       itemIndex < (sliceParameters.Offset + sliceParameters.Length);
-            }
-
-            private IArrowArray SliceTargetArray(IArrowArray array, int targetIndex)
-            {
-                if (_sliceParameters == null)
-                {
-                    return array;
-                }
-
-                return ArrowArrayFactory.Slice(
-                    array, _sliceParameters[targetIndex].Offset, _sliceParameters[targetIndex].Length);
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowArrayTests.cs b/csharp/test/Apache.Arrow.Tests/ArrowArrayTests.cs
deleted file mode 100644
index c3c21c4..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrowArrayTests.cs
+++ /dev/null
@@ -1,501 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ArrowArrayTests
-    {
-
-        [Fact]
-        public void ThrowsWhenGetValueIndexOutOfBounds()
-        {
-            var array = new Int64Array.Builder().Append(1).Append(2).Build();
-            Assert.Throws<ArgumentOutOfRangeException>(() => array.GetValue(-1));
-            Assert.Equal(1, array.GetValue(0));
-            Assert.Equal(2, array.GetValue(1));
-            Assert.Throws<ArgumentOutOfRangeException>(() => array.GetValue(2));
-        }
-
-        [Fact]
-        public void ThrowsWhenGetValueAndOffsetIndexOutOfBounds()
-        {
-            var array = new BinaryArray.Builder().Append(1).Append(2).Build();
-            Assert.Throws<ArgumentOutOfRangeException>(() => array.GetValueLength(-1));
-            Assert.Equal(1, array.GetValueLength(0));
-            Assert.Equal(1, array.GetValueLength(1));
-            Assert.Throws<ArgumentOutOfRangeException>(() => array.GetValueLength(2));
-
-#pragma warning disable 618
-            Assert.Throws<ArgumentOutOfRangeException>(() => array.GetValueOffset(-1));
-            Assert.Equal(0, array.GetValueOffset(0));
-            Assert.Equal(1, array.GetValueOffset(1));
-            Assert.Equal(2, array.GetValueOffset(2));
-            Assert.Throws<ArgumentOutOfRangeException>(() => array.GetValueOffset(3));
-#pragma warning restore 618
-
-            Assert.Throws<IndexOutOfRangeException>(() => array.ValueOffsets[-1]);
-            Assert.Equal(0, array.ValueOffsets[0]);
-            Assert.Equal(1, array.ValueOffsets[1]);
-            Assert.Equal(2, array.ValueOffsets[2]);
-            Assert.Throws<IndexOutOfRangeException>(() => array.ValueOffsets[3]);
-
-        }
-
-        [Fact]
-        public void IsValidValue()
-        {
-            const int totalValueCount = 8;
-            const byte nullBitmap = 0b_11110011;
-
-            var nullBitmapBuffer = new ArrowBuffer.Builder<byte>().Append(nullBitmap).Build();
-            var valueBuffer = new ArrowBuffer.Builder<long>().Append(0).Append(1).Append(4).Append(5).Append(6).Append(7).Append(8).Build();
-
-            //Check all offset and length
-            for (var offset = 0; offset < totalValueCount; offset++)
-            {
-                var nullCount = totalValueCount - offset - BitUtility.CountBits(nullBitmapBuffer.Span, offset);
-                for (var length = 1; length + offset < totalValueCount; length++)
-                {
-                    TestIsValid(valueBuffer, nullBitmapBuffer, length, nullCount, offset);
-                }
-            }
-
-            void TestIsValid(ArrowBuffer valueBuf, ArrowBuffer nullBitmapBuf, int length, int nullCount, int offset)
-            {
-                var array = new Int64Array(valueBuf, nullBitmapBuf, length, nullCount, offset);
-                for (var i = 0; i < length; i++)
-                {
-                    if (BitUtility.GetBit(nullBitmap, i + offset))
-                    {
-                        Assert.True(array.IsValid(i));
-                    }
-                    else
-                    {
-                        Assert.False(array.IsValid(i));
-                    }
-                }
-            }
-        }
-
-        [Fact]
-        public void EnumerateArray()
-        {
-            var array = new Int64Array.Builder().Append(1).Append(2).Build();
-
-            foreach(long? foo in array)
-            {
-                Assert.InRange(foo!.Value, 1, 2);
-            }
-
-            foreach (object foo in (IEnumerable)array)
-            {
-                Assert.InRange((long)foo, 1, 2);
-            }
-        }
-
-        [Fact]
-        public void ArrayAsReadOnlyList()
-        {
-            TestArrayAsReadOnlyList<long, Int64Array, Int64Array.Builder>([1, 2]);
-            TestArrayAsReadOnlyList<byte, UInt8Array, UInt8Array.Builder>([1, 2]);
-            TestArrayAsReadOnlyList<bool, BooleanArray, BooleanArray.Builder>([true, false]);
-            TestArrayAsReadOnlyList<DateTime, Date32Array, Date32Array.Builder>([DateTime.MinValue.Date, DateTime.MaxValue.Date]);
-            TestArrayAsReadOnlyList<DateTime, Date64Array, Date64Array.Builder>([DateTime.MinValue.Date, DateTime.MaxValue.Date]);
-            TestArrayAsReadOnlyList<DateTimeOffset, TimestampArray, TimestampArray.Builder>([DateTimeOffset.MinValue, DateTimeOffset.MinValue.AddYears(100)]);
-
-#if NET5_0_OR_GREATER
-            TestArrayAsReadOnlyList<DateOnly, Date32Array, Date32Array.Builder>([DateOnly.MinValue, DateOnly.MaxValue]);
-            TestArrayAsReadOnlyList<DateOnly, Date64Array, Date64Array.Builder>([DateOnly.MinValue, DateOnly.MaxValue]);
-            TestArrayAsReadOnlyList<TimeOnly, Time32Array, Time32Array.Builder>([TimeOnly.MinValue, TimeOnly.MinValue.AddHours(23)]);
-            TestArrayAsReadOnlyList<TimeOnly, Time64Array, Time64Array.Builder>([TimeOnly.MinValue, TimeOnly.MaxValue]);
-            TestArrayAsReadOnlyList<Half, HalfFloatArray, HalfFloatArray.Builder>([(Half)1.1, (Half)2.2f]);
-#endif
-        }
-
-        // Parameter 'values' must contain two distinct values
-        private static void TestArrayAsReadOnlyList<T, TArray, TArrayBuilder>(IReadOnlyList<T> values)
-            where T : struct
-            where TArray : IArrowArray
-            where TArrayBuilder : IArrowArrayBuilder<T, TArray, TArrayBuilder>, new()
-        {
-            Assert.Equal(2, values.Count);
-            TArray array = new TArrayBuilder().Append(values[0]).AppendNull().Append(values[1]).Build(default);
-            Assert.NotNull(array);
-            var readOnlyList = (IReadOnlyList<T?>)array;
-
-            Assert.Equal(array.Length, readOnlyList.Count);
-            Assert.Equal(3, readOnlyList.Count);
-            Assert.Equal(values[0], readOnlyList[0]);
-            Assert.Null(readOnlyList[1]);
-            Assert.Equal(values[1], readOnlyList[2]);
-        }
-
-        [Fact]
-        public void ArrayAsCollection()
-        {
-            TestPrimitiveArrayAsCollection<long, Int64Array, Int64Array.Builder>([1, 2, 3, 4]);
-            TestPrimitiveArrayAsCollection<byte, UInt8Array, UInt8Array.Builder>([1, 2, 3, 4]);
-            TestPrimitiveArrayAsCollection<bool, BooleanArray, BooleanArray.Builder>([true, true, true, false]);
-            TestPrimitiveArrayAsCollection<DateTime, Date32Array, Date32Array.Builder>([DateTime.MinValue.Date, DateTime.MaxValue.Date, DateTime.Today, DateTime.Today]);
-            TestPrimitiveArrayAsCollection<DateTime, Date64Array, Date64Array.Builder>([DateTime.MinValue.Date, DateTime.MaxValue.Date, DateTime.Today, DateTime.Today]);
-            TestPrimitiveArrayAsCollection<DateTimeOffset, TimestampArray, TimestampArray.Builder>([DateTimeOffset.MinValue, DateTimeOffset.MinValue.AddYears(100), DateTimeOffset.Now, DateTimeOffset.UtcNow]);
-
-#if NET5_0_OR_GREATER
-            TestPrimitiveArrayAsCollection<DateOnly, Date32Array, Date32Array.Builder>([DateOnly.MinValue, DateOnly.MaxValue, DateOnly.FromDayNumber(1), DateOnly.FromDayNumber(2)]);
-            TestPrimitiveArrayAsCollection<DateOnly, Date64Array, Date64Array.Builder>([DateOnly.MinValue, DateOnly.MaxValue, DateOnly.FromDayNumber(1), DateOnly.FromDayNumber(2)]);
-            TestPrimitiveArrayAsCollection<TimeOnly, Time32Array, Time32Array.Builder>([TimeOnly.MinValue, TimeOnly.MinValue.AddHours(23), TimeOnly.MinValue.AddHours(1), TimeOnly.MinValue.AddHours(2)]);
-            TestPrimitiveArrayAsCollection<TimeOnly, Time64Array, Time64Array.Builder>([TimeOnly.MinValue, TimeOnly.MaxValue, TimeOnly.MinValue.AddHours(1), TimeOnly.MinValue.AddHours(2)]);
-            TestPrimitiveArrayAsCollection<Half, HalfFloatArray, HalfFloatArray.Builder>([(Half)1.1, (Half)2.2f, (Half)3.3f, (Half)4.4f]);
-#endif
-
-            byte[][] byteArrs = [new byte[1], [], [255], new byte[2]];
-            TestObjectArrayAsCollection(new BinaryArray.Builder().Append(byteArrs[0].AsEnumerable()).AppendNull().Append(byteArrs[1].AsEnumerable()).Append(byteArrs[0].AsEnumerable()).Build(), System.Array.Empty<byte>(), byteArrs);
-
-            string[] strings = ["abc", "abd", "acd", "adc"];
-            TestObjectArrayAsCollection(new StringArray.Builder().Append(strings[0]).AppendNull().Append(strings[1]).Append(strings[0]).Build(), null, strings);
-        }
-
-        // Parameter 'values' must contain four values. The last value must be distinct from the rest.
-        private static void TestPrimitiveArrayAsCollection<T, TArray, TArrayBuilder>(IReadOnlyList<T> values)
-            where T : struct
-            where TArray : IArrowArray, ICollection<T?>
-            where TArrayBuilder : IArrowArrayBuilder<T, TArray, TArrayBuilder>, new()
-        {
-            Assert.Equal(4, values.Count);
-            TArray array = new TArrayBuilder().Append(values[0]).AppendNull().Append(values[1]).Append(values[0]).Build(default);
-            Assert.NotNull(array);
-            var collection = (ICollection<T?>)array;
-
-            Assert.Equal(array.Length, collection.Count);
-            Assert.Equal(4, collection.Count);
-            Assert.True(collection.IsReadOnly);
-
-            Assert.Equal("Collection is read-only.", Assert.Throws<NotSupportedException>(() => collection.Add(values[3])).Message);
-            Assert.Equal("Collection is read-only.", Assert.Throws<NotSupportedException>(() => collection.Remove(values[3])).Message);
-            Assert.Equal("Collection is read-only.", Assert.Throws<NotSupportedException>(collection.Clear).Message);
-
-            Assert.True(collection.Contains(values[0]));
-            Assert.True(collection.Contains(values[1]));
-            Assert.True(collection.Contains(default));
-            Assert.False(collection.Contains(values[3]));
-
-            T sentinel = values[2];
-            T?[] destArr = { sentinel, sentinel, sentinel, sentinel, sentinel, sentinel };
-            collection.CopyTo(destArr, 1);
-            Assert.Equal(sentinel, destArr[0]);
-            Assert.Equal(values[0], destArr[1]);
-            Assert.Null(destArr[2]);
-            Assert.Equal(values[1], destArr[3]);
-            Assert.Equal(values[0], destArr[4]);
-            Assert.Equal(sentinel, destArr[0]);
-        }
-
-        // Parameter 'values' must contain four values. The last value must be distinct from the rest.
-        private static void TestObjectArrayAsCollection<T, TArray>(TArray array, T nullValue, IReadOnlyList<T> values)
-            where T : class
-            where TArray : IArrowArray, ICollection<T>
-        {
-            Assert.NotNull(array);
-            Assert.Equal(4, values.Count);
-            var collection = (ICollection<T>)array;
-
-            Assert.Equal(array.Length, collection.Count);
-            Assert.Equal(4, collection.Count);
-            Assert.True(collection.IsReadOnly);
-
-            Assert.Equal("Collection is read-only.", Assert.Throws<NotSupportedException>(() => collection.Add(values[3])).Message);
-            Assert.Equal("Collection is read-only.", Assert.Throws<NotSupportedException>(() => collection.Remove(values[3])).Message);
-            Assert.Equal("Collection is read-only.", Assert.Throws<NotSupportedException>(collection.Clear).Message);
-
-            Assert.True(collection.Contains(values[0]));
-            Assert.True(collection.Contains(values[1]));
-            Assert.True(collection.Contains(default));
-            Assert.False(collection.Contains(values[3]));
-
-            T sentinel = values[2];
-            T[] destArr = { sentinel, sentinel, sentinel, sentinel, sentinel, sentinel };
-            collection.CopyTo(destArr, 1);
-            Assert.Equal(sentinel, destArr[0]);
-            Assert.Equal(values[0], destArr[1]);
-            Assert.Equal(nullValue, destArr[2]);
-            Assert.Equal(values[1], destArr[3]);
-            Assert.Equal(values[0], destArr[4]);
-            Assert.Equal(sentinel, destArr[0]);
-        }
-
-        [Fact]
-        public void ContainsDoesNotMatchDefaultValueInArrayWithNullValue()
-        {
-            Int64Array array = new Int64Array.Builder().Append(1).Append(2).AppendNull().Build();
-            Assert.NotNull(array);
-            var collection = (ICollection<long?>)array;
-
-            Assert.True(collection.Contains(1));
-            Assert.True(collection.Contains(2));
-            Assert.True(collection.Contains(default));
-            // A null value is stored as a null bit in the null bitmap, and a default value in the value buffer. Check that we do not match the default value.
-            Assert.False(collection.Contains(0));
-        }
-
-        [Fact]
-        public void RecursiveArraySlice()
-        {
-            var initialValues = Enumerable.Range(0, 100).ToArray();
-            var array = new Int32Array.Builder().AppendRange(initialValues).Build();
-
-            var sliced = (Int32Array) array.Slice(20, 30);
-            var slicedAgain = (Int32Array) sliced.Slice(5, 10);
-
-            Assert.Equal(25, slicedAgain.Offset);
-            Assert.Equal(10, slicedAgain.Length);
-            Assert.Equal(
-                initialValues.Skip(25).Take(10).Select(val => (int?) val).ToArray(),
-                (IReadOnlyList<int?>) slicedAgain);
-        }
-
-#if NET5_0_OR_GREATER
-        [Fact]
-        public void SliceArray()
-        {
-            TestNumberSlice<int, Int32Array, Int32Array.Builder>();
-            TestNumberSlice<sbyte, Int8Array, Int8Array.Builder>();
-            TestNumberSlice<short, Int16Array, Int16Array.Builder>();
-            TestNumberSlice<long, Int64Array, Int64Array.Builder>();
-            TestNumberSlice<byte, UInt8Array, UInt8Array.Builder>();
-            TestNumberSlice<ushort, UInt16Array, UInt16Array.Builder>();
-            TestNumberSlice<uint, UInt32Array, UInt32Array.Builder>();
-            TestNumberSlice<ulong, UInt64Array, UInt64Array.Builder>();
-            TestNumberSlice<Half, HalfFloatArray, HalfFloatArray.Builder>();
-            TestNumberSlice<float, FloatArray, FloatArray.Builder>();
-            TestNumberSlice<double, DoubleArray, DoubleArray.Builder>();
-            TestSlice<Date32Array, Date32Array.Builder>(x => x.Append(new DateTime(2019, 1, 1)).Append(new DateTime(2019, 1, 2)).Append(new DateTime(2019, 1, 3)));
-            TestSlice<Date64Array, Date64Array.Builder>(x => x.Append(new DateTime(2019, 1, 1)).Append(new DateTime(2019, 1, 2)).Append(new DateTime(2019, 1, 3)));
-            TestSlice<Time32Array, Time32Array.Builder>(x => x.Append(10).Append(20).Append(30));
-            TestSlice<Time64Array, Time64Array.Builder>(x => x.Append(10).Append(20).Append(30));
-            TestSlice<StringArray, StringArray.Builder>(x => x.Append("10").Append("20").Append("30"));
-
-            static void TestNumberSlice<T, TArray, TBuilder>()
-                where T : struct, INumber<T>
-                where TArray : PrimitiveArray<T>
-                where TBuilder : PrimitiveArrayBuilder<T, TArray, TBuilder>, new() =>
-                TestSlice<TArray, TBuilder>(x => x.Append(T.CreateChecked(10)).Append(T.CreateChecked(20)).Append(T.CreateChecked(30)));
-        }
-
-        [Fact]
-        public void SlicePrimitiveArrayWithNulls()
-        {
-            TestNumberSlice<int, Int32Array, Int32Array.Builder>();
-            TestNumberSlice<sbyte, Int8Array, Int8Array.Builder>();
-            TestNumberSlice<short, Int16Array, Int16Array.Builder>();
-            TestNumberSlice<long, Int64Array, Int64Array.Builder>();
-            TestNumberSlice<byte, UInt8Array, UInt8Array.Builder>();
-            TestNumberSlice<ushort, UInt16Array, UInt16Array.Builder>();
-            TestNumberSlice<uint, UInt32Array, UInt32Array.Builder>();
-            TestNumberSlice<ulong, UInt64Array, UInt64Array.Builder>();
-            TestNumberSlice<Half, HalfFloatArray, HalfFloatArray.Builder>();
-            TestNumberSlice<float, FloatArray, FloatArray.Builder>();
-            TestNumberSlice<double, DoubleArray, DoubleArray.Builder>();
-            TestSlice<Date32Array, Date32Array.Builder>(x => x.Append(new DateTime(2019, 1, 1)).Append(new DateTime(2019, 1, 2)).AppendNull().Append(new DateTime(2019, 1, 3)));
-            TestSlice<Date64Array, Date64Array.Builder>(x => x.Append(new DateTime(2019, 1, 1)).Append(new DateTime(2019, 1, 2)).AppendNull().Append(new DateTime(2019, 1, 3)));
-            TestSlice<Time32Array, Time32Array.Builder>(x => x.Append(10).Append(20).AppendNull().Append(30));
-            TestSlice<Time64Array, Time64Array.Builder>(x => x.Append(10).Append(20).AppendNull().Append(30));
-            TestSlice<Int32Array, Int32Array.Builder>(x => x.AppendNull().AppendNull().AppendNull());  // All nulls
-
-            static void TestNumberSlice<T, TArray, TBuilder>()
-                where T : struct, INumber<T>
-                where TArray : PrimitiveArray<T>
-                where TBuilder : PrimitiveArrayBuilder<T, TArray, TBuilder>, new() =>
-                TestSlice<TArray, TBuilder>(x => x.AppendNull().Append(T.CreateChecked(10)).Append(T.CreateChecked(20)).AppendNull().Append(T.CreateChecked(30)));
-        }
-#endif
-
-        [Fact]
-        public void SliceBooleanArray()
-        {
-            TestSlice<BooleanArray, BooleanArray.Builder>(x => x.Append(true).Append(false).Append(true));
-            TestSlice<BooleanArray, BooleanArray.Builder>(x => x.Append(true).Append(false).AppendNull().Append(true));
-        }
-
-        [Fact]
-        public void SliceStringArrayWithNullsAndEmptyStrings()
-        {
-            TestSlice<StringArray, StringArray.Builder>(x => x.Append("10").AppendNull().Append("30"));
-            TestSlice<StringArray, StringArray.Builder>(x => x.Append("10").Append(string.Empty).Append("30"));
-            TestSlice<StringArray, StringArray.Builder>(x => x.Append("10").Append(string.Empty).AppendNull().Append("30"));
-            TestSlice<StringArray, StringArray.Builder>(x => x.Append("10").AppendNull().Append(string.Empty).Append("30"));
-            TestSlice<StringArray, StringArray.Builder>(x => x.Append("10").AppendNull().Append(string.Empty).AppendNull().Append("30"));
-        }
-
-        private static void TestSlice<TArray, TArrayBuilder>(Action<TArrayBuilder> action)
-            where TArray : IArrowArray
-            where TArrayBuilder : IArrowArrayBuilder<TArray>, new()
-        {
-            var builder = new TArrayBuilder();
-            action(builder);
-            var baseArray = builder.Build(default) as Array;
-            Assert.NotNull(baseArray);
-            var totalLength = baseArray.Length;
-            var validator = new ArraySliceValidator(baseArray);
-
-            //Check all offset and length
-            for (var offset = 0; offset < totalLength; offset++)
-            {
-                for (var length = 1; length + offset <= totalLength; length++)
-                {
-                    var targetArray = baseArray.Slice(offset, length);
-                    targetArray.Accept(validator);
-                }
-            }
-        }
-
-        private class ArraySliceValidator :
-            IArrowArrayVisitor<Int8Array>,
-            IArrowArrayVisitor<Int16Array>,
-            IArrowArrayVisitor<Int32Array>,
-            IArrowArrayVisitor<Int64Array>,
-            IArrowArrayVisitor<UInt8Array>,
-            IArrowArrayVisitor<UInt16Array>,
-            IArrowArrayVisitor<UInt32Array>,
-            IArrowArrayVisitor<UInt64Array>,
-            IArrowArrayVisitor<Date32Array>,
-            IArrowArrayVisitor<Date64Array>,
-            IArrowArrayVisitor<Time32Array>,
-            IArrowArrayVisitor<Time64Array>,
-            IArrowArrayVisitor<DurationArray>,
-#if NET5_0_OR_GREATER
-            IArrowArrayVisitor<HalfFloatArray>,
-#endif
-            IArrowArrayVisitor<FloatArray>,
-            IArrowArrayVisitor<DoubleArray>,
-            IArrowArrayVisitor<BooleanArray>,
-            IArrowArrayVisitor<StringArray>
-        {
-            private readonly IArrowArray _baseArray;
-
-            public ArraySliceValidator(IArrowArray baseArray)
-            {
-                _baseArray = baseArray;
-            }
-
-            public void Visit(Int8Array array) => ValidateArrays(array);
-            public void Visit(Int16Array array) => ValidateArrays(array);
-            public void Visit(Int32Array array) => ValidateArrays(array);
-            public void Visit(Int64Array array) => ValidateArrays(array);
-            public void Visit(UInt8Array array) => ValidateArrays(array);
-            public void Visit(UInt16Array array) => ValidateArrays(array);
-            public void Visit(UInt32Array array) => ValidateArrays(array);
-            public void Visit(UInt64Array array) => ValidateArrays(array);
-
-            public void Visit(Date32Array array)
-            {
-                ValidateArrays(array);
-                Assert.IsAssignableFrom<Date32Array>(_baseArray);
-                var baseArray = (Date32Array)_baseArray;
-
-                Assert.Equal(baseArray.GetDateTimeOffset(array.Offset), array.GetDateTimeOffset(0));
-            }
-
-            public void Visit(Date64Array array)
-            {
-                ValidateArrays(array);
-                Assert.IsAssignableFrom<Date64Array>(_baseArray);
-                var baseArray = (Date64Array)_baseArray;
-
-                Assert.Equal(baseArray.GetDateTimeOffset(array.Offset), array.GetDateTimeOffset(0));
-            }
-            public void Visit(Time32Array array) => ValidateArrays(array);
-            public void Visit(Time64Array array) => ValidateArrays(array);
-            public void Visit(DurationArray array) => ValidateArrays(array);
-
-#if NET5_0_OR_GREATER
-            public void Visit(HalfFloatArray array) => ValidateArrays(array);
-#endif
-            public void Visit(FloatArray array) => ValidateArrays(array);
-            public void Visit(DoubleArray array) => ValidateArrays(array);
-            public void Visit(StringArray array) => ValidateArrays(array);
-            public void Visit(BooleanArray array) => ValidateArrays(array);
-
-            public void Visit(IArrowArray array) => throw new NotImplementedException();
-
-            private void ValidateArrays<T>(PrimitiveArray<T> slicedArray)
-                where T : struct, IEquatable<T>
-            {
-                Assert.IsAssignableFrom<PrimitiveArray<T>>(_baseArray);
-                var baseArray = (PrimitiveArray<T>)_baseArray;
-
-                Assert.True(baseArray.NullBitmapBuffer.Span.SequenceEqual(slicedArray.NullBitmapBuffer.Span));
-                Assert.True(
-                    baseArray.ValueBuffer.Span.CastTo<T>().Slice(slicedArray.Offset, slicedArray.Length)
-                        .SequenceEqual(slicedArray.Values));
-
-                Assert.Equal(baseArray.GetValue(slicedArray.Offset), slicedArray.GetValue(0));
-
-                ValidateNullCount(slicedArray);
-            }
-
-            private void ValidateArrays(BooleanArray slicedArray)
-            {
-                Assert.IsAssignableFrom<BooleanArray>(_baseArray);
-                var baseArray = (BooleanArray)_baseArray;
-
-                Assert.True(baseArray.NullBitmapBuffer.Span.SequenceEqual(slicedArray.NullBitmapBuffer.Span));
-                Assert.True(baseArray.Values.SequenceEqual(slicedArray.Values));
-
-                Assert.True(
-                    baseArray.ValueBuffer.Span.Slice(0, (int) Math.Ceiling(slicedArray.Length / 8.0))
-                        .SequenceEqual(slicedArray.Values));
-
-                Assert.Equal(baseArray.GetValue(slicedArray.Offset), slicedArray.GetValue(0));
-
-#pragma warning disable CS0618
-                Assert.Equal(baseArray.GetBoolean(slicedArray.Offset), slicedArray.GetBoolean(0));
-#pragma warning restore CS0618
-
-                ValidateNullCount(slicedArray);
-            }
-
-            private void ValidateArrays(BinaryArray slicedArray)
-            {
-                Assert.IsAssignableFrom<BinaryArray>(_baseArray);
-                var baseArray = (BinaryArray)_baseArray;
-
-                Assert.True(baseArray.Values.SequenceEqual(slicedArray.Values));
-                Assert.True(baseArray.NullBitmapBuffer.Span.SequenceEqual(slicedArray.NullBitmapBuffer.Span));
-                Assert.True(
-                    baseArray.ValueOffsetsBuffer.Span.CastTo<int>().Slice(slicedArray.Offset, slicedArray.Length + 1)
-                        .SequenceEqual(slicedArray.ValueOffsets));
-
-                Assert.True(baseArray.GetBytes(slicedArray.Offset).SequenceEqual(slicedArray.GetBytes(0)));
-
-                ValidateNullCount(slicedArray);
-            }
-
-            private static void ValidateNullCount(IArrowArray slicedArray)
-            {
-                var expectedNullCount = Enumerable.Range(0, slicedArray.Length)
-                    .Select(i => slicedArray.IsNull(i) ? 1 : 0)
-                    .Sum();
-                Assert.Equal(expectedNullCount, slicedArray.NullCount);
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowBufferBitmapBuilderTests.cs b/csharp/test/Apache.Arrow.Tests/ArrowBufferBitmapBuilderTests.cs
deleted file mode 100644
index a4e698f..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrowBufferBitmapBuilderTests.cs
+++ /dev/null
@@ -1,633 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-namespace Apache.Arrow.Tests
-{
-    using System;
-    using System.Linq;
-    using Xunit;
-
-    /// <summary>
-    /// The <see cref="ArrowBufferBitmapBuilderTests"/> class provides unit tests for the
-    /// <see cref="ArrowBuffer.BitmapBuilder"/> class.
-    /// </summary>
-    public class ArrowBufferBitmapBuilderTests
-    {
-        public class Append
-        {
-            [Theory]
-            [InlineData(new bool[] {}, false, 1, 0, 1)]
-            [InlineData(new bool[] {}, true, 1, 1, 0)]
-            [InlineData(new[] { true, false }, true, 3, 2, 1)]
-            [InlineData(new[] { true, false }, false, 3, 1, 2)]
-            public void IncreasesLength(
-                bool[] initialContents,
-                bool valueToAppend,
-                int expectedLength,
-                int expectedSetBitCount,
-                int expectedUnsetBitCount)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(initialContents);
-
-                // Act
-                var actualReturnValue = builder.Append(valueToAppend);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedLength, builder.Length);
-                Assert.True(builder.Capacity >= expectedLength);
-                Assert.Equal(expectedSetBitCount, builder.SetBitCount);
-                Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount);
-            }
-
-            [Theory]
-            [InlineData(new bool[] {}, false)]
-            [InlineData(new bool[] {}, true)]
-            [InlineData(new[] { true, false }, true)]
-            [InlineData(new[] { true, false }, false)]
-            public void AfterClearIncreasesLength(bool[] initialContentsToClear, bool valueToAppend)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(initialContentsToClear);
-                builder.Clear();
-
-                // Act
-                var actualReturnValue = builder.Append(valueToAppend);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(1, builder.Length);
-                Assert.True(builder.Capacity >= 1);
-                Assert.Equal(valueToAppend ? 1 : 0, builder.SetBitCount);
-                Assert.Equal(valueToAppend ? 0 : 1, builder.UnsetBitCount);
-            }
-
-            [Fact]
-            public void IncreasesCapacityWhenRequired()
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                int initialCapacity = builder.Capacity;
-                builder.AppendRange(true, initialCapacity); // Fill to capacity.
-
-                // Act
-                var actualReturnValue = builder.Append(true);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(initialCapacity + 1, builder.Length);
-                Assert.True(builder.Capacity >= initialCapacity + 1);
-            }
-        }
-
-        public class AppendSpan
-        {
-            [Theory]
-            [InlineData(new byte[] { 0b00000110 }, 4, 4, 2, 2)]    
-            [InlineData(new byte[] { 0b11111110 }, 4, 4, 3, 1)]
-            [InlineData(new byte[] { 0b11111110, 0b00000001 }, 9, 9, 8, 1)]
-            [InlineData(new byte[] { 0b11111001, 0b00000001 }, 9, 9, 7, 2)]
-            public void BitsAreAppendedToEmptyBuilder(byte[] bytesToAppend,
-                int validBits,
-                int expectedLength,
-                int expectedSetBitCount,
-                int expectedUnsetBitCount)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-
-                // Act
-                var actualReturnValue = builder.Append(new Span<byte>(bytesToAppend), validBits);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedLength, builder.Length);
-                Assert.True(builder.Capacity >= expectedLength);
-                Assert.Equal(expectedSetBitCount, builder.SetBitCount);
-                Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount);
-
-            }
-
-            [Theory]
-            [InlineData(new byte[] { 6 }, 4, 12, 10, 2)]
-            [InlineData(new byte[] { 254 }, 4, 12, 11, 1)]
-            [InlineData(new byte[] { 254, 1 }, 9, 17, 16, 1)]
-            [InlineData(new byte[] { 249, 1 }, 9, 17, 15, 2)]
-            public void BitsAreAppendedToBuilderContainingByteAlignedData(byte[] bytesToAppend,
-                int validBits,
-                int expectedLength,
-                int expectedSetBitCount,
-                int expectedUnsetBitCount)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(true, 8);
-
-                // Act
-                var actualReturnValue = builder.Append(new Span<byte>(bytesToAppend), validBits);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedLength, builder.Length);
-                Assert.True(builder.Capacity >= expectedLength);
-                Assert.Equal(expectedSetBitCount, builder.SetBitCount);
-                Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount);
-            }
-
-            [Theory]
-            [InlineData(new byte[] { 6 }, 4, 13, 11, 2)]
-            [InlineData(new byte[] { 254 }, 4, 13, 12, 1)]
-            [InlineData(new byte[] { 254, 1 }, 9, 18, 17, 1)]
-            [InlineData(new byte[] { 249, 1 }, 9, 18, 16, 2)]
-            public void BitsAreAppendedToBuilderContainingNotAlignedData(byte[] bytesToAppend,
-                int validBits,
-                int expectedLength,
-                int expectedSetBitCount,
-                int expectedUnsetBitCount)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(true, 9);
-
-                // Act
-                var actualReturnValue = builder.Append(new Span<byte>(bytesToAppend), validBits);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedLength, builder.Length);
-                Assert.True(builder.Capacity >= expectedLength);
-                Assert.Equal(expectedSetBitCount, builder.SetBitCount);
-                Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount);
-            }
-
-            [Fact]
-            public void EmptySpanAppendsCorrectNumberOfBits()
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(true, 8);
-
-                // Act
-                var actualReturnValue = builder.Append(Span<byte>.Empty, 8);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(16, builder.Length);
-                Assert.True(builder.Capacity >= 16);
-                Assert.Equal(16, builder.SetBitCount);
-                Assert.Equal(0, builder.UnsetBitCount);
-            }
-
-            [Fact]
-            public void ThrowsWhenLengthIsTooBig()
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(true, 8);
-
-                // Act
-                Assert.Throws<ArgumentException>(() => builder.Append(new byte[] { 0b0010111 }, 9));
-                Assert.Throws<ArgumentException>(() => builder.Append(new byte[] { 0, 1, 3, 4 }, 33));
-            }
-        }
-
-        public class AppendRange
-        {
-            [Theory]
-            [InlineData(new bool[] {}, new bool[] {}, 0, 0, 0)]
-            [InlineData(new bool[] {}, new[] { true, false }, 2, 1, 1)]
-            [InlineData(new[] { true, false }, new bool[] {}, 2, 1, 1)]
-            [InlineData(new[] { true, false }, new[] { true, false }, 4, 2, 2)]
-            public void AppendingEnumerableIncreasesLength(
-                bool[] initialContents,
-                bool[] toAppend,
-                int expectedLength,
-                int expectedSetBitCount,
-                int expectedUnsetBitCount)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(initialContents);
-
-                // Act
-                var actualReturnValue = builder.AppendRange(toAppend);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedLength, builder.Length);
-                Assert.True(builder.Capacity >= expectedLength);
-                Assert.Equal(expectedSetBitCount, builder.SetBitCount);
-                Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount);
-            }
-
-            [Theory]
-            [InlineData(new bool[] { }, true, 0, 0, 0, 0)]
-            [InlineData(new bool[] { }, true, 2, 2, 2, 0)]
-            [InlineData(new[] { true, false }, false, 0, 2, 1, 1)]
-            [InlineData(new[] { true, false }, false, 2, 4, 1, 3)]
-            [InlineData(new[] { true, false }, true, 2, 4, 3, 1)]
-            public void AppendingValueMultipleTimesIncreasesLength(
-                bool[] initialContents,
-                bool valueToAppend,
-                int numberOfTimes,
-                int expectedLength,
-                int expectedSetBitCount,
-                int expectedUnsetBitCount)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(initialContents);
-
-                // Act
-                var actualReturnValue = builder.AppendRange(valueToAppend, numberOfTimes);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedLength, builder.Length);
-                Assert.True(builder.Capacity >= expectedLength);
-                Assert.Equal(expectedSetBitCount, builder.SetBitCount);
-                Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount);
-            }
-        }
-
-        public class Build
-        {
-            [Theory]
-            [InlineData(new bool[] { }, new byte[] { })]
-            [InlineData(new[] { true, false, true, false }, new byte[] { 0b00000101 })]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false, true, false },
-                new byte[] { 0b01010101, 0b00000101 })]
-            public void AppendedRangeBitPacks(bool[] contents, byte[] expectedBytes)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(contents);
-
-                // Act
-                var buf = builder.Build();
-
-                // Assert
-                AssertBuffer(expectedBytes, buf);
-            }
-        }
-
-        public class Clear
-        {
-            [Theory]
-            [InlineData(10)]
-            [InlineData(100)]
-            public void ClearingSetsBitCountToZero(int numBitsBeforeClear)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                var data = Enumerable.Repeat(true, numBitsBeforeClear).Select(x => x).ToArray();
-                builder.AppendRange(data);
-
-                // Act
-                var actualReturnValue = builder.Clear();
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(0, builder.Length);
-            }
-        }
-
-        public class Resize
-        {
-            [Theory]
-            [InlineData(new bool[] {}, 256, 0, 256)]
-            [InlineData(new[] { true, true, true, true}, 256, 4, 252)]
-            [InlineData(new[] { false, false, false, false}, 256, 0, 256)]
-            [InlineData(new[] { true, true, true, true}, 2, 2, 0)]
-            [InlineData(new[] { true, true, true, true}, 0, 0, 0)]
-            public void LengthHasExpectedValueAfterResize(
-                bool[] bits, int newSize, int expectedSetBitCount, int expectedUnsetBitCount)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(bits);
-
-                // Act
-                var actualReturnValue = builder.Resize(newSize);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.True(builder.Capacity >= newSize);
-                Assert.Equal(newSize, builder.Length);
-                Assert.Equal(expectedSetBitCount, builder.SetBitCount);
-                Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount);
-            }
-
-            [Fact]
-            public void NegativeLengthThrows()
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.Append(false);
-                builder.Append(true);
-
-                // Act/Assert
-                Assert.Throws<ArgumentOutOfRangeException>(() => builder.Resize(-1));
-            }
-        }
-
-        public class Reserve
-        {
-            [Theory]
-            [InlineData(0, 0, 0)]
-            [InlineData(0, 0, 8)]
-            [InlineData(8, 8, 8)]
-            [InlineData(8, 8, 16)]
-            public void CapacityIncreased(int initialCapacity, int numBitsToAppend, int additionalCapacity)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder(initialCapacity);
-                builder.AppendRange(true, numBitsToAppend);
-
-                // Act
-                var actualReturnValue = builder.Reserve(additionalCapacity);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.True(builder.Capacity >= numBitsToAppend + additionalCapacity);
-            }
-
-            [Fact]
-            public void NegativeCapacityThrows()
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-
-                // Act/Assert
-                Assert.Throws<ArgumentOutOfRangeException>(() => builder.Reserve(-1));
-            }
-        }
-
-        public class Set
-        {
-            [Theory]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                2,
-                new byte[] { 0b01010101, 0b00000001 },
-                5, 5)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                3,
-                new byte[] { 0b01011101, 0b00000001 },
-                6, 4)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                8,
-                new byte[] { 0b01010101, 0b00000001 },
-                5, 5)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                9,
-                new byte[] { 0b01010101, 0b00000011 },
-                6, 4)]
-            public void OverloadWithNoValueParameterSetsAsExpected(
-                bool[] bits, int indexToSet, byte[] expectedBytes,
-                int expectedSetBitCount, int expectedUnsetBitCount)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(bits);
-
-                // Act
-                var actualReturnValue = builder.Set(indexToSet);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedSetBitCount, builder.SetBitCount);
-                Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount);
-                var buf = builder.Build();
-                AssertBuffer(expectedBytes, buf);
-            }
-
-            [Theory]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                2, true,
-                new byte[] { 0b01010101, 0b00000001 },
-                5, 5)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                2, false,
-                new byte[] { 0b01010001, 0b00000001 },
-                4, 6)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                3, true,
-                new byte[] { 0b01011101, 0b00000001 },
-                6, 4)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                3, false,
-                new byte[] { 0b01010101, 0b00000001 },
-                5, 5)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                8, true,
-                new byte[] { 0b01010101, 0b00000001 },
-                5, 5)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                8, false,
-                new byte[] { 0b01010101, 0b00000000 },
-                4, 6)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                9, true,
-                new byte[] { 0b01010101, 0b00000011 },
-                6, 4)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                9, false,
-                new byte[] { 0b01010101, 0b00000001 },
-                5, 5)]
-            public void OverloadWithValueParameterSetsAsExpected(
-                bool[] bits, int indexToSet, bool valueToSet, byte[] expectedBytes,
-                int expectedSetBitCount, int expectedUnsetBitCount)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(bits);
-
-                // Act
-                var actualReturnValue = builder.Set(indexToSet, valueToSet);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedSetBitCount, builder.SetBitCount);
-                Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount);
-                var buf = builder.Build();
-                AssertBuffer(expectedBytes, buf);
-            }
-
-            [Theory]
-            [InlineData(0, -1)]
-            [InlineData(0, 0)]
-            [InlineData(1, 1)]
-            [InlineData(10, 10)]
-            [InlineData(10, 11)]
-            public void BadIndexThrows(int numBitsToAppend, int indexToSet)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                var bits = Enumerable.Repeat(true, numBitsToAppend);
-                builder.AppendRange(bits);
-
-                // Act/Assert
-                Assert.Throws<ArgumentOutOfRangeException>(() => builder.Set(indexToSet));
-                Assert.Throws<ArgumentOutOfRangeException>(() => builder.Set(indexToSet, true));
-            }
-        }
-
-        public class Swap
-        {
-            [Theory]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                0, 2,
-                new byte[] { 0b01010101, 0b00000001 })]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                0, 3,
-                new byte[] { 0b01011100, 0b00000001 })]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                4, 8,
-                new byte[] { 0b01010101, 0b00000001 })]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                4, 9,
-                new byte[] { 0b01000101, 0b00000011 })]
-            public void SwapsAsExpected(bool[] bits, int firstIndex, int secondIndex, byte[] expectedBytes)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(bits);
-
-                // Act
-                var actualReturnValue = builder.Swap(firstIndex, secondIndex);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                var buf = builder.Build();
-                AssertBuffer(expectedBytes, buf);
-            }
-
-            [Theory]
-            [InlineData(0, -1, 0)]
-            [InlineData(0, 0, -1)]
-            [InlineData(0, 0, 0)]
-            [InlineData(1, 0, 1)]
-            [InlineData(1, 1, 0)]
-            [InlineData(1, 0, -1)]
-            [InlineData(1, -1, 0)]
-            [InlineData(1, 1, 1)]
-            [InlineData(10, 10, 0)]
-            [InlineData(10, 0, 10)]
-            [InlineData(10, 10, 10)]
-            [InlineData(10, 11, 0)]
-            [InlineData(10, 0, 11)]
-            [InlineData(10, 11, 11)]
-            public void BadIndicesThrows(int numBitsToAppend, int firstIndex, int secondIndex)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                var bits = Enumerable.Repeat(true, numBitsToAppend);
-                builder.AppendRange(bits);
-
-                // Act/Assert
-                Assert.Throws<ArgumentOutOfRangeException>(() => builder.Swap(firstIndex, secondIndex));
-            }
-        }
-
-        public class Toggle
-        {
-            [Theory]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                2,
-                new byte[] { 0b01010001, 0b00000001 },
-                4, 6)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                3,
-                new byte[] { 0b01011101, 0b00000001 },
-                6, 4)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                8,
-                new byte[] { 0b01010101, 0b00000000 },
-                4, 6)]
-            [InlineData(
-                new[] { true, false, true, false, true, false, true, false, true, false},
-                9,
-                new byte[] { 0b01010101, 0b00000011 },
-                6, 4)]
-            public void TogglesAsExpected(
-                bool[] bits, int indexToToggle, byte[] expectedBytes,
-                int expectedSetBitCount, int expectedUnsetBitCount)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                builder.AppendRange(bits);
-
-                // Act
-                var actualReturnValue = builder.Toggle(indexToToggle);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedSetBitCount, builder.SetBitCount);
-                Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount);
-                var buf = builder.Build();
-                AssertBuffer(expectedBytes, buf);
-            }
-
-            [Theory]
-            [InlineData(0, -1)]
-            [InlineData(0, 0)]
-            [InlineData(1, 1)]
-            [InlineData(10, 10)]
-            [InlineData(10, 11)]
-            public void BadIndexThrows(int numBitsToAppend, int indexToToggle)
-            {
-                // Arrange
-                var builder = new ArrowBuffer.BitmapBuilder();
-                var bits = Enumerable.Repeat(true, numBitsToAppend);
-                builder.AppendRange(bits);
-
-                // Act/Assert
-                Assert.Throws<ArgumentOutOfRangeException>(() => builder.Toggle(indexToToggle));
-            }
-        }
-
-        private static void AssertBuffer(byte[] expectedBytes, ArrowBuffer buf)
-        {
-            Assert.True(buf.Length >= expectedBytes.Length);
-            for (int i = 0; i < expectedBytes.Length; i++)
-            {
-                Assert.Equal(expectedBytes[i], buf.Span[i]);
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowBufferBuilderTests.cs b/csharp/test/Apache.Arrow.Tests/ArrowBufferBuilderTests.cs
deleted file mode 100644
index 495fc2e..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrowBufferBuilderTests.cs
+++ /dev/null
@@ -1,216 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Linq;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ArrowBufferBuilderTests
-    {
-        [Fact]
-        public void ThrowsWhenIndexOutOfBounds()
-        {
-            Assert.Throws<IndexOutOfRangeException>(() =>
-            {
-                var builder = new ArrowBuffer.Builder<int>();
-                builder.Span[100] = 100;
-            });
-        }
-
-        public class Append
-        {
-            [Fact]
-            public void DoesNotThrowWithNullParameters()
-            {
-                var builder = new ArrowBuffer.Builder<int>();
-
-                builder.AppendRange(null);
-            }
-
-            [Fact]
-            public void CapacityOnlyGrowsWhenLengthWillExceedCapacity()
-            {
-                var builder = new ArrowBuffer.Builder<int>(1);
-                var capacity = builder.Capacity;
-
-                builder.Append(1);
-
-                Assert.Equal(capacity, builder.Capacity);
-            }
-
-            [Fact]
-            public void CapacityGrowsAfterAppendWhenLengthExceedsCapacity()
-            {
-                var builder = new ArrowBuffer.Builder<int>(1);
-                var capacity = builder.Capacity;
-
-                builder.Append(1);
-                builder.Append(2);
-
-                Assert.True(builder.Capacity > capacity);
-            }
-
-            [Fact]
-            public void CapacityGrowsAfterAppendSpan()
-            {
-                var builder = new ArrowBuffer.Builder<int>(1);
-                var capacity = builder.Capacity;
-                var data = Enumerable.Range(0, 10).Select(x => x).ToArray();
-
-                builder.Append(data);
-
-                Assert.True(builder.Capacity > capacity);
-            }
-
-            [Fact]
-            public void LengthIncrementsAfterAppend()
-            {
-                var builder = new ArrowBuffer.Builder<int>(1);
-                var length = builder.Length;
-
-                builder.Append(1);
-
-                Assert.Equal(length + 1, builder.Length);
-            }
-
-            [Fact]
-            public void LengthGrowsBySpanLength()
-            {
-                var builder = new ArrowBuffer.Builder<int>(1);
-                var data = Enumerable.Range(0, 10).Select(x => x).ToArray();
-
-                builder.Append(data);
-
-                Assert.Equal(10, builder.Length);
-            }
-
-            [Fact]
-            public void BufferHasExpectedValues()
-            {
-                var builder = new ArrowBuffer.Builder<int>(1);
-
-                builder.Append(10);
-                builder.Append(20);
-
-                var buffer = builder.Build();
-                var span = buffer.Span.CastTo<int>();
-
-                Assert.Equal(10, span[0]);
-                Assert.Equal(20, span[1]);
-                Assert.Equal(0, span[2]);
-            }
-        }
-
-        public class AppendRange
-        {
-            [Fact]
-            public void CapacityGrowsAfterAppendEnumerable()
-            {
-                var builder = new ArrowBuffer.Builder<int>(1);
-                var capacity = builder.Capacity;
-                var data = Enumerable.Range(0, 10).Select(x => x);
-
-                builder.AppendRange(data);
-
-                Assert.True(builder.Capacity > capacity);
-            }
-
-            [Fact]
-            public void LengthGrowsByEnumerableCount()
-            {
-                var builder = new ArrowBuffer.Builder<int>(1);
-                var length = builder.Length;
-                var data = Enumerable.Range(0, 10).Select(x => x).ToArray();
-                var count = data.Length;
-
-                builder.AppendRange(data);
-
-                Assert.Equal(length + count, builder.Length);
-            }
-
-            [Fact]
-            public void BufferHasExpectedValues()
-            {
-                var builder = new ArrowBuffer.Builder<int>(1);
-                var data = Enumerable.Range(0, 10).Select(x => x).ToArray();
-
-                builder.AppendRange(data);
-
-                var buffer = builder.Build();
-                var span = buffer.Span.CastTo<int>();
-
-                for (var i = 0; i < 10; i++)
-                {
-                    Assert.Equal(i, span[i]);
-                }
-            }
-        }
-
-        public class Clear
-        {
-            [Theory]
-            [InlineData(10)]
-            [InlineData(100)]
-            public void SetsAllValuesToDefault(int sizeBeforeClear)
-            {
-                var builder = new ArrowBuffer.Builder<int>(1);
-                var data = Enumerable.Range(0, sizeBeforeClear).Select(x => x).ToArray();
-
-                builder.AppendRange(data);
-                builder.Clear();
-                builder.Append(0);
-
-                var buffer = builder.Build();
-                // No matter the sizeBeforeClear, we only appended a single 0,
-                // so the buffer length should be the smallest possible.
-                Assert.Equal(64, buffer.Length);
-
-                // check all 16 int elements are default
-                var zeros = Enumerable.Range(0, 16).Select(x => 0).ToArray();
-                var values = buffer.Span.CastTo<int>().Slice(0, 16).ToArray();
-
-                Assert.True(zeros.SequenceEqual(values));
-            }
-        }
-
-        public class Resize
-        {
-            [Fact]
-            public void LengthHasExpectedValueAfterResize()
-            {
-                var builder = new ArrowBuffer.Builder<int>();
-                builder.Resize(8);
-
-                Assert.True(builder.Capacity >= 8);
-                Assert.Equal(8, builder.Length);
-            }
-
-            [Fact]
-            public void NegativeLengthThrows()
-            {
-                // Arrange
-                var builder = new ArrowBuffer.Builder<int>();
-                builder.Append(10);
-                builder.Append(20);
-
-                // Act/Assert
-                Assert.Throws<ArgumentOutOfRangeException>(() => builder.Resize(-1));
-            }
-        }
-
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowBufferTests.cs b/csharp/test/Apache.Arrow.Tests/ArrowBufferTests.cs
deleted file mode 100644
index e6fa525..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrowBufferTests.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Tests.Fixtures;
-using System;
-using System.Runtime.InteropServices;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ArrowBufferTests
-    {
-        public class Allocate : 
-            IClassFixture<DefaultMemoryAllocatorFixture>
-        {
-            private readonly DefaultMemoryAllocatorFixture _memoryPoolFixture;
-
-            public Allocate(DefaultMemoryAllocatorFixture memoryPoolFixture)
-            {
-                _memoryPoolFixture = memoryPoolFixture;
-            }
-
-            /// <summary>
-            /// Ensure Arrow buffers are allocated in multiples of 64 bytes.
-            /// </summary>
-            /// <param name="size">number of bytes to allocate</param>
-            /// <param name="expectedCapacity">expected buffer capacity after allocation</param>
-            [Theory]
-            [InlineData(0, 0)]
-            [InlineData(1, 64)]
-            [InlineData(8, 64)]
-            [InlineData(9, 64)]
-            [InlineData(65, 128)]
-            public void AllocatesWithExpectedPadding(int size, int expectedCapacity)
-            {
-                var builder = new ArrowBuffer.Builder<byte>(size);
-                for (int i = 0; i < size; i++)
-                {
-                    builder.Append(0);
-                }
-                var buffer = builder.Build();
-
-                Assert.Equal(expectedCapacity, buffer.Length);
-            }
-
-            /// <summary>
-            /// Ensure allocated buffers are aligned to multiples of 64.
-            /// </summary>
-            [Theory]
-            [InlineData(1)]
-            [InlineData(8)]
-            [InlineData(64)]
-            [InlineData(128)]
-            public unsafe void AllocatesAlignedToMultipleOf64(int size)
-            {
-                var builder = new ArrowBuffer.Builder<byte>(size);
-                for (int i = 0; i < size; i++)
-                {
-                    builder.Append(0);
-                }
-                var buffer = builder.Build();
-
-                fixed (byte* ptr = &buffer.Span.GetPinnableReference())
-                { 
-                    Assert.True(new IntPtr(ptr).ToInt64() % 64 == 0);
-                }
-            }
-
-            /// <summary>
-            /// Ensure padding in arrow buffers is initialized with zeroes.
-            /// </summary>
-            [Fact]
-            public void HasZeroPadding()
-            {
-                var buffer = new ArrowBuffer.Builder<byte>(10).Append(0).Build();
-                
-                foreach (var b in buffer.Span)
-                {
-                    Assert.Equal(0, b);
-                }
-            }
-
-        }
-
-        [Fact]
-        public void TestExternalMemoryWrappedAsArrowBuffer()
-        {
-            Memory<byte> memory = new byte[sizeof(int) * 3];
-            Span<byte> spanOfBytes = memory.Span;
-            var span = spanOfBytes.CastTo<int>();
-            span[0] = 0;
-            span[1] = 1;
-            span[2] = 2;
-
-            ArrowBuffer buffer = new ArrowBuffer(memory);
-            Assert.Equal(2, buffer.Span.CastTo<int>()[2]);
-
-            span[2] = 10;
-            Assert.Equal(10, buffer.Span.CastTo<int>()[2]);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowFileReaderTests.cs b/csharp/test/Apache.Arrow.Tests/ArrowFileReaderTests.cs
deleted file mode 100644
index 585b1ac..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrowFileReaderTests.cs
+++ /dev/null
@@ -1,172 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Ipc;
-using System;
-using System.IO;
-using System.Reflection;
-using System.Threading.Tasks;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ArrowFileReaderTests
-    {
-        [Fact]
-        public void Ctor_LeaveOpenDefault_StreamClosedOnDispose()
-        {
-            var stream = new MemoryStream();
-            new ArrowFileReader(stream).Dispose();
-            Assert.Throws<ObjectDisposedException>(() => stream.Position);
-        }
-
-        [Fact]
-        public void Ctor_LeaveOpenFalse_StreamClosedOnDispose()
-        {
-            var stream = new MemoryStream();
-            new ArrowFileReader(stream, leaveOpen: false).Dispose();
-            Assert.Throws<ObjectDisposedException>(() => stream.Position);
-        }
-
-        [Fact]
-        public void Ctor_LeaveOpenTrue_StreamValidOnDispose()
-        {
-            var stream = new MemoryStream();
-            new ArrowFileReader(stream, leaveOpen: true).Dispose();
-            Assert.Equal(0, stream.Position);
-        }
-
-        [Theory]
-        [InlineData(true)]
-        [InlineData(false)]
-        public async Task Ctor_MemoryPool_AllocatesFromPool(bool shouldLeaveOpen)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-
-            using (MemoryStream stream = new MemoryStream())
-            {
-                ArrowFileWriter writer = new ArrowFileWriter(stream, originalBatch.Schema);
-                await writer.WriteRecordBatchAsync(originalBatch);
-                await writer.WriteEndAsync();
-                stream.Position = 0;
-
-                var memoryPool = new TestMemoryAllocator();
-                ArrowFileReader reader = new ArrowFileReader(stream, memoryPool, leaveOpen: shouldLeaveOpen);
-                reader.ReadNextRecordBatch();
-
-                Assert.Equal(2, memoryPool.Statistics.Allocations);
-                Assert.True(memoryPool.Statistics.BytesAllocated > 0);
-
-                reader.Dispose();
-
-                if (shouldLeaveOpen)
-                {
-                    Assert.True(stream.Position > 0);
-                }
-                else
-                {
-                    Assert.Throws<ObjectDisposedException>(() => stream.Position);
-                }
-            }
-        }
-
-        [Fact]
-        public async Task TestReadNextRecordBatch()
-        {
-            await TestReadRecordBatchHelper((reader, originalBatch) =>
-            {
-                ArrowReaderVerifier.VerifyReader(reader, originalBatch);
-                return Task.CompletedTask;
-            });
-        }
-
-        [Fact]
-        public async Task TestReadNextRecordBatchAsync()
-        {
-            await TestReadRecordBatchHelper(ArrowReaderVerifier.VerifyReaderAsync);
-        }
-
-        [Fact]
-        public async Task TestReadRecordBatchAsync()
-        {
-            await TestReadRecordBatchHelper(async (reader, originalBatch) =>
-            {
-                RecordBatch readBatch = await reader.ReadRecordBatchAsync(0);
-                ArrowReaderVerifier.CompareBatches(originalBatch, readBatch);
-
-                // You should be able to read the same record batch again
-                RecordBatch readBatch2 = await reader.ReadRecordBatchAsync(0);
-                ArrowReaderVerifier.CompareBatches(originalBatch, readBatch2);
-            });
-        }
-
-        private static async Task TestReadRecordBatchHelper(
-            Func<ArrowFileReader, RecordBatch, Task> verificationFunc)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-
-            using (MemoryStream stream = new MemoryStream())
-            {
-                ArrowFileWriter writer = new ArrowFileWriter(stream, originalBatch.Schema);
-                await writer.WriteRecordBatchAsync(originalBatch);
-                await writer.WriteEndAsync();
-                stream.Position = 0;
-
-                ArrowFileReader reader = new ArrowFileReader(stream);
-                await verificationFunc(reader, originalBatch);
-            }
-        }
-
-        [Fact]
-        public async Task TestReadMultipleRecordBatchAsync()
-        {
-            RecordBatch originalBatch1 = TestData.CreateSampleRecordBatch(length: 100, createDictionaryArray: false);
-            RecordBatch originalBatch2 = TestData.CreateSampleRecordBatch(length: 50, createDictionaryArray: false);
-
-            using (MemoryStream stream = new MemoryStream())
-            {
-                ArrowFileWriter writer = new ArrowFileWriter(stream, originalBatch1.Schema);
-                await writer.WriteRecordBatchAsync(originalBatch1);
-                await writer.WriteRecordBatchAsync(originalBatch2);
-                await writer.WriteEndAsync();
-                stream.Position = 0;
-
-                ArrowFileReader reader = new ArrowFileReader(stream);
-                RecordBatch readBatch1 = await reader.ReadRecordBatchAsync(0);
-                ArrowReaderVerifier.CompareBatches(originalBatch1, readBatch1);
-
-                RecordBatch readBatch2 = await reader.ReadRecordBatchAsync(1);
-                ArrowReaderVerifier.CompareBatches(originalBatch2, readBatch2);
-
-                // now read the first again, for random access
-                RecordBatch readBatch3 = await reader.ReadRecordBatchAsync(0);
-                ArrowReaderVerifier.CompareBatches(originalBatch1, readBatch3);
-            }
-        }
-
-        [Fact]
-        public void TestRecordBatchBasics()
-        {
-            RecordBatch recordBatch = TestData.CreateSampleRecordBatch(length: 1);
-            Assert.Throws<ArgumentOutOfRangeException>(() => new RecordBatch(recordBatch.Schema, recordBatch.Arrays, -1));
-
-            var col1 = recordBatch.Column(0);
-            var col2 = recordBatch.Column("list0");
-            ArrowReaderVerifier.CompareArrays(col1, col2);
-
-            recordBatch.Dispose();
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowFileWriterTests.cs b/csharp/test/Apache.Arrow.Tests/ArrowFileWriterTests.cs
deleted file mode 100644
index 7b25910..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrowFileWriterTests.cs
+++ /dev/null
@@ -1,326 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Ipc;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ArrowFileWriterTests
-    {
-        [Fact]
-        public void Ctor_LeaveOpenDefault_StreamClosedOnDispose()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-            var stream = new MemoryStream();
-            new ArrowFileWriter(stream, originalBatch.Schema).Dispose();
-            Assert.Throws<ObjectDisposedException>(() => stream.Position);
-        }
-
-        [Fact]
-        public void Ctor_LeaveOpenFalse_StreamClosedOnDispose()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-            var stream = new MemoryStream();
-            new ArrowFileWriter(stream, originalBatch.Schema, leaveOpen: false).Dispose();
-            Assert.Throws<ObjectDisposedException>(() => stream.Position);
-        }
-
-        [Fact]
-        public void Ctor_LeaveOpenTrue_StreamValidOnDispose()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-            var stream = new MemoryStream();
-            new ArrowFileWriter(stream, originalBatch.Schema, leaveOpen: true).Dispose();
-            Assert.Equal(0, stream.Position);
-        }
-
-        /// <summary>
-        /// Tests that writing an arrow file will always align the Block lengths
-        /// to 8 bytes. There are asserts in both the reader and writer which will fail
-        /// if this isn't the case.
-        /// </summary>
-        /// <returns></returns>
-        [Fact]
-        public async Task WritesFooterAlignedMultipleOf8()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-
-            var stream = new MemoryStream();
-            var writer = new ArrowFileWriter(
-                stream,
-                originalBatch.Schema,
-                leaveOpen: true,
-                // use WriteLegacyIpcFormat, which only uses a 4-byte length prefix
-                // which causes the length prefix to not be 8-byte aligned by default
-                new IpcOptions() { WriteLegacyIpcFormat = true });
-
-            writer.WriteRecordBatch(originalBatch);
-            writer.WriteEnd();
-
-            stream.Position = 0;
-
-            await ValidateRecordBatchFile(stream, originalBatch);
-        }
-
-        /// <summary>
-        /// Tests that writing an arrow file will always align the Block lengths
-        /// to 8 bytes. There are asserts in both the reader and writer which will fail
-        /// if this isn't the case.
-        /// </summary>
-        /// <returns></returns>
-        [Fact]
-        public async Task WritesFooterAlignedMultipleOf8Async()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-
-            var stream = new MemoryStream();
-            var writer = new ArrowFileWriter(
-                stream,
-                originalBatch.Schema,
-                leaveOpen: true,
-                // use WriteLegacyIpcFormat, which only uses a 4-byte length prefix
-                // which causes the length prefix to not be 8-byte aligned by default
-                new IpcOptions() { WriteLegacyIpcFormat = true });
-
-            await writer.WriteRecordBatchAsync(originalBatch);
-            await writer.WriteEndAsync();
-
-            stream.Position = 0;
-
-            await ValidateRecordBatchFile(stream, originalBatch);
-        }
-
-        [Theory]
-        [InlineData(0, 45)]
-        [InlineData(3, 45)]
-        [InlineData(16, 45)]
-        [InlineData(10, 0)]
-        public async Task WriteSlicedArrays(int sliceOffset, int sliceLength)
-        {
-            var originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-            var slicedArrays = originalBatch.Arrays
-                .Select(array => ArrowArrayFactory.Slice(array, sliceOffset, sliceLength))
-                .ToList();
-            var slicedBatch = new RecordBatch(originalBatch.Schema, slicedArrays, sliceLength);
-
-            var stream = new MemoryStream();
-            var writer = new ArrowFileWriter(stream, slicedBatch.Schema, leaveOpen: true);
-
-            await writer.WriteRecordBatchAsync(slicedBatch);
-            await writer.WriteEndAsync();
-
-            stream.Position = 0;
-
-            // Disable strict comparison because we don't expect buffers to match exactly
-            // due to writing slices of buffers, and instead need to compare array values
-            await ValidateRecordBatchFile(stream, slicedBatch, strictCompare: false);
-        }
-
-        [Theory]
-        [InlineData(0, 100)]
-        [InlineData(0, 50)]
-        [InlineData(50, 50)]
-        [InlineData(25, 50)]
-        public async Task WriteListViewDataWithUnorderedOffsets(int sliceOffset, int sliceLength)
-        {
-            // A list-view array doesn't require that offsets are ordered,
-            // so verify that we can round trip a list-view array with out-of-order offsets.
-            const int length = 100;
-            var random = new Random();
-
-            var randomizedIndices = Enumerable.Range(0, length).ToArray();
-            Shuffle(randomizedIndices, random);
-
-            var offsetsBuilder = new ArrowBuffer.Builder<int>().Resize(length);
-            var sizesBuilder = new ArrowBuffer.Builder<int>().Resize(length);
-            var validityBuilder = new ArrowBuffer.BitmapBuilder().Reserve(length);
-
-            var valuesLength = 0;
-            for (int i = 0; i < length; ++i)
-            {
-                var index = randomizedIndices[i];
-                var listLength = random.Next(0, 10);
-                offsetsBuilder.Span[index] = valuesLength;
-                sizesBuilder.Span[index] = listLength;
-                valuesLength += listLength;
-
-                validityBuilder.Append(random.NextDouble() < 0.9);
-            }
-
-            var valuesBuilder = new Int64Array.Builder().Reserve(valuesLength);
-            for (int i = 0; i < valuesLength; ++i)
-            {
-                valuesBuilder.Append(random.Next(0, 1_000));
-            }
-
-            var type = new ListViewType(new Int64Type());
-            var offsets = offsetsBuilder.Build();
-            var sizes = sizesBuilder.Build();
-            var values = valuesBuilder.Build();
-            var nullCount = validityBuilder.UnsetBitCount;
-            var validityBuffer = validityBuilder.Build();
-
-            IArrowArray listViewArray = new ListViewArray(
-                type, length, offsets, sizes, values, validityBuffer, nullCount);
-
-            if (sliceOffset != 0 || sliceLength != length)
-            {
-                listViewArray = ArrowArrayFactory.Slice(listViewArray, sliceOffset, sliceLength);
-            }
-
-            var recordBatch = new RecordBatch.Builder().Append("x", true, listViewArray).Build();
-
-            var stream = new MemoryStream();
-            var writer = new ArrowFileWriter(stream, recordBatch.Schema, leaveOpen: true);
-
-            await writer.WriteRecordBatchAsync(recordBatch);
-            await writer.WriteEndAsync();
-
-            stream.Position = 0;
-
-            await ValidateRecordBatchFile(stream, recordBatch, strictCompare: false);
-        }
-
-        private async Task ValidateRecordBatchFile(Stream stream, RecordBatch recordBatch, bool strictCompare = true)
-        {
-            var reader = new ArrowFileReader(stream);
-            int count = await reader.RecordBatchCountAsync();
-            Assert.Equal(1, count);
-            RecordBatch readBatch = await reader.ReadRecordBatchAsync(0);
-            ArrowReaderVerifier.CompareBatches(recordBatch, readBatch, strictCompare);
-        }
-
-        /// <summary>
-        /// Tests that writing an arrow file with no RecordBatches produces the correct
-        /// file.
-        /// </summary>
-        [Fact]
-        public async Task WritesEmptyFile()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 1);
-
-            var stream = new MemoryStream();
-            var writer = new ArrowFileWriter(stream, originalBatch.Schema);
-
-            writer.WriteStart();
-            writer.WriteEnd();
-
-            stream.Position = 0;
-
-            var reader = new ArrowFileReader(stream);
-            int count = await reader.RecordBatchCountAsync();
-            Assert.Equal(0, count);
-            RecordBatch readBatch = reader.ReadNextRecordBatch();
-            Assert.Null(readBatch);
-            SchemaComparer.Compare(originalBatch.Schema, reader.Schema);
-        }
-
-        /// <summary>
-        /// Tests that writing an arrow file with no RecordBatches produces the correct
-        /// file when using WriteStartAsync and WriteEndAsync.
-        /// </summary>
-        [Fact]
-        public async Task WritesEmptyFileAsync()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 1);
-
-            var stream = new MemoryStream();
-            var writer = new ArrowFileWriter(stream, originalBatch.Schema);
-
-            await writer.WriteStartAsync();
-            await writer.WriteEndAsync();
-
-            stream.Position = 0;
-
-            var reader = new ArrowFileReader(stream);
-            int count = await reader.RecordBatchCountAsync();
-            Assert.Equal(0, count);
-            RecordBatch readBatch = reader.ReadNextRecordBatch();
-            Assert.Null(readBatch);
-            SchemaComparer.Compare(originalBatch.Schema, reader.Schema);
-        }
-
-        [Fact]
-        public async Task WriteBinaryArrayWithEmptyOffsets()
-        {
-            // Empty binary arrays generated by the C# builder have a single offset,
-            // but some implementations may produce an empty offsets buffer.
-
-            var array = new BinaryArray(
-                new BinaryType(),
-                length: 0,
-                valueOffsetsBuffer: ArrowBuffer.Empty,
-                dataBuffer: ArrowBuffer.Empty,
-                nullBitmapBuffer: ArrowBuffer.Empty,
-                nullCount: 0);
-
-            var recordBatch = new RecordBatch.Builder().Append("x", true, array).Build();
-
-            var stream = new MemoryStream();
-            var writer = new ArrowFileWriter(stream, recordBatch.Schema, leaveOpen: true);
-
-            await writer.WriteRecordBatchAsync(recordBatch);
-            await writer.WriteEndAsync();
-
-            stream.Position = 0;
-
-            await ValidateRecordBatchFile(stream, recordBatch, strictCompare: false);
-        }
-
-        [Fact]
-        public async Task WriteListArrayWithEmptyOffsets()
-        {
-            var values = new Int32Array.Builder().Build();
-            var array = new ListArray(
-                new ListType(new Int32Type()),
-                length: 0,
-                valueOffsetsBuffer: ArrowBuffer.Empty,
-                values: values,
-                nullBitmapBuffer: ArrowBuffer.Empty,
-                nullCount: 0);
-
-            var recordBatch = new RecordBatch.Builder().Append("x", true, array).Build();
-
-            var stream = new MemoryStream();
-            var writer = new ArrowFileWriter(stream, recordBatch.Schema, leaveOpen: true);
-
-            await writer.WriteRecordBatchAsync(recordBatch);
-            await writer.WriteEndAsync();
-
-            stream.Position = 0;
-
-            await ValidateRecordBatchFile(stream, recordBatch, strictCompare: false);
-        }
-
-        private static void Shuffle(int[] values, Random random)
-        {
-            var length = values.Length;
-            for (int i = 0; i < length - 1; ++i)
-            {
-                var j = random.Next(i, length);
-                var tmp = values[i];
-                values[i] = values[j];
-                values[j] = tmp;
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowReaderVerifier.cs b/csharp/test/Apache.Arrow.Tests/ArrowReaderVerifier.cs
deleted file mode 100644
index 5977c32..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrowReaderVerifier.cs
+++ /dev/null
@@ -1,603 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Ipc;
-using Apache.Arrow.Types;
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-using Apache.Arrow.Arrays;
-using Xunit;
-using System.Diagnostics;
-
-namespace Apache.Arrow.Tests
-{
-    public static class ArrowReaderVerifier
-    {
-        public static void VerifyReader(ArrowStreamReader reader, RecordBatch originalBatch)
-        {
-            RecordBatch readBatch = reader.ReadNextRecordBatch();
-            CompareBatches(originalBatch, readBatch);
-
-            // There should only be one batch - calling ReadNextRecordBatch again should return null.
-            Assert.Null(reader.ReadNextRecordBatch());
-            Assert.Null(reader.ReadNextRecordBatch());
-        }
-
-        public static async Task VerifyReaderAsync(ArrowStreamReader reader, RecordBatch originalBatch)
-        {
-            Schema schema = await reader.GetSchema();
-            Assert.NotNull(schema);
-
-            RecordBatch readBatch = await reader.ReadNextRecordBatchAsync();
-            CompareBatches(originalBatch, readBatch);
-
-            // There should only be one batch - calling ReadNextRecordBatchAsync again should return null.
-            Assert.Null(await reader.ReadNextRecordBatchAsync());
-            Assert.Null(await reader.ReadNextRecordBatchAsync());
-        }
-
-        public static void CompareBatches(RecordBatch expectedBatch, RecordBatch actualBatch, bool strictCompare = true)
-        {
-            SchemaComparer.Compare(expectedBatch.Schema, actualBatch.Schema);
-            Assert.Equal(expectedBatch.Length, actualBatch.Length);
-            Assert.Equal(expectedBatch.ColumnCount, actualBatch.ColumnCount);
-
-            for (int i = 0; i < expectedBatch.ColumnCount; i++)
-            {
-                IArrowArray expectedArray = expectedBatch.Arrays.ElementAt(i);
-                IArrowArray actualArray = actualBatch.Arrays.ElementAt(i);
-
-                CompareArrays(expectedArray, actualArray, strictCompare);
-            }
-        }
-
-        public static void CompareArrays(IArrowArray expectedArray, IArrowArray actualArray, bool strictCompare = true)
-        {
-            actualArray.Accept(new ArrayComparer(expectedArray, strictCompare));
-        }
-
-        private class ArrayComparer :
-            IArrowArrayVisitor<Int8Array>,
-            IArrowArrayVisitor<Int16Array>,
-            IArrowArrayVisitor<Int32Array>,
-            IArrowArrayVisitor<Int64Array>,
-            IArrowArrayVisitor<UInt8Array>,
-            IArrowArrayVisitor<UInt16Array>,
-            IArrowArrayVisitor<UInt32Array>,
-            IArrowArrayVisitor<UInt64Array>,
-#if NET5_0_OR_GREATER
-            IArrowArrayVisitor<HalfFloatArray>,
-#endif
-            IArrowArrayVisitor<FloatArray>,
-            IArrowArrayVisitor<DoubleArray>,
-            IArrowArrayVisitor<BooleanArray>,
-            IArrowArrayVisitor<TimestampArray>,
-            IArrowArrayVisitor<Date32Array>,
-            IArrowArrayVisitor<Date64Array>,
-            IArrowArrayVisitor<Time32Array>,
-            IArrowArrayVisitor<Time64Array>,
-            IArrowArrayVisitor<DurationArray>,
-            IArrowArrayVisitor<YearMonthIntervalArray>,
-            IArrowArrayVisitor<DayTimeIntervalArray>,
-            IArrowArrayVisitor<MonthDayNanosecondIntervalArray>,
-            IArrowArrayVisitor<ListArray>,
-            IArrowArrayVisitor<ListViewArray>,
-            IArrowArrayVisitor<LargeListArray>,
-            IArrowArrayVisitor<FixedSizeListArray>,
-            IArrowArrayVisitor<StringArray>,
-            IArrowArrayVisitor<StringViewArray>,
-            IArrowArrayVisitor<LargeStringArray>,
-            IArrowArrayVisitor<FixedSizeBinaryArray>,
-            IArrowArrayVisitor<BinaryArray>,
-            IArrowArrayVisitor<BinaryViewArray>,
-            IArrowArrayVisitor<LargeBinaryArray>,
-            IArrowArrayVisitor<StructArray>,
-            IArrowArrayVisitor<UnionArray>,
-            IArrowArrayVisitor<Decimal32Array>,
-            IArrowArrayVisitor<Decimal64Array>,
-            IArrowArrayVisitor<Decimal128Array>,
-            IArrowArrayVisitor<Decimal256Array>,
-            IArrowArrayVisitor<DictionaryArray>,
-            IArrowArrayVisitor<NullArray>
-        {
-            private readonly IArrowArray _expectedArray;
-            private readonly ArrayTypeComparer _arrayTypeComparer;
-            private readonly bool _strictCompare;
-
-            public ArrayComparer(IArrowArray expectedArray, bool strictCompare)
-            {
-                _expectedArray = expectedArray;
-                _arrayTypeComparer = new ArrayTypeComparer(expectedArray.Data.DataType);
-                _strictCompare = strictCompare;
-            }
-
-            public void Visit(Int8Array array) => CompareArrays(array);
-            public void Visit(Int16Array array) => CompareArrays(array);
-            public void Visit(Int32Array array) => CompareArrays(array);
-            public void Visit(Int64Array array) => CompareArrays(array);
-            public void Visit(UInt8Array array) => CompareArrays(array);
-            public void Visit(UInt16Array array) => CompareArrays(array);
-            public void Visit(UInt32Array array) => CompareArrays(array);
-            public void Visit(UInt64Array array) => CompareArrays(array);
-#if NET5_0_OR_GREATER
-            public void Visit(HalfFloatArray array) => CompareArrays(array);
-#endif
-            public void Visit(FloatArray array) => CompareArrays(array);
-            public void Visit(DoubleArray array) => CompareArrays(array);
-            public void Visit(BooleanArray array) => CompareArrays(array);
-            public void Visit(TimestampArray array) => CompareArrays(array);
-            public void Visit(Date32Array array) => CompareArrays(array);
-            public void Visit(Date64Array array) => CompareArrays(array);
-            public void Visit(Time32Array array) => CompareArrays(array);
-            public void Visit(Time64Array array) => CompareArrays(array);
-            public void Visit(DurationArray array) => CompareArrays(array);
-            public void Visit(YearMonthIntervalArray array) => CompareArrays(array);
-            public void Visit(DayTimeIntervalArray array) => CompareArrays(array);
-            public void Visit(MonthDayNanosecondIntervalArray array) => CompareArrays(array);
-            public void Visit(ListArray array) => CompareArrays(array);
-            public void Visit(ListViewArray array) => CompareArrays(array);
-            public void Visit(LargeListArray array) => CompareArrays(array);
-            public void Visit(FixedSizeListArray array) => CompareArrays(array);
-            public void Visit(FixedSizeBinaryArray array) => CompareArrays(array);
-            public void Visit(Decimal32Array array) => CompareArrays(array);
-            public void Visit(Decimal64Array array) => CompareArrays(array);
-            public void Visit(Decimal128Array array) => CompareArrays(array);
-            public void Visit(Decimal256Array array) => CompareArrays(array);
-            public void Visit(StringArray array) => CompareBinaryArrays<StringArray>(array);
-            public void Visit(StringViewArray array) => CompareVariadicArrays<StringViewArray>(array);
-            public void Visit(LargeStringArray array) => CompareLargeBinaryArrays<LargeStringArray>(array);
-            public void Visit(BinaryArray array) => CompareBinaryArrays<BinaryArray>(array);
-            public void Visit(BinaryViewArray array) => CompareVariadicArrays<BinaryViewArray>(array);
-            public void Visit(LargeBinaryArray array) => CompareLargeBinaryArrays<LargeBinaryArray>(array);
-
-            public void Visit(StructArray array)
-            {
-                Assert.IsAssignableFrom<StructArray>(_expectedArray);
-                StructArray expectedArray = (StructArray)_expectedArray;
-
-                Assert.Equal(expectedArray.Length, array.Length);
-                Assert.Equal(expectedArray.NullCount, array.NullCount);
-                Assert.Equal(expectedArray.Data.Children.Length, array.Data.Children.Length);
-                Assert.Equal(expectedArray.Fields.Count, array.Fields.Count);
-
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, array.Offset);
-                }
-
-                for (int i = 0; i < array.Fields.Count; i++)
-                {
-                    array.Fields[i].Accept(new ArrayComparer(expectedArray.Fields[i], _strictCompare));
-                }
-            }
-
-            public void Visit(UnionArray array)
-            {
-                Assert.IsAssignableFrom<UnionArray>(_expectedArray);
-                UnionArray expectedArray = (UnionArray)_expectedArray;
-
-                Assert.Equal(expectedArray.Mode, array.Mode);
-                Assert.Equal(expectedArray.Length, array.Length);
-                Assert.Equal(expectedArray.NullCount, array.NullCount);
-                Assert.Equal(expectedArray.Data.Children.Length, array.Data.Children.Length);
-                Assert.Equal(expectedArray.Fields.Count, array.Fields.Count);
-
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, array.Offset);
-                    Assert.True(expectedArray.TypeBuffer.Span.SequenceEqual(array.TypeBuffer.Span));
-                }
-                else
-                {
-                    for (int i = 0; i < expectedArray.Length; i++)
-                    {
-                        Assert.Equal(expectedArray.TypeIds[i], array.TypeIds[i]);
-                    }
-                }
-
-                if (_expectedArray is DenseUnionArray expectedDenseArray)
-                {
-                    Assert.IsAssignableFrom<DenseUnionArray>(array);
-                    var denseArray = array as DenseUnionArray;
-                    Assert.NotNull(denseArray);
-
-                    if (_strictCompare)
-                    {
-                        Assert.True(expectedDenseArray.ValueOffsetBuffer.Span.SequenceEqual(denseArray.ValueOffsetBuffer.Span));
-                    }
-                    else
-                    {
-                        for (int i = 0; i < expectedDenseArray.Length; i++)
-                        {
-                            Assert.Equal(
-                                expectedDenseArray.ValueOffsets[i], denseArray.ValueOffsets[i]);
-                        }
-                    }
-                }
-
-                for (int i = 0; i < array.Fields.Count; i++)
-                {
-                    array.Fields[i].Accept(new ArrayComparer(expectedArray.Fields[i], _strictCompare));
-                }
-            }
-
-            public void Visit(DictionaryArray array)
-            {
-                Assert.IsAssignableFrom<DictionaryArray>(_expectedArray);
-                DictionaryArray expectedArray = (DictionaryArray)_expectedArray;
-                var indicesComparer = new ArrayComparer(expectedArray.Indices, _strictCompare);
-                var dictionaryComparer = new ArrayComparer(expectedArray.Dictionary, _strictCompare);
-                array.Indices.Accept(indicesComparer);
-                array.Dictionary.Accept(dictionaryComparer);
-            }
-
-            public void Visit(NullArray array)
-            {
-                Assert.IsAssignableFrom<NullArray>(_expectedArray);
-                Assert.Equal(_expectedArray.Length, array.Length);
-                Assert.Equal(_expectedArray.NullCount, array.NullCount);
-                Assert.Equal(_expectedArray.Offset, array.Offset);
-            }
-
-            public void Visit(IArrowArray array) => throw new NotImplementedException();
-
-            private void CompareBinaryArrays<T>(BinaryArray actualArray)
-                where T : IArrowArray
-            {
-                Assert.IsAssignableFrom<T>(_expectedArray);
-                Assert.IsAssignableFrom<T>(actualArray);
-
-                var expectedArray = (BinaryArray)_expectedArray;
-
-                actualArray.Data.DataType.Accept(_arrayTypeComparer);
-
-                Assert.Equal(expectedArray.Length, actualArray.Length);
-                Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
-
-                CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, expectedArray.Offset, actualArray.NullBitmapBuffer, actualArray.Offset);
-
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, actualArray.Offset);
-                    Assert.True(expectedArray.ValueOffsetsBuffer.Span.SequenceEqual(actualArray.ValueOffsetsBuffer.Span));
-                    Assert.True(expectedArray.Values.Slice(0, expectedArray.Length).SequenceEqual(actualArray.Values.Slice(0, actualArray.Length)));
-                }
-                else
-                {
-                    for (int i = 0; i < expectedArray.Length; i++)
-                    {
-                        Assert.True(
-                            expectedArray.GetBytes(i).SequenceEqual(actualArray.GetBytes(i)),
-                            $"BinaryArray values do not match at index {i}.");
-                    }
-                }
-            }
-
-            private void CompareLargeBinaryArrays<T>(LargeBinaryArray actualArray)
-                where T : IArrowArray
-            {
-                Assert.IsAssignableFrom<T>(_expectedArray);
-                Assert.IsAssignableFrom<T>(actualArray);
-
-                var expectedArray = (LargeBinaryArray)_expectedArray;
-
-                actualArray.Data.DataType.Accept(_arrayTypeComparer);
-
-                Assert.Equal(expectedArray.Length, actualArray.Length);
-                Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
-
-                CompareValidityBuffer(
-                    expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer,
-                    expectedArray.Offset, actualArray.NullBitmapBuffer, actualArray.Offset);
-
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, actualArray.Offset);
-                    Assert.True(expectedArray.ValueOffsetsBuffer.Span.SequenceEqual(actualArray.ValueOffsetsBuffer.Span));
-                    Assert.True(expectedArray.ValueBuffer.Span.Slice(0, expectedArray.Length).SequenceEqual(actualArray.ValueBuffer.Span.Slice(0, actualArray.Length)));
-                }
-                else
-                {
-                    for (int i = 0; i < expectedArray.Length; i++)
-                    {
-                        Assert.True(
-                            expectedArray.GetBytes(i).SequenceEqual(actualArray.GetBytes(i)),
-                            $"LargeBinaryArray values do not match at index {i}.");
-                    }
-                }
-            }
-
-            private void CompareVariadicArrays<T>(BinaryViewArray actualArray)
-                where T : IArrowArray
-            {
-                Assert.IsAssignableFrom<T>(_expectedArray);
-                Assert.IsAssignableFrom<T>(actualArray);
-
-                var expectedArray = (BinaryViewArray)_expectedArray;
-
-                actualArray.Data.DataType.Accept(_arrayTypeComparer);
-
-                Assert.Equal(expectedArray.Length, actualArray.Length);
-                Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
-
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, actualArray.Offset);
-                }
-
-                CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, expectedArray.Offset, actualArray.NullBitmapBuffer, actualArray.Offset);
-
-                Assert.True(expectedArray.Views.SequenceEqual(actualArray.Views));
-
-                for (int i = 0; i < expectedArray.Length; i++)
-                {
-                    Assert.True(
-                        expectedArray.GetBytes(i).SequenceEqual(actualArray.GetBytes(i)),
-                        $"BinaryArray values do not match at index {i}.");
-                }
-            }
-
-            private void CompareArrays(FixedSizeBinaryArray actualArray)
-            {
-                Assert.IsAssignableFrom<FixedSizeBinaryArray>(_expectedArray);
-                Assert.IsAssignableFrom<FixedSizeBinaryArray>(actualArray);
-
-                var expectedArray = (FixedSizeBinaryArray)_expectedArray;
-
-                actualArray.Data.DataType.Accept(_arrayTypeComparer);
-
-                Assert.Equal(expectedArray.Length, actualArray.Length);
-                Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
-
-                CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, expectedArray.Offset, actualArray.NullBitmapBuffer, actualArray.Offset);
-
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, actualArray.Offset);
-                    Assert.True(expectedArray.ValueBuffer.Span.Slice(0, expectedArray.Length).SequenceEqual(actualArray.ValueBuffer.Span.Slice(0, actualArray.Length)));
-                }
-                else
-                {
-                    for (int i = 0; i < expectedArray.Length; i++)
-                    {
-                        Assert.True(
-                            expectedArray.GetBytes(i).SequenceEqual(actualArray.GetBytes(i)),
-                            $"FixedSizeBinaryArray values do not match at index {i}.");
-                    }
-                }
-            }
-
-            private void CompareArrays<T>(PrimitiveArray<T> actualArray)
-                where T : struct, IEquatable<T>
-            {
-                Assert.IsAssignableFrom<PrimitiveArray<T>>(_expectedArray);
-                PrimitiveArray<T> expectedArray = (PrimitiveArray<T>)_expectedArray;
-
-                actualArray.Data.DataType.Accept(_arrayTypeComparer);
-
-                Assert.Equal(expectedArray.Length, actualArray.Length);
-                Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
-
-                CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, expectedArray.Offset, actualArray.NullBitmapBuffer, actualArray.Offset);
-
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, actualArray.Offset);
-                    Assert.True(expectedArray.Values.Slice(0, expectedArray.Length).SequenceEqual(actualArray.Values.Slice(0, actualArray.Length)));
-                }
-                else
-                {
-                    for (int i = 0; i < expectedArray.Length; i++)
-                    {
-                        T? expected = expectedArray.GetValue(i);
-                        T? actual = actualArray.GetValue(i);
-                        Assert.Equal(expected.HasValue, actual.HasValue);
-                        if (expected.HasValue)
-                        {
-                            Assert.Equal(expected.Value, actual.Value);
-                        }
-                    }
-                }
-            }
-
-            private void CompareArrays(BooleanArray actualArray)
-            {
-                Assert.IsAssignableFrom<BooleanArray>(_expectedArray);
-                BooleanArray expectedArray = (BooleanArray)_expectedArray;
-
-                actualArray.Data.DataType.Accept(_arrayTypeComparer);
-
-                Assert.Equal(expectedArray.Length, actualArray.Length);
-                Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
-
-                CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, expectedArray.Offset, actualArray.NullBitmapBuffer, actualArray.Offset);
-
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, actualArray.Offset);
-                    int booleanByteCount = BitUtility.ByteCount(expectedArray.Length);
-                    Assert.True(expectedArray.Values.Slice(0, booleanByteCount).SequenceEqual(actualArray.Values.Slice(0, booleanByteCount)));
-                }
-                else
-                {
-                    for (int i = 0; i < expectedArray.Length; i++)
-                    {
-                        Assert.Equal(expectedArray.GetValue(i), actualArray.GetValue(i));
-                    }
-                }
-            }
-
-            private void CompareArrays(ListArray actualArray)
-            {
-                Assert.IsAssignableFrom<ListArray>(_expectedArray);
-                ListArray expectedArray = (ListArray)_expectedArray;
-
-                actualArray.Data.DataType.Accept(_arrayTypeComparer);
-
-                Assert.Equal(expectedArray.Length, actualArray.Length);
-                Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
-
-                CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, expectedArray.Offset, actualArray.NullBitmapBuffer, actualArray.Offset);
-
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, actualArray.Offset);
-                    Assert.True(expectedArray.ValueOffsetsBuffer.Span.SequenceEqual(actualArray.ValueOffsetsBuffer.Span));
-                    actualArray.Values.Accept(new ArrayComparer(expectedArray.Values, _strictCompare));
-                }
-                else
-                {
-                    for (int i = 0; i < actualArray.Length; ++i)
-                    {
-                        if (expectedArray.IsNull(i))
-                        {
-                            Assert.True(actualArray.IsNull(i));
-                        }
-                        else
-                        {
-                            var expectedList = expectedArray.GetSlicedValues(i);
-                            var actualList = actualArray.GetSlicedValues(i);
-                            actualList.Accept(new ArrayComparer(expectedList, _strictCompare));
-                        }
-                    }
-                }
-            }
-
-            private void CompareArrays(ListViewArray actualArray)
-            {
-                Assert.IsAssignableFrom<ListViewArray>(_expectedArray);
-                ListViewArray expectedArray = (ListViewArray)_expectedArray;
-
-                actualArray.Data.DataType.Accept(_arrayTypeComparer);
-
-                Assert.Equal(expectedArray.Length, actualArray.Length);
-                Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
-
-                CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, expectedArray.Offset, actualArray.NullBitmapBuffer, actualArray.Offset);
-
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, actualArray.Offset);
-                    Assert.True(expectedArray.ValueOffsetsBuffer.Span.SequenceEqual(actualArray.ValueOffsetsBuffer.Span));
-                    Assert.True(expectedArray.SizesBuffer.Span.SequenceEqual(actualArray.SizesBuffer.Span));
-                    actualArray.Values.Accept(new ArrayComparer(expectedArray.Values, _strictCompare));
-                }
-                else
-                {
-                    for (int i = 0; i < actualArray.Length; ++i)
-                    {
-                        if (expectedArray.IsNull(i))
-                        {
-                            Assert.True(actualArray.IsNull(i));
-                        }
-                        else
-                        {
-                            var expectedList = expectedArray.GetSlicedValues(i);
-                            var actualList = actualArray.GetSlicedValues(i);
-                            actualList.Accept(new ArrayComparer(expectedList, _strictCompare));
-                        }
-                    }
-                }
-            }
-
-            private void CompareArrays(LargeListArray actualArray)
-            {
-                Assert.IsAssignableFrom<LargeListArray>(_expectedArray);
-                LargeListArray expectedArray = (LargeListArray)_expectedArray;
-
-                actualArray.Data.DataType.Accept(_arrayTypeComparer);
-
-                Assert.Equal(expectedArray.Length, actualArray.Length);
-                Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
-
-                CompareValidityBuffer(
-                    expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer,
-                    expectedArray.Offset, actualArray.NullBitmapBuffer, actualArray.Offset);
-
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, actualArray.Offset);
-                    Assert.True(expectedArray.ValueOffsetsBuffer.Span.SequenceEqual(actualArray.ValueOffsetsBuffer.Span));
-                    actualArray.Values.Accept(new ArrayComparer(expectedArray.Values, _strictCompare));
-                }
-                else
-                {
-                    for (int i = 0; i < actualArray.Length; ++i)
-                    {
-                        if (expectedArray.IsNull(i))
-                        {
-                            Assert.True(actualArray.IsNull(i));
-                        }
-                        else
-                        {
-                            var expectedList = expectedArray.GetSlicedValues(i);
-                            var actualList = actualArray.GetSlicedValues(i);
-                            actualList.Accept(new ArrayComparer(expectedList, _strictCompare));
-                        }
-                    }
-                }
-            }
-
-            private void CompareArrays(FixedSizeListArray actualArray)
-            {
-                Assert.IsAssignableFrom<FixedSizeListArray>(_expectedArray);
-                FixedSizeListArray expectedArray = (FixedSizeListArray)_expectedArray;
-
-                actualArray.Data.DataType.Accept(_arrayTypeComparer);
-
-                Assert.Equal(expectedArray.Length, actualArray.Length);
-                Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
-                if (_strictCompare)
-                {
-                    Assert.Equal(expectedArray.Offset, actualArray.Offset);
-                }
-
-                CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, expectedArray.Offset, actualArray.NullBitmapBuffer, actualArray.Offset);
-
-                var listSize = ((FixedSizeListType)expectedArray.Data.DataType).ListSize;
-                var expectedValuesSlice = ArrowArrayFactory.Slice(
-                    expectedArray.Values, expectedArray.Offset * listSize, expectedArray.Length * listSize);
-                var actualValuesSlice = ArrowArrayFactory.Slice(
-                    actualArray.Values, actualArray.Offset * listSize, actualArray.Length * listSize);
-                actualValuesSlice.Accept(new ArrayComparer(expectedValuesSlice, _strictCompare));
-            }
-
-            private void CompareValidityBuffer(int nullCount, int arrayLength, ArrowBuffer expectedValidityBuffer, int expectedBufferOffset, ArrowBuffer actualValidityBuffer, int actualBufferOffset)
-            {
-                if (_strictCompare)
-                {
-                    Assert.True(expectedValidityBuffer.Span.SequenceEqual(actualValidityBuffer.Span));
-                }
-                else if (actualValidityBuffer.IsEmpty || expectedValidityBuffer.IsEmpty || arrayLength == 0)
-                {
-                    Assert.True(nullCount == 0 || arrayLength == 0);
-                }
-                else
-                {
-                    // Compare all values bitwise
-                    var expectedSpan = expectedValidityBuffer.Span;
-                    var actualSpan = actualValidityBuffer.Span;
-                    for (int i = 0; i < arrayLength; i++)
-                    {
-                        Assert.True(
-                            BitUtility.GetBit(expectedSpan, expectedBufferOffset + i) == BitUtility.GetBit(actualSpan, actualBufferOffset + i),
-                            string.Format("Bit at index {0}/{1} is not equal", i, arrayLength));
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowStreamReaderTests.cs b/csharp/test/Apache.Arrow.Tests/ArrowStreamReaderTests.cs
deleted file mode 100644
index c375457..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrowStreamReaderTests.cs
+++ /dev/null
@@ -1,285 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Ipc;
-using Apache.Arrow.Memory;
-using System;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ArrowStreamReaderTests
-    {
-        [Fact]
-        public void Ctor_LeaveOpenDefault_StreamClosedOnDispose()
-        {
-            var stream = new MemoryStream();
-            new ArrowStreamReader(stream).Dispose();
-            Assert.Throws<ObjectDisposedException>(() => stream.Position);
-        }
-
-        [Fact]
-        public void Ctor_LeaveOpenFalse_StreamClosedOnDispose()
-        {
-            var stream = new MemoryStream();
-            new ArrowStreamReader(stream, leaveOpen: false).Dispose();
-            Assert.Throws<ObjectDisposedException>(() => stream.Position);
-        }
-
-        [Fact]
-        public void Ctor_LeaveOpenTrue_StreamValidOnDispose()
-        {
-            var stream = new MemoryStream();
-            new ArrowStreamReader(stream, leaveOpen: true).Dispose();
-            Assert.Equal(0, stream.Position);
-        }
-
-        [Theory]
-        [InlineData(true, true, 2)]
-        [InlineData(true, false, 1)]
-        [InlineData(false, true, 2)]
-        [InlineData(false, false, 1)]
-        public async Task Ctor_MemoryPool_AllocatesFromPool(bool shouldLeaveOpen, bool createDictionaryArray, int expectedAllocations)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100, createDictionaryArray: createDictionaryArray);
-
-            using (MemoryStream stream = new MemoryStream())
-            {
-                ArrowStreamWriter writer = new ArrowStreamWriter(stream, originalBatch.Schema);
-                await writer.WriteRecordBatchAsync(originalBatch);
-                await writer.WriteEndAsync();
-
-                stream.Position = 0;
-
-                var memoryPool = new TestMemoryAllocator();
-                ArrowStreamReader reader = new ArrowStreamReader(stream, memoryPool, shouldLeaveOpen);
-                reader.ReadNextRecordBatch();
-
-                Assert.Equal(expectedAllocations, memoryPool.Statistics.Allocations);
-                Assert.True(memoryPool.Statistics.BytesAllocated > 0);
-
-                reader.Dispose();
-
-                if (shouldLeaveOpen)
-                {
-                    Assert.True(stream.Position > 0);
-                }
-                else
-                {
-                    Assert.Throws<ObjectDisposedException>(() => stream.Position);
-                }
-            }
-        }
-
-        [Theory]
-        [InlineData(true)]
-        [InlineData(false)]
-        public async Task ReadRecordBatch_Memory(bool writeEnd)
-        {
-            await TestReaderFromMemory((reader, originalBatch) =>
-            {
-                Assert.NotNull(reader.Schema);
-
-                ArrowReaderVerifier.VerifyReader(reader, originalBatch);
-                return Task.CompletedTask;
-            }, writeEnd);
-        }
-
-        [Theory]
-        [InlineData(true)]
-        [InlineData(false)]
-        public async Task ReadRecordBatchAsync_Memory(bool writeEnd)
-        {
-            await TestReaderFromMemory(ArrowReaderVerifier.VerifyReaderAsync, writeEnd);
-        }
-
-        private static async Task TestReaderFromMemory(
-            Func<ArrowStreamReader, RecordBatch, Task> verificationFunc,
-            bool writeEnd)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-
-            byte[] buffer;
-            using (MemoryStream stream = new MemoryStream())
-            {
-                ArrowStreamWriter writer = new ArrowStreamWriter(stream, originalBatch.Schema);
-                await writer.WriteRecordBatchAsync(originalBatch);
-                if (writeEnd)
-                {
-                    await writer.WriteEndAsync();
-                }
-                buffer = stream.GetBuffer();
-            }
-
-            ArrowStreamReader reader = new ArrowStreamReader(buffer);
-            await verificationFunc(reader, originalBatch);
-        }
-
-        [Fact]
-        public void ReadRecordBatch_EmptyStream()
-        {
-            using (MemoryStream stream = new())
-            {
-                ArrowStreamReader reader = new(stream);
-                RecordBatch readBatch = reader.ReadNextRecordBatch();
-                Assert.Null(readBatch);
-            }
-        }
-
-        [Theory]
-        [InlineData(true, true)]
-        [InlineData(true, false)]
-        [InlineData(false, true)]
-        [InlineData(false, false)]
-        public async Task ReadRecordBatch_Stream(bool writeEnd, bool createDictionaryArray)
-        {
-            await TestReaderFromStream((reader, originalBatch) =>
-            {
-                ArrowReaderVerifier.VerifyReader(reader, originalBatch);
-                return Task.CompletedTask;
-            }, writeEnd, createDictionaryArray);
-        }
-
-        [Fact]
-        public async Task ReadRecordBatchAsync_EmptyStream()
-        {
-            using (MemoryStream stream = new())
-            {
-                ArrowStreamReader reader = new(stream);
-                RecordBatch readBatch = await reader.ReadNextRecordBatchAsync();
-                Assert.Null(readBatch);
-            }
-        }
-
-        [Theory]
-        [InlineData(true, true)]
-        [InlineData(true, false)]
-        [InlineData(false, true)]
-        [InlineData(false, false)]
-        public async Task ReadRecordBatchAsync_Stream(bool writeEnd, bool createDictionaryArray)
-        {
-            await TestReaderFromStream(ArrowReaderVerifier.VerifyReaderAsync, writeEnd, createDictionaryArray);
-        }
-
-        private static async Task TestReaderFromStream(
-            Func<ArrowStreamReader, RecordBatch, Task> verificationFunc,
-            bool writeEnd, bool createDictionaryArray)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100, createDictionaryArray: createDictionaryArray);
-
-            using (MemoryStream stream = new MemoryStream())
-            {
-                ArrowStreamWriter writer = new ArrowStreamWriter(stream, originalBatch.Schema);
-                await writer.WriteRecordBatchAsync(originalBatch);
-                if (writeEnd)
-                {
-                    await writer.WriteEndAsync();
-                }
-
-                stream.Position = 0;
-
-                ArrowStreamReader reader = new ArrowStreamReader(stream);
-                await verificationFunc(reader, originalBatch);
-            }
-        }
-
-        [Theory]
-        [InlineData(true)]
-        [InlineData(false)]
-        public async Task ReadRecordBatch_PartialReadStream(bool createDictionaryArray)
-        {
-            await TestReaderFromPartialReadStream((reader, originalBatch) =>
-            {
-                ArrowReaderVerifier.VerifyReader(reader, originalBatch);
-                return Task.CompletedTask;
-            }, createDictionaryArray);
-        }
-
-        [Theory]
-        [InlineData(true)]
-        [InlineData(false)]
-        public async Task ReadRecordBatchAsync_PartialReadStream(bool createDictionaryArray)
-        {
-            await TestReaderFromPartialReadStream(ArrowReaderVerifier.VerifyReaderAsync, createDictionaryArray);
-        }
-
-        /// <summary>
-        /// Verifies that the stream reader reads multiple times when a stream
-        /// only returns a subset of the data from each Read.
-        /// </summary>
-        private static async Task TestReaderFromPartialReadStream(Func<ArrowStreamReader, RecordBatch, Task> verificationFunc, bool createDictionaryArray)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100, createDictionaryArray: createDictionaryArray);
-
-            using (PartialReadStream stream = new PartialReadStream())
-            {
-                ArrowStreamWriter writer = new ArrowStreamWriter(stream, originalBatch.Schema);
-                await writer.WriteRecordBatchAsync(originalBatch);
-                await writer.WriteEndAsync();
-
-                stream.Position = 0;
-
-                ArrowStreamReader reader = new ArrowStreamReader(stream);
-                await verificationFunc(reader, originalBatch);
-            }
-        }
-
-        /// <summary>
-        /// A stream class that only returns a part of the data at a time.
-        /// </summary>
-        private class PartialReadStream : MemoryStream
-        {
-            // by default return 20 bytes at a time
-            public int PartialReadLength { get; set; } = 20;
-
-#if NET5_0_OR_GREATER
-            public override int Read(Span<byte> destination)
-            {
-                if (destination.Length > PartialReadLength)
-                {
-                    destination = destination.Slice(0, PartialReadLength);
-                }
-
-                return base.Read(destination);
-            }
-
-            public override ValueTask<int> ReadAsync(Memory<byte> destination, CancellationToken cancellationToken = default)
-            {
-                if (destination.Length > PartialReadLength)
-                {
-                    destination = destination.Slice(0, PartialReadLength);
-                }
-
-                return base.ReadAsync(destination, cancellationToken);
-            }
-#else
-            public override int Read(byte[] buffer, int offset, int length)
-            {
-                return base.Read(buffer, offset, Math.Min(length, PartialReadLength));
-            }
-
-            public override Task<int> ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken = default)
-            {
-                return base.ReadAsync(buffer, offset, Math.Min(length, PartialReadLength), cancellationToken);
-            }
-#endif
-        }
-    }
-}
-
diff --git a/csharp/test/Apache.Arrow.Tests/ArrowStreamWriterTests.cs b/csharp/test/Apache.Arrow.Tests/ArrowStreamWriterTests.cs
deleted file mode 100644
index 570fb03..0000000
--- a/csharp/test/Apache.Arrow.Tests/ArrowStreamWriterTests.cs
+++ /dev/null
@@ -1,739 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Buffers.Binary;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-using Apache.Arrow.Ipc;
-using Apache.Arrow.Memory;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ArrowStreamWriterTests
-    {
-        [Fact]
-        public void Ctor_LeaveOpenDefault_StreamClosedOnDispose()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-            var stream = new MemoryStream();
-            new ArrowStreamWriter(stream, originalBatch.Schema).Dispose();
-            Assert.Throws<ObjectDisposedException>(() => stream.Position);
-        }
-
-        [Fact]
-        public void Ctor_LeaveOpenFalse_StreamClosedOnDispose()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-            var stream = new MemoryStream();
-            new ArrowStreamWriter(stream, originalBatch.Schema, leaveOpen: false).Dispose();
-            Assert.Throws<ObjectDisposedException>(() => stream.Position);
-        }
-
-        [Fact]
-        public void Ctor_LeaveOpenTrue_StreamValidOnDispose()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-            var stream = new MemoryStream();
-            new ArrowStreamWriter(stream, originalBatch.Schema, leaveOpen: true).Dispose();
-            Assert.Equal(0, stream.Position);
-        }
-
-        [Theory]
-        [InlineData(true)]
-        [InlineData(false)]
-        public void CanWriteToNetworkStream(bool createDictionaryArray)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100, createDictionaryArray: createDictionaryArray);
-
-            TcpListener listener = new TcpListener(IPAddress.Loopback, 0);
-            listener.Start();
-            int port = ((IPEndPoint)listener.LocalEndpoint).Port;
-
-            using (TcpClient sender = new TcpClient())
-            {
-                sender.Connect(IPAddress.Loopback, port);
-                NetworkStream stream = sender.GetStream();
-
-                using (var writer = new ArrowStreamWriter(stream, originalBatch.Schema))
-                {
-                    writer.WriteRecordBatch(originalBatch);
-                    writer.WriteEnd();
-
-                    stream.Flush();
-                }
-            }
-
-            using (TcpClient receiver = listener.AcceptTcpClient())
-            {
-                NetworkStream stream = receiver.GetStream();
-                using (var reader = new ArrowStreamReader(stream))
-                {
-                    RecordBatch newBatch = reader.ReadNextRecordBatch();
-                    ArrowReaderVerifier.CompareBatches(originalBatch, newBatch);
-                }
-            }
-        }
-
-        [Theory]
-        [InlineData(true)]
-        [InlineData(false)]
-        public async Task CanWriteToNetworkStreamAsync(bool createDictionaryArray)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100, createDictionaryArray: createDictionaryArray);
-
-            TcpListener listener = new TcpListener(IPAddress.Loopback, 0);
-            listener.Start();
-            int port = ((IPEndPoint)listener.LocalEndpoint).Port;
-
-            using (TcpClient sender = new TcpClient())
-            {
-                sender.Connect(IPAddress.Loopback, port);
-                NetworkStream stream = sender.GetStream();
-
-                using (var writer = new ArrowStreamWriter(stream, originalBatch.Schema))
-                {
-                    await writer.WriteRecordBatchAsync(originalBatch);
-                    await writer.WriteEndAsync();
-
-                    stream.Flush();
-                }
-            }
-
-            using (TcpClient receiver = listener.AcceptTcpClient())
-            {
-                NetworkStream stream = receiver.GetStream();
-                using (var reader = new ArrowStreamReader(stream))
-                {
-                    RecordBatch newBatch = reader.ReadNextRecordBatch();
-                    ArrowReaderVerifier.CompareBatches(originalBatch, newBatch);
-                }
-            }
-        }
-
-        [Theory]
-        [InlineData(true)]
-        [InlineData(false)]
-        public void WriteEmptyBatch(bool createDictionaryArray)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 0, createDictionaryArray: createDictionaryArray);
-
-            TestRoundTripRecordBatch(originalBatch);
-        }
-
-        [Theory]
-        [InlineData(true)]
-        [InlineData(false)]
-        public async Task WriteEmptyBatchAsync(bool createDictionaryArray)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 0, createDictionaryArray: createDictionaryArray);
-
-            await TestRoundTripRecordBatchAsync(originalBatch);
-        }
-
-        [Fact]
-        public void WriteBatchWithNulls()
-        {
-            RecordBatch originalBatch = new RecordBatch.Builder()
-                .Append("Column1", false, col => col.Int32(array => array.AppendRange(Enumerable.Range(0, 10))))
-                .Append("Column2", true, new Int32Array(
-                    valueBuffer: new ArrowBuffer.Builder<int>().AppendRange(Enumerable.Range(0, 10)).Build(),
-                    nullBitmapBuffer: new ArrowBuffer.Builder<byte>().Append(0xfd).Append(0xff).Build(),
-                    length: 10,
-                    nullCount: 2,
-                    offset: 0))
-                .Append("Column3", true, new Int32Array(
-                    valueBuffer: new ArrowBuffer.Builder<int>().AppendRange(Enumerable.Range(0, 10)).Build(),
-                    nullBitmapBuffer: new ArrowBuffer.Builder<byte>().Append(0x00).Append(0x00).Build(),
-                    length: 10,
-                    nullCount: 10,
-                    offset: 0))
-                .Append("NullableBooleanColumn", true, new BooleanArray(
-                    valueBuffer: new ArrowBuffer.Builder<byte>().Append(0xfd).Append(0xff).Build(),
-                    nullBitmapBuffer: new ArrowBuffer.Builder<byte>().Append(0xed).Append(0xff).Build(),
-                    length: 10,
-                    nullCount: 3,
-                    offset: 0))
-                .Append("NullColumn", true, new NullArray(10))
-                .Build();
-
-            TestRoundTripRecordBatch(originalBatch);
-        }
-
-        [Fact]
-        public async Task WriteBatchWithNullsAsync()
-        {
-            RecordBatch originalBatch = new RecordBatch.Builder()
-                .Append("Column1", false, col => col.Int32(array => array.AppendRange(Enumerable.Range(0, 10))))
-                .Append("Column2", true, new Int32Array(
-                    valueBuffer: new ArrowBuffer.Builder<int>().AppendRange(Enumerable.Range(0, 10)).Build(),
-                    nullBitmapBuffer: new ArrowBuffer.Builder<byte>().Append(0xfd).Append(0xff).Build(),
-                    length: 10,
-                    nullCount: 2,
-                    offset: 0))
-                .Append("Column3", true, new Int32Array(
-                    valueBuffer: new ArrowBuffer.Builder<int>().AppendRange(Enumerable.Range(0, 10)).Build(),
-                    nullBitmapBuffer: new ArrowBuffer.Builder<byte>().Append(0x00).Append(0x00).Build(),
-                    length: 10,
-                    nullCount: 10,
-                    offset: 0))
-                .Append("NullableBooleanColumn", true, new BooleanArray(
-                    valueBuffer: new ArrowBuffer.Builder<byte>().Append(0xfd).Append(0xff).Build(),
-                    nullBitmapBuffer: new ArrowBuffer.Builder<byte>().Append(0xed).Append(0xff).Build(),
-                    length: 10,
-                    nullCount: 3,
-                    offset: 0))
-                .Build();
-
-            await TestRoundTripRecordBatchAsync(originalBatch);
-        }
-
-        [Theory]
-        [InlineData(0, 45)]
-        [InlineData(3, 45)]
-        [InlineData(16, 45)]
-        public void WriteSlicedArrays(int sliceOffset, int sliceLength)
-        {
-            var originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-            var slicedArrays = originalBatch.Arrays
-                .Select(array => ArrowArrayFactory.Slice(array, sliceOffset, sliceLength))
-                .ToList();
-            var slicedBatch = new RecordBatch(originalBatch.Schema, slicedArrays, sliceLength);
-
-            TestRoundTripRecordBatch(slicedBatch, strictCompare: false);
-        }
-
-        [Theory]
-        [InlineData(0, 45)]
-        [InlineData(3, 45)]
-        [InlineData(16, 45)]
-        public async Task WriteSlicedArraysAsync(int sliceOffset, int sliceLength)
-        {
-            var originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-            var slicedArrays = originalBatch.Arrays
-                .Select(array => ArrowArrayFactory.Slice(array, sliceOffset, sliceLength))
-                .ToList();
-            var slicedBatch = new RecordBatch(originalBatch.Schema, slicedArrays, sliceLength);
-
-            await TestRoundTripRecordBatchAsync(slicedBatch, strictCompare: false);
-        }
-
-        private static void TestRoundTripRecordBatches(List<RecordBatch> originalBatches, IpcOptions options = null, bool strictCompare = true)
-        {
-            using (MemoryStream stream = new MemoryStream())
-            {
-                using (var writer = new ArrowStreamWriter(stream, originalBatches[0].Schema, leaveOpen: true, options, new TestMemoryAllocator()))
-                {
-                    foreach (RecordBatch originalBatch in originalBatches)
-                    {
-                        writer.WriteRecordBatch(originalBatch);
-                    }
-                    writer.WriteEnd();
-                }
-
-                stream.Position = 0;
-
-                using (var reader = new ArrowStreamReader(stream))
-                {
-                    foreach (RecordBatch originalBatch in originalBatches)
-                    {
-                        RecordBatch newBatch = reader.ReadNextRecordBatch();
-                        ArrowReaderVerifier.CompareBatches(originalBatch, newBatch, strictCompare: strictCompare);
-                    }
-                }
-            }
-        }
-
-        private static async Task TestRoundTripRecordBatchesAsync(List<RecordBatch> originalBatches, IpcOptions options = null, bool strictCompare = true, MemoryAllocator memoryAllocator = null)
-        {
-            using (MemoryStream stream = new MemoryStream())
-            {
-                using (var writer = new ArrowStreamWriter(stream, originalBatches[0].Schema, leaveOpen: true, options, memoryAllocator ??  new TestMemoryAllocator()))
-                {
-                    foreach (RecordBatch originalBatch in originalBatches)
-                    {
-                        await writer.WriteRecordBatchAsync(originalBatch);
-                    }
-                    await writer.WriteEndAsync();
-                }
-
-                stream.Position = 0;
-
-                using (var reader = new ArrowStreamReader(stream))
-                {
-                    foreach (RecordBatch originalBatch in originalBatches)
-                    {
-                        RecordBatch newBatch = reader.ReadNextRecordBatch();
-                        ArrowReaderVerifier.CompareBatches(originalBatch, newBatch, strictCompare: strictCompare);
-                    }
-                }
-            }
-        }
-
-        private static void TestRoundTripRecordBatch(RecordBatch originalBatch, IpcOptions options = null, bool strictCompare = true)
-        {
-            TestRoundTripRecordBatches(new List<RecordBatch> { originalBatch }, options, strictCompare: strictCompare);
-        }
-
-        private static async Task TestRoundTripRecordBatchAsync(RecordBatch originalBatch, IpcOptions options = null, bool strictCompare = true)
-        {
-            await TestRoundTripRecordBatchesAsync(new List<RecordBatch> { originalBatch }, options, strictCompare: strictCompare);
-        }
-
-        [Fact]
-        public void WriteBatchWithCorrectPadding()
-        {
-            byte value1 = 0x04;
-            byte value2 = 0x14;
-            var batch = new RecordBatch(
-                new Schema.Builder()
-                    .Field(f => f.Name("age").DataType(Int32Type.Default))
-                    .Field(f => f.Name("characterCount").DataType(Int32Type.Default))
-                    .Build(),
-                new IArrowArray[]
-                {
-                    new Int32Array(
-                        new ArrowBuffer(new byte[] { value1, value1, 0x00, 0x00 }),
-                        ArrowBuffer.Empty,
-                        length: 1,
-                        nullCount: 0,
-                        offset: 0),
-                    new Int32Array(
-                        new ArrowBuffer(new byte[] { value2, value2, 0x00, 0x00 }),
-                        ArrowBuffer.Empty,
-                        length: 1,
-                        nullCount: 0,
-                        offset: 0)
-                },
-                length: 1);
-
-            TestRoundTripRecordBatch(batch);
-
-            using (MemoryStream stream = new MemoryStream())
-            {
-                using (var writer = new ArrowStreamWriter(stream, batch.Schema, leaveOpen: true))
-                {
-                    writer.WriteRecordBatch(batch);
-                    writer.WriteEnd();
-                }
-
-                byte[] writtenBytes = stream.ToArray();
-
-                // ensure that the data buffers at the end are 8-byte aligned
-                Assert.Equal(value1, writtenBytes[writtenBytes.Length - 24]);
-                Assert.Equal(value1, writtenBytes[writtenBytes.Length - 23]);
-                for (int i = 22; i > 16; i--)
-                {
-                    Assert.Equal(0, writtenBytes[writtenBytes.Length - i]);
-                }
-
-                Assert.Equal(value2, writtenBytes[writtenBytes.Length - 16]);
-                Assert.Equal(value2, writtenBytes[writtenBytes.Length - 15]);
-                for (int i = 14; i > 8; i--)
-                {
-                    Assert.Equal(0, writtenBytes[writtenBytes.Length - i]);
-                }
-
-                // verify the EOS is written correctly
-                for (int i = 8; i > 4; i--)
-                {
-                    Assert.Equal(0xFF, writtenBytes[writtenBytes.Length - i]);
-                }
-                for (int i = 4; i > 0; i--)
-                {
-                    Assert.Equal(0x00, writtenBytes[writtenBytes.Length - i]);
-                }
-            }
-        }
-
-        [Fact]
-        public async Task WriteBatchWithCorrectPaddingAsync()
-        {
-            byte value1 = 0x04;
-            byte value2 = 0x14;
-            var batch = new RecordBatch(
-                new Schema.Builder()
-                    .Field(f => f.Name("age").DataType(Int32Type.Default))
-                    .Field(f => f.Name("characterCount").DataType(Int32Type.Default))
-                    .Build(),
-                new IArrowArray[]
-                {
-                    new Int32Array(
-                        new ArrowBuffer(new byte[] { value1, value1, 0x00, 0x00 }),
-                        ArrowBuffer.Empty,
-                        length: 1,
-                        nullCount: 0,
-                        offset: 0),
-                    new Int32Array(
-                        new ArrowBuffer(new byte[] { value2, value2, 0x00, 0x00 }),
-                        ArrowBuffer.Empty,
-                        length: 1,
-                        nullCount: 0,
-                        offset: 0)
-                },
-                length: 1);
-
-            await TestRoundTripRecordBatchAsync(batch);
-
-            using (MemoryStream stream = new MemoryStream())
-            {
-                using (var writer = new ArrowStreamWriter(stream, batch.Schema, leaveOpen: true))
-                {
-                    await writer.WriteRecordBatchAsync(batch);
-                    await writer.WriteEndAsync();
-                }
-
-                byte[] writtenBytes = stream.ToArray();
-
-                // ensure that the data buffers at the end are 8-byte aligned
-                Assert.Equal(value1, writtenBytes[writtenBytes.Length - 24]);
-                Assert.Equal(value1, writtenBytes[writtenBytes.Length - 23]);
-                for (int i = 22; i > 16; i--)
-                {
-                    Assert.Equal(0, writtenBytes[writtenBytes.Length - i]);
-                }
-
-                Assert.Equal(value2, writtenBytes[writtenBytes.Length - 16]);
-                Assert.Equal(value2, writtenBytes[writtenBytes.Length - 15]);
-                for (int i = 14; i > 8; i--)
-                {
-                    Assert.Equal(0, writtenBytes[writtenBytes.Length - i]);
-                }
-
-                // verify the EOS is written correctly
-                for (int i = 8; i > 4; i--)
-                {
-                    Assert.Equal(0xFF, writtenBytes[writtenBytes.Length - i]);
-                }
-                for (int i = 4; i > 0; i--)
-                {
-                    Assert.Equal(0x00, writtenBytes[writtenBytes.Length - i]);
-                }
-            }
-        }
-
-        [Theory]
-        [InlineData(true)]
-        [InlineData(false)]
-        public void LegacyIpcFormatRoundTrips(bool createDictionaryArray)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100, createDictionaryArray: createDictionaryArray);
-            TestRoundTripRecordBatch(originalBatch, new IpcOptions() { WriteLegacyIpcFormat = true });
-        }
-
-        [Theory]
-        [InlineData(true)]
-        [InlineData(false)]
-        public async Task LegacyIpcFormatRoundTripsAsync(bool createDictionaryArray)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100, createDictionaryArray: createDictionaryArray);
-            await TestRoundTripRecordBatchAsync(originalBatch, new IpcOptions() { WriteLegacyIpcFormat = true });
-        }
-
-        [Theory]
-        [InlineData(true, true)]
-        [InlineData(true, false)]
-        [InlineData(false, true)]
-        [InlineData(false, false)]
-        public void WriteLegacyIpcFormat(bool writeLegacyIpcFormat, bool createDictionaryArray)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100, createDictionaryArray: createDictionaryArray);
-            var options = new IpcOptions() { WriteLegacyIpcFormat = writeLegacyIpcFormat };
-
-            using (MemoryStream stream = new MemoryStream())
-            {
-                using (var writer = new ArrowStreamWriter(stream, originalBatch.Schema, leaveOpen: true, options))
-                {
-                    writer.WriteRecordBatch(originalBatch);
-                    writer.WriteEnd();
-                }
-
-                stream.Position = 0;
-
-                // ensure the continuation is written correctly
-                byte[] buffer = stream.ToArray();
-                int messageLength = BinaryPrimitives.ReadInt32LittleEndian(buffer);
-                int endOfBuffer1 = BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(buffer.Length - 8));
-                int endOfBuffer2 = BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(buffer.Length - 4));
-                if (writeLegacyIpcFormat)
-                {
-                    // the legacy IPC format doesn't have a continuation token at the start
-                    Assert.NotEqual(-1, messageLength);
-                    Assert.NotEqual(-1, endOfBuffer1);
-                }
-                else
-                {
-                    // the latest IPC format has a continuation token at the start
-                    Assert.Equal(-1, messageLength);
-                    Assert.Equal(-1, endOfBuffer1);
-                }
-
-                Assert.Equal(0, endOfBuffer2);
-            }
-        }
-
-        [Theory]
-        [InlineData(true, true)]
-        [InlineData(true, false)]
-        [InlineData(false, true)]
-        [InlineData(false, false)]
-        public async Task WriteLegacyIpcFormatAsync(bool writeLegacyIpcFormat, bool createDictionaryArray)
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 100, createDictionaryArray: createDictionaryArray);
-            var options = new IpcOptions() { WriteLegacyIpcFormat = writeLegacyIpcFormat };
-
-            using (MemoryStream stream = new MemoryStream())
-            {
-                using (var writer = new ArrowStreamWriter(stream, originalBatch.Schema, leaveOpen: true, options))
-                {
-                    await writer.WriteRecordBatchAsync(originalBatch);
-                    await writer.WriteEndAsync();
-                }
-
-                stream.Position = 0;
-
-                // ensure the continuation is written correctly
-                byte[] buffer = stream.ToArray();
-                int messageLength = BinaryPrimitives.ReadInt32LittleEndian(buffer);
-                int endOfBuffer1 = BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(buffer.Length - 8));
-                int endOfBuffer2 = BinaryPrimitives.ReadInt32LittleEndian(buffer.AsSpan(buffer.Length - 4));
-                if (writeLegacyIpcFormat)
-                {
-                    // the legacy IPC format doesn't have a continuation token at the start
-                    Assert.NotEqual(-1, messageLength);
-                    Assert.NotEqual(-1, endOfBuffer1);
-                }
-                else
-                {
-                    // the latest IPC format has a continuation token at the start
-                    Assert.Equal(-1, messageLength);
-                    Assert.Equal(-1, endOfBuffer1);
-                }
-
-                Assert.Equal(0, endOfBuffer2);
-            }
-        }
-
-        [Fact]
-        public void WritesMetadataCorrectly()
-        {
-            Schema.Builder schemaBuilder = new Schema.Builder()
-                .Metadata("index", "1, 2, 3, 4, 5")
-                .Metadata("reverseIndex", "5, 4, 3, 2, 1")
-                .Field(f => f
-                    .Name("IntCol")
-                    .DataType(UInt32Type.Default)
-                    .Metadata("custom1", "false")
-                    .Metadata("custom2", "true"))
-                .Field(f => f
-                    .Name("StringCol")
-                    .DataType(StringType.Default)
-                    .Metadata("custom2", "false")
-                    .Metadata("custom3", "4"))
-                .Field(f => f
-                    .Name("StructCol")
-                    .DataType(new StructType(new[] {
-                        new Field("Inner1", FloatType.Default, nullable: false),
-                        new Field("Inner2", DoubleType.Default, nullable: true, new Dictionary<string, string>() { { "customInner", "1" }, { "customInner2", "3" } })
-                    }))
-                    .Metadata("custom4", "6.4")
-                    .Metadata("custom1", "true"));
-
-            var schema = schemaBuilder.Build();
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(schema, length: 10);
-
-            TestRoundTripRecordBatch(originalBatch);
-        }
-
-        [Fact]
-        public async Task WriteMultipleDictionaryArraysAsync()
-        {
-            List<RecordBatch> originalRecordBatches = CreateMultipleDictionaryArraysTestData();
-            await TestRoundTripRecordBatchesAsync(originalRecordBatches);
-        }
-
-        [Fact]
-        public void WriteMultipleDictionaryArrays()
-        {
-            List<RecordBatch> originalRecordBatches = CreateMultipleDictionaryArraysTestData();
-            Assert.Equal("RecordBatch: 10 columns by 3 rows", originalRecordBatches[0].ToString());
-            Assert.Equal("Schema: Num fields=10, Num metadata=0", originalRecordBatches[0].Schema.ToString());
-            Assert.Equal("Field: Name=dictionaryField_int8, DataType=dictionary, IsNullable=False, Metadata count=0",
-                originalRecordBatches[0].Schema.FieldsLookup["dictionaryField_int8"].Single().ToString());
-            TestRoundTripRecordBatches(originalRecordBatches);
-        }
-
-        private List<RecordBatch> CreateMultipleDictionaryArraysTestData()
-        {
-            var dictionaryData = new List<string> { "a", "b", "c" };
-            int length = dictionaryData.Count;
-
-            var schemaForSimpleCase = new Schema(new List<Field> {
-                new Field("int8", Int8Type.Default, true),
-                new Field("uint8", UInt8Type.Default, true),
-                new Field("int16", Int16Type.Default, true),
-                new Field("uint16", UInt16Type.Default, true),
-                new Field("int32", Int32Type.Default, true),
-                new Field("uint32", UInt32Type.Default, true),
-                new Field("int64", Int64Type.Default, true),
-                new Field("uint64", UInt64Type.Default, true)
-            }, null);
-
-            StringArray dictionary = new StringArray.Builder().AppendRange(dictionaryData).Build();
-            IEnumerable<IArrowArray> indicesArraysForSimpleCase = TestData.CreateArrays(schemaForSimpleCase, length);
-
-            var fields = new List<Field>(capacity: length + 1);
-            var testTargetArrays = new List<IArrowArray>(capacity: length + 1);
-
-            foreach (IArrowArray indices in indicesArraysForSimpleCase)
-            {
-                var dictionaryArray = new DictionaryArray(
-                    new DictionaryType(indices.Data.DataType, StringType.Default, false),
-                    indices, dictionary);
-                testTargetArrays.Add(dictionaryArray);
-                fields.Add(new Field($"dictionaryField_{indices.Data.DataType.Name}", dictionaryArray.Data.DataType, false));
-            }
-
-            (Field dictionaryTypeListArrayField, ListArray dictionaryTypeListArray) = CreateDictionaryTypeListArrayTestData(dictionary);
-
-            fields.Add(dictionaryTypeListArrayField);
-            testTargetArrays.Add(dictionaryTypeListArray);
-
-            (Field listTypeDictionaryArrayField, DictionaryArray listTypeDictionaryArray) = CreateListTypeDictionaryArrayTestData(dictionaryData);
-
-            fields.Add(listTypeDictionaryArrayField);
-            testTargetArrays.Add(listTypeDictionaryArray);
-
-            var schema = new Schema(fields, null);
-
-            return new List<RecordBatch> {
-                new RecordBatch(schema, testTargetArrays, length),
-                new RecordBatch(schema, testTargetArrays, length),
-            };
-        }
-
-        private Tuple<Field, ListArray> CreateDictionaryTypeListArrayTestData(StringArray dictionary)
-        {
-            Int32Array indiceArray = new Int32Array.Builder().AppendRange(Enumerable.Range(0, dictionary.Length)).Build();
-
-            //DictionaryArray has no Builder for now, so creating ListArray directly.
-            var dictionaryType = new DictionaryType(Int32Type.Default, StringType.Default, false);
-            var dictionaryArray = new DictionaryArray(dictionaryType, indiceArray, dictionary);
-
-            var valueOffsetsBufferBuilder = new ArrowBuffer.Builder<int>();
-            var validityBufferBuilder = new ArrowBuffer.BitmapBuilder();
-
-            foreach (int i in Enumerable.Range(0, dictionary.Length + 1))
-            {
-                valueOffsetsBufferBuilder.Append(i);
-                validityBufferBuilder.Append(true);
-            }
-
-            var dictionaryField = new Field("dictionaryField_list", dictionaryType, false);
-            var listType = new ListType(dictionaryField);
-            var listArray = new ListArray(listType, valueOffsetsBufferBuilder.Length - 1, valueOffsetsBufferBuilder.Build(), dictionaryArray, valueOffsetsBufferBuilder.Build());
-
-            return Tuple.Create(new Field($"listField_{listType.ValueDataType.Name}", listType, false), listArray);
-        }
-
-        private Tuple<Field, DictionaryArray> CreateListTypeDictionaryArrayTestData(List<string> dictionaryDataBase)
-        {
-            var listBuilder = new ListArray.Builder(StringType.Default);
-            var valueBuilder = listBuilder.ValueBuilder as StringArray.Builder;
-
-            foreach(string data in dictionaryDataBase) {
-                listBuilder.Append();
-                valueBuilder.Append(data);
-            }
-
-            ListArray dictionary = listBuilder.Build();
-            Int32Array indiceArray = new Int32Array.Builder().AppendRange(Enumerable.Range(0, dictionary.Length)).Build();
-            var dictionaryArrayType = new DictionaryType(Int32Type.Default, dictionary.Data.DataType, false);
-            var dictionaryArray = new DictionaryArray(dictionaryArrayType, indiceArray, dictionary);
-
-            return Tuple.Create(new Field($"dictionaryField_{dictionaryArray.Data.DataType.Name}", dictionaryArrayType, false), dictionaryArray);
-        }
-
-        /// <summary>
-        /// Tests that writing an arrow stream with no RecordBatches produces the correct result.
-        /// </summary>
-        [Fact]
-        public void WritesEmptyFile()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 1);
-
-            var stream = new MemoryStream();
-            var writer = new ArrowStreamWriter(stream, originalBatch.Schema);
-
-            writer.WriteStart();
-            writer.WriteEnd();
-
-            stream.Position = 0;
-
-            var reader = new ArrowStreamReader(stream);
-            RecordBatch readBatch = reader.ReadNextRecordBatch();
-            Assert.Null(readBatch);
-            SchemaComparer.Compare(originalBatch.Schema, reader.Schema);
-        }
-
-        /// <summary>
-        /// Tests that writing an arrow stream with no RecordBatches produces the correct
-        /// result when using WriteStartAsync and WriteEndAsync.
-        /// </summary>
-        [Fact]
-        public async Task WritesEmptyFileAsync()
-        {
-            RecordBatch originalBatch = TestData.CreateSampleRecordBatch(length: 1);
-
-            var stream = new MemoryStream();
-            var writer = new ArrowStreamWriter(stream, originalBatch.Schema);
-
-            await writer.WriteStartAsync();
-            await writer.WriteEndAsync();
-
-            stream.Position = 0;
-
-            var reader = new ArrowStreamReader(stream);
-            RecordBatch readBatch = reader.ReadNextRecordBatch();
-            Assert.Null(readBatch);
-            SchemaComparer.Compare(originalBatch.Schema, reader.Schema);
-        }
-
-
-        [Theory]
-        [InlineData(0, 45)]
-        [InlineData(3, 45)]
-        [InlineData(16, 45)]
-        public async Task MemoryOwnerDisposalSlicedArray(int sliceOffset, int sliceLength)
-        {
-            var originalBatch = TestData.CreateSampleRecordBatch(length: 100);
-            var slicedArrays = originalBatch.Arrays
-                .Select(array => ArrowArrayFactory.Slice(array, sliceOffset, sliceLength))
-                .ToList();
-            var slicedBatch = new RecordBatch(originalBatch.Schema, slicedArrays, sliceLength);
-            var allocator = new TestMemoryAllocator();
-            await TestRoundTripRecordBatchesAsync(new List<RecordBatch> () {slicedBatch}, null, false, allocator);
-            if(sliceOffset % 8 != 0)
-                Assert.True(allocator.Statistics.Allocations > 0);
-            Assert.Equal(0,allocator.Rented);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/BinaryArrayBuilderTests.cs b/csharp/test/Apache.Arrow.Tests/BinaryArrayBuilderTests.cs
deleted file mode 100644
index 447572d..0000000
--- a/csharp/test/Apache.Arrow.Tests/BinaryArrayBuilderTests.cs
+++ /dev/null
@@ -1,490 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Apache.Arrow.Memory;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class BinaryArrayBuilderTests
-    {
-        private static readonly MemoryAllocator _allocator = new NativeMemoryAllocator();
-
-        // Various example byte arrays for use in testing.
-        private static readonly byte[] _exampleNull = null;
-        private static readonly byte[] _exampleEmpty = { };
-        private static readonly byte[] _exampleNonEmpty1 = { 10, 20, 30, 40 };
-        private static readonly byte[] _exampleNonEmpty2 = { 50, 60, 70, 80 };
-        private static readonly byte[] _exampleNonEmpty3 = { 90 };
-
-        // Base set of single bytes that may be used to append to a builder in testing.
-        private static readonly byte[] _singleBytesToAppend = { 0, 123, 127, 255 };
-
-        // Base set of byte arrays that may be used to append to a builder in testing.
-        private static readonly byte[][] _byteArraysToAppend =
-        {
-            _exampleNull,
-            _exampleEmpty,
-            _exampleNonEmpty2,
-            _exampleNonEmpty3,
-        };
-
-        // Base set of multiple byte arrays that may be used to append to a builder in testing.
-        private static readonly byte[][][] _byteArrayArraysToAppend =
-        {
-            new byte[][] { },
-            new[] { _exampleNull },
-            new[] { _exampleEmpty },
-            new[] { _exampleNonEmpty2 },
-            new[] { _exampleNonEmpty2, _exampleNonEmpty3 },
-            new[] { _exampleNonEmpty2, _exampleEmpty, _exampleNull },
-        };
-
-        // Base set of byte arrays that can be used as "initial contents" of any builder under test.
-        private static readonly byte[][][] _initialContentsSet =
-        {
-            new byte[][] { },
-            new[] { _exampleNull },
-            new[] { _exampleEmpty },
-            new[] { _exampleNonEmpty1 },
-            new[] { _exampleNonEmpty1, _exampleNonEmpty3 },
-            new[] { _exampleNonEmpty1, _exampleEmpty, _exampleNull },
-        };
-
-        public class Append
-        {
-            public static IEnumerable<object[]> _appendSingleByteTestData =
-                from initialContents in _initialContentsSet
-                from singleByte in _singleBytesToAppend
-                select new object[] { initialContents, singleByte };
-
-            [Theory]
-            [MemberData(nameof(_appendSingleByteTestData))]
-            public void AppendSingleByte(byte[][] initialContents, byte singleByte)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                int initialLength = builder.Length;
-                int expectedLength = initialLength + 1;
-                var expectedArrayContents = initialContents.Concat(new[] { new[] { singleByte } });
-
-                // Act
-                var actualReturnValue = builder.Append(singleByte);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedLength, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-            }
-
-            [Theory]
-            [MemberData(nameof(_appendSingleByteTestData))]
-            public void AppendSingleByteAfterClear(byte[][] initialContents, byte singleByte)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                builder.Clear();
-                var expectedArrayContents = new[] { new[] { singleByte } };
-
-                // Act
-                var actualReturnValue = builder.Append(singleByte);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(1, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-            }
-
-            public static readonly IEnumerable<object[]> _appendNullTestData =
-                from initialContents in _initialContentsSet
-                select new object[] { initialContents };
-
-            [Theory]
-            [MemberData(nameof(_appendNullTestData))]
-            public void AppendNull(byte[][] initialContents)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                int initialLength = builder.Length;
-                int expectedLength = initialLength + 1;
-                var expectedArrayContents = initialContents.Concat(new byte[][] { null });
-
-                // Act
-                var actualReturnValue = builder.AppendNull();
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedLength, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-            }
-
-            [Theory]
-            [MemberData(nameof(_appendNullTestData))]
-            public void AppendNullAfterClear(byte[][] initialContents)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                builder.Clear();
-                var expectedArrayContents = new byte[][] { null };
-
-                // Act
-                var actualReturnValue = builder.AppendNull();
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(1, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-            }
-
-            public static readonly IEnumerable<object[]> _appendNonNullByteArrayTestData =
-                from initialContents in _initialContentsSet
-                from bytes in _byteArraysToAppend
-                where bytes != null
-                select new object[] { initialContents, bytes };
-
-            [Theory]
-            [MemberData(nameof(_appendNonNullByteArrayTestData))]
-            public void AppendReadOnlySpan(byte[][] initialContents, byte[] bytes)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                int initialLength = builder.Length;
-                var span = (ReadOnlySpan<byte>)bytes;
-                int expectedLength = initialLength + 1;
-                var expectedArrayContents = initialContents.Concat(new[] { bytes });
-
-                // Act
-                var actualReturnValue = builder.Append(span);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedLength, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-            }
-
-            [Theory]
-            [MemberData(nameof(_appendNonNullByteArrayTestData))]
-            public void AppendReadOnlySpanAfterClear(byte[][] initialContents, byte[] bytes)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                builder.Clear();
-                var span = (ReadOnlySpan<byte>)bytes;
-                var expectedArrayContents = new[] { bytes };
-
-                // Act
-                var actualReturnValue = builder.Append(span);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(1, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-            }
-
-            public static readonly IEnumerable<object[]> _appendByteArrayTestData =
-                from initialContents in _initialContentsSet
-                from bytes in _byteArraysToAppend
-                select new object[] { initialContents, bytes };
-
-            [Theory]
-            [MemberData(nameof(_appendByteArrayTestData))]
-            public void AppendEnumerable(byte[][] initialContents, byte[] bytes)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                int initialLength = builder.Length;
-                int expectedLength = initialLength + 1;
-                var enumerable = (IEnumerable<byte>)bytes;
-                var expectedArrayContents = initialContents.Concat(new[] { bytes });
-
-                // Act
-                var actualReturnValue = builder.Append(enumerable);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedLength, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-            }
-
-            [Theory]
-            [MemberData(nameof(_appendByteArrayTestData))]
-            public void AppendEnumerableAfterClear(byte[][] initialContents, byte[] bytes)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                builder.Clear();
-                var enumerable = (IEnumerable<byte>)bytes;
-                var expectedArrayContents = new[] { bytes };
-
-                // Act
-                var actualReturnValue = builder.Append(enumerable);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(1, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-            }
-        }
-
-        public class AppendRange
-        {
-            public static readonly IEnumerable<object[]> _appendRangeSingleBytesTestData =
-                from initialContents in _initialContentsSet
-                select new object[] { initialContents, _singleBytesToAppend };
-
-            [Theory]
-            [MemberData(nameof(_appendRangeSingleBytesTestData))]
-            public void AppendRangeSingleBytes(byte[][] initialContents, byte[] singleBytes)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                int initialLength = builder.Length;
-                int expectedNewLength = initialLength + singleBytes.Length;
-                var expectedArrayContents = initialContents.Concat(singleBytes.Select(b => new[] { b }));
-
-                // Act
-                var actualReturnValue = builder.AppendRange(singleBytes);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedNewLength, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-
-            }
-
-            [Theory]
-            [MemberData(nameof(_appendRangeSingleBytesTestData))]
-            public void AppendRangeSingleBytesAfterClear(byte[][] initialContents, byte[] singleBytes)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                builder.Clear();
-                var expectedArrayContents = singleBytes.Select(b => new[] { b });
-
-                // Act
-                var actualReturnValue = builder.AppendRange(singleBytes);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(singleBytes.Length, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-            }
-
-            public static readonly IEnumerable<object[]> _appendRangeByteArraysTestData =
-                from initialContents in _initialContentsSet
-                from byteArrays in _byteArrayArraysToAppend
-                select new object[] { initialContents, byteArrays };
-
-            [Theory]
-            [MemberData(nameof(_appendRangeByteArraysTestData))]
-            public void AppendRangeArrays(byte[][] initialContents, byte[][] byteArrays)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                int initialLength = builder.Length;
-                int expectedNewLength = initialLength + byteArrays.Length;
-                var expectedArrayContents = initialContents.Concat(byteArrays);
-
-                // Act
-                var actualReturnValue = builder.AppendRange(byteArrays);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(expectedNewLength, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-            }
-
-            [Theory]
-            [MemberData(nameof(_appendRangeByteArraysTestData))]
-            public void AppendRangeArraysAfterClear(byte[][] initialContents, byte[][] byteArrays)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                if (initialContents.Length > 0)
-                    builder.AppendRange(initialContents);
-                builder.Clear();
-                var expectedArrayContents = byteArrays;
-
-                // Act
-                var actualReturnValue = builder.AppendRange(byteArrays);
-
-                // Assert
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(byteArrays.Length, builder.Length);
-                var actualArray = builder.Build(_allocator);
-                AssertArrayContents(expectedArrayContents, actualArray);
-            }
-        }
-
-        public class Clear
-        {
-            [Fact]
-            public void ClearEmpty()
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-
-                // Act
-                var actualReturnValue = builder.Clear();
-
-                // Assert
-                Assert.NotNull(actualReturnValue);
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(0, builder.Length);
-                var array = builder.Build(_allocator);
-                Assert.Equal(0, array.Length);
-            }
-
-            public static readonly IEnumerable<object[]> _testData =
-                from byteArrays in _byteArrayArraysToAppend
-                select new object[] { byteArrays };
-
-            [Theory]
-            [MemberData(nameof(_testData))]
-            public void ClearNonEmpty(byte[][] byteArrays)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                builder.AppendRange(byteArrays);
-
-                // Act
-                var actualReturnValue = builder.Clear();
-
-                // Assert
-                Assert.NotNull(actualReturnValue);
-                Assert.Equal(builder, actualReturnValue);
-                Assert.Equal(0, builder.Length);
-                var array = builder.Build(_allocator);
-                Assert.Equal(0, array.Length);
-            }
-        }
-
-        public class Build
-        {
-            [Fact]
-            public void BuildImmediately()
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-
-                // Act
-                var array = builder.Build(_allocator);
-
-                // Assert
-                Assert.Equal(0, array.Length);
-            }
-
-            public static readonly IEnumerable<object[]> _testData =
-                from ba1 in _initialContentsSet
-                from ba2 in _byteArrayArraysToAppend
-                select new object[] { ba1.Concat(ba2) };
-
-            [Theory]
-            [MemberData(nameof(_testData))]
-            public void AppendThenBuild(byte[][] byteArrays)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                foreach (var byteArray in byteArrays)
-                {
-                    // Test the type of byte array to ensure each Append() overload is exercised.
-                    if (byteArray == null)
-                    {
-                        builder.AppendNull();
-                    }
-                    else if (byteArray.Length == 1)
-                    {
-                        builder.Append(byteArray[0]);
-                    }
-                    else
-                    {
-                        builder.Append((ReadOnlySpan<byte>)byteArray);
-                    }
-                }
-
-                // Act
-                var array = builder.Build(_allocator);
-
-                // Assert
-                AssertArrayContents(byteArrays, array);
-            }
-
-            [Theory]
-            [MemberData(nameof(_testData))]
-            public void BuildMultipleTimes(byte[][] byteArrays)
-            {
-                // Arrange
-                var builder = new BinaryArray.Builder();
-                builder.AppendRange(byteArrays);
-                builder.Build(_allocator);
-
-                // Act
-                var array = builder.Build(_allocator);
-
-                // Assert
-                AssertArrayContents(byteArrays, array);
-            }
-        }
-
-        private static void AssertArrayContents(IEnumerable<byte[]> expectedContents, BinaryArray array)
-        {
-            var expectedContentsArr = expectedContents.ToArray();
-            Assert.Equal(expectedContentsArr.Length, array.Length);
-            for (int i = 0; i < array.Length; i++)
-            {
-                var expectedArray = expectedContentsArr[i];
-                var actualSpan = array.GetBytes(i, out bool isNull);
-                var actualArray = isNull ? null : actualSpan.ToArray();
-                Assert.Equal(expectedArray, actualArray);
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/BinaryViewArrayTests.cs b/csharp/test/Apache.Arrow.Tests/BinaryViewArrayTests.cs
deleted file mode 100644
index 7c18a49..0000000
--- a/csharp/test/Apache.Arrow.Tests/BinaryViewArrayTests.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Xunit;
-
-namespace Apache.Arrow.Tests;
-
-public class BinaryViewArrayTests
-{
-    [Fact]
-    public void SliceBinaryViewArray()
-    {
-        var array = new BinaryViewArray.Builder()
-            .Append(new byte[] { 0, 1, 2 })
-            .Append(new byte[] { 3, 4 })
-            .AppendNull()
-            .Append(new byte[] { 5, 6 })
-            .Append(new byte[] { 7, 8 })
-            .Build();
-
-        var slice = (BinaryViewArray)array.Slice(1, 3);
-
-        Assert.Equal(3, slice.Length);
-        Assert.Equal(new byte[] {3, 4}, slice.GetBytes(0).ToArray());
-        Assert.True(slice.GetBytes(1).IsEmpty);
-        Assert.Equal(new byte[] {5, 6}, slice.GetBytes(2).ToArray());
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/BinaryViewTests.cs b/csharp/test/Apache.Arrow.Tests/BinaryViewTests.cs
deleted file mode 100644
index eb617b4..0000000
--- a/csharp/test/Apache.Arrow.Tests/BinaryViewTests.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Scalars;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class BinaryViewTests
-    {
-        private static readonly byte[] empty = new byte[0];
-        private static readonly byte[] oneByte = new byte[1];
-        private static readonly byte[] fourBytes = new byte[] { 1, 2, 3, 4 };
-        private static readonly byte[] fiveBytes = new byte[] { 5, 4, 3, 2, 1 };
-        private static readonly byte[] twelveBytes = new byte[] { 1, 2, 3, 4, 8, 7, 6, 5, 9, 10, 11, 12 };
-        private static readonly byte[] thirteenBytes = new byte[13];
-
-        [Fact]
-        public void Equality()
-        {
-            BinaryView one = new BinaryView(oneByte);
-            BinaryView four = new BinaryView(fourBytes);
-            BinaryView twelve = new BinaryView(twelveBytes);
-            BinaryView twelvePlus = new BinaryView(13, fourBytes, 0, 0);
-            Assert.Equal(one, one);
-            Assert.NotEqual(one, four);
-            Assert.NotEqual(four, twelve);
-            Assert.NotEqual(four, twelvePlus);
-        }
-
-        [Fact]
-        public void ConstructorThrows()
-        {
-            Assert.Throws<ArgumentException>(() => new BinaryView(thirteenBytes));
-            Assert.Throws<ArgumentException>(() => new BinaryView(20, empty, 0, 0));
-            Assert.Throws<ArgumentException>(() => new BinaryView(20, fiveBytes, 0, 0));
-            Assert.Throws<ArgumentException>(() => new BinaryView(13, thirteenBytes, 0, 0));
-            Assert.Throws<ArgumentException>(() => new BinaryView(4, fourBytes, 0, 0));
-        }
-
-        [Fact]
-        public void ConstructInline()
-        {
-            BinaryView zero = new BinaryView(empty);
-            Assert.Equal(-1, zero.BufferIndex);
-            Assert.Equal(-1, zero.BufferOffset);
-            Assert.Equal(0, zero.Length);
-            Assert.Equal(0, zero.Bytes.Length);
-
-            BinaryView one = new BinaryView(oneByte);
-            Assert.Equal(-1, one.BufferIndex);
-            Assert.Equal(-1, one.BufferOffset);
-            Assert.Equal(1, one.Length);
-            Assert.Equal(1, one.Bytes.Length);
-            Assert.Equal((byte)0, one.Bytes[0]);
-
-            BinaryView twelve = new BinaryView(twelveBytes);
-            Assert.Equal(-1, one.BufferIndex);
-            Assert.Equal(-1, one.BufferOffset);
-            Assert.Equal(12, twelve.Length);
-            Assert.Equal(12, twelve.Bytes.Length);
-            Assert.Equal((byte)8, twelve.Bytes[4]);
-        }
-
-        [Fact]
-        public void ConstructPrefix()
-        {
-            BinaryView four = new BinaryView(14, fourBytes, 2, 3);
-            Assert.Equal(2, four.BufferIndex);
-            Assert.Equal(3, four.BufferOffset);
-            Assert.Equal(14, four.Length);
-            Assert.Equal(4, four.Bytes.Length);
-            Assert.Equal((byte)2, four.Bytes[1]);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/BitUtilityTests.cs b/csharp/test/Apache.Arrow.Tests/BitUtilityTests.cs
deleted file mode 100644
index 528dca1..0000000
--- a/csharp/test/Apache.Arrow.Tests/BitUtilityTests.cs
+++ /dev/null
@@ -1,267 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class BitUtilityTests
-    {
-        public class ByteCount
-        {
-            [Theory]
-            [InlineData(0, 0)]
-            [InlineData(1, 1)]
-            [InlineData(8, 1)]
-            [InlineData(9, 2)]
-            [InlineData(32, 4)]
-            public void HasExpectedResult(int n, int expected)
-            {
-                var count = BitUtility.ByteCount(n);
-                Assert.Equal(expected, count);
-            }
-        }
-
-        public class CountBits
-        {
-            [Theory]
-            [InlineData(new byte[] { 0b00000000 }, 0)]
-            [InlineData(new byte[] { 0b00000001 }, 1)]
-            [InlineData(new byte[] { 0b11111111 }, 8)]
-            [InlineData(new byte[] { 0b01001001, 0b01010010 }, 6)]
-            public void CountsAllOneBits(byte[] data, int expectedCount)
-            {
-                Assert.Equal(expectedCount,
-                    BitUtility.CountBits(data));
-            }
-
-            [Theory]
-            [InlineData(new byte[] { 0b11111111 }, 0, 8)]
-            [InlineData(new byte[] { 0b11111111 }, 3, 5)]
-            [InlineData(new byte[] { 0b11111111, 0b11111111 }, 9, 7)]
-            [InlineData(new byte[] { 0b11111111 }, -1, 0)]
-            public void CountsAllOneBitsFromAnOffset(byte[] data, int offset, int expectedCount)
-            {
-                Assert.Equal(expectedCount,
-                    BitUtility.CountBits(data, offset));
-            }
-                        
-            [Theory]
-            [InlineData(new byte[] { 0b11111111 }, 0, 8, 8)]
-            [InlineData(new byte[] { 0b11111111 }, 0, 4, 4)]
-            [InlineData(new byte[] { 0b11111111 }, 3, 2, 2)]
-            [InlineData(new byte[] { 0b11111111 }, 3, 5, 5)]
-            [InlineData(new byte[] { 0b11111111, 0b11111111 }, 9, 7, 7)]
-            [InlineData(new byte[] { 0b11111111, 0b11111111 }, 7, 2, 2)]
-            [InlineData(new byte[] { 0b11111111, 0b11111111, 0b11111111 }, 0, 24, 24)]
-            [InlineData(new byte[] { 0b11111111, 0b11111111, 0b11111111 }, 8, 16, 16)]
-            [InlineData(new byte[] { 0b11111111, 0b11111111, 0b11111111 }, 0, 16, 16)]
-            [InlineData(new byte[] { 0b11111111, 0b11111111, 0b11111111 }, 3, 18, 18)]
-            [InlineData(new byte[] { 0b11111111 }, -1, 0, 0)]
-            public void CountsAllOneBitsFromOffsetWithinLength(byte[] data, int offset, int length, int expectedCount)
-            {
-                var actualCount = BitUtility.CountBits(data, offset, length);
-                Assert.Equal(expectedCount, actualCount);
-            }
-
-            [Fact]
-            public void CountsZeroBitsWhenDataIsEmpty()
-            {
-                Assert.Equal(0,
-                    BitUtility.CountBits(null));
-            }
-        }
-
-        public class GetBit
-        {
-            [Theory]
-            [InlineData(new byte[] { 0b01001001 }, 0, true)]
-            [InlineData(new byte[] { 0b01001001 }, 1, false)]
-            [InlineData(new byte[] { 0b01001001 }, 2, false)]
-            [InlineData(new byte[] { 0b01001001 }, 3, true)]
-            [InlineData(new byte[] { 0b01001001 }, 4, false)]
-            [InlineData(new byte[] { 0b01001001 }, 5, false)]
-            [InlineData(new byte[] { 0b01001001 }, 6, true)]
-            [InlineData(new byte[] { 0b01001001 }, 7, false)]
-            [InlineData(new byte[] { 0b01001001, 0b01010010 }, 8, false)]
-            [InlineData(new byte[] { 0b01001001, 0b01010010 }, 14, true)]
-            public void GetsCorrectBitForIndex(byte[] data, int index, bool expectedValue)
-            {
-                Assert.Equal(expectedValue,
-                    BitUtility.GetBit(data, index));
-            }
-
-            [Theory]
-            [InlineData(null, 0)]
-            [InlineData(new byte[] { 0b00000000 }, -1)]
-            public void ThrowsWhenBitIndexOutOfRange(byte[] data, int index)
-            {
-                Assert.Throws<IndexOutOfRangeException>(() =>
-                    BitUtility.GetBit(data, index));
-            }
-        }
-
-        public class SetBit
-        {
-            [Theory]
-            [InlineData(new byte[] { 0b00000000 }, 0, new byte[] { 0b00000001 })]
-            [InlineData(new byte[] { 0b00000000 }, 2, new byte[] { 0b00000100 })]
-            [InlineData(new byte[] { 0b00000000 }, 7, new byte[] { 0b10000000 })]
-            [InlineData(new byte[] { 0b00000000, 0b00000000 }, 8, new byte[] { 0b00000000, 0b00000001 })]
-            [InlineData(new byte[] { 0b00000000, 0b00000000 }, 15, new byte[] { 0b00000000, 0b10000000 })]
-            public void SetsBitAtIndex(byte[] data, int index, byte[] expectedValue)
-            {
-                BitUtility.SetBit(data, index);
-                Assert.Equal(expectedValue, data);
-            }
-
-            [Theory]
-            [InlineData(new byte[] { 0b10000000 }, 0, true, new byte[] { 0b10000001 })]
-            [InlineData(new byte[] { 0b00000000 }, 2, true, new byte[] { 0b00000100 })]
-            [InlineData(new byte[] { 0b11111111 }, 2, false, new byte[] { 0b11111011 })]
-            [InlineData(new byte[] { 0b01111111 }, 7, true, new byte[] { 0b11111111 })]
-            [InlineData(new byte[] { 0b00000000, 0b00000000 }, 8, true, new byte[] { 0b00000000, 0b00000001 })]
-            [InlineData(new byte[] { 0b11111110, 0b11111110 }, 15, false, new byte[] { 0b11111110, 0b01111110 })]
-            public void SetsBitValueAtIndex(byte[] data, int index, bool value, byte[] expectedValue)
-            {
-                BitUtility.SetBit(data, index, value);
-                Assert.Equal(expectedValue, data);
-            }
-        }
-
-        public class SetBits
-        {
-            [Theory]
-            [InlineData(new byte[] { 0b00000000 }, 0, 0, true, new byte[] { 0b00000000 })]
-            [InlineData(new byte[] { 0b00000000 }, 0, 1, true, new byte[] { 0b00000001 })]
-            [InlineData(new byte[] { 0b00000000 }, 0, 8, true, new byte[] { 0b11111111 })]
-            [InlineData(new byte[] { 0b00000000 }, 2, 2, true, new byte[] { 0b00001100 })]
-            [InlineData(new byte[] { 0b00000000 }, 5, 3, true, new byte[] { 0b11100000 })]
-            [InlineData(new byte[] { 0b00000000, 0b00000000 }, 8, 1, true, new byte[] { 0b00000000, 0b00000001 })]
-            [InlineData(new byte[] { 0b00000000, 0b00000000 }, 15, 1, true, new byte[] { 0b00000000, 0b10000000 })]
-            [InlineData(new byte[] { 0b00000000, 0b00000000 }, 7, 2, true, new byte[] { 0b10000000, 0b00000001 })]
-            [InlineData(new byte[] { 0b11111111, 0b11111111 }, 7, 2, false, new byte[] { 0b01111111, 0b11111110 })]
-            public void SetsBitsInRangeOnSmallRanges(byte[] data, int index, int length, bool value, byte[] expectedValue)
-            {
-                BitUtility.SetBits(data, index, length, value);
-                Assert.Equal(expectedValue, data);
-            }
-                        
-            [Fact]
-            public void SetsBitsInRangeOnBigRanges()
-            {
-                //Arrange
-                //Allocate 64 bits
-                Span<byte> data = stackalloc byte[8];
-                data.Clear();
-
-                //Act
-                //Sets 56 bits in the middle
-                BitUtility.SetBits(data, 4, 56, true);
-
-                //Assert
-                //Check that 4 bits in the lower and upper boundaries are left untouched
-                Assert.Equal(0b11110000, data[0]);
-                Assert.Equal(0b00001111, data[7]);
-
-                //Check bits in the middle
-                for (int i = 1; i < 7; i++)
-                    Assert.Equal(0b11111111, data[i]);
-            }
-
-            [Fact]
-            public void SetsBitsInRangeOnBigRanges_LowerBoundaryCornerCase()
-            {
-                //Arrange
-                //Allocate 64 bits
-                Span<byte> data = stackalloc byte[8];
-                data.Clear();
-
-                //Act
-                //Sets all bits starting from 1
-                BitUtility.SetBits(data, 1, 63, true);
-
-                //Assert
-                //Check lower boundary
-                Assert.Equal(0b11111110, data[0]);
-
-                //Check other bits
-                for (int i = 1; i < 8; i++)
-                    Assert.Equal(0b11111111, data[i]);
-            }
-
-            [Fact]
-            public void SetsBitsInRangeOnBigRanges_UpperBoundaryCornerCase()
-            {
-                //Arrange
-                //Allocate 64 bits
-                Span<byte> data = stackalloc byte[8];
-                data.Clear();
-
-                //Act
-                //Sets all bits starting from 0
-                BitUtility.SetBits(data, 0, 63, true);
-
-                //Assert
-                //Check upper boundary
-                Assert.Equal(0b01111111, data[7]);
-
-                //Check other bits
-                for (int i = 0; i < 7; i++)
-                    Assert.Equal(0b11111111, data[i]);
-            }
-        }
-
-        public class ClearBit
-        {
-            [Theory]
-            [InlineData(new byte[] { 0b00000001 }, 0, new byte[] { 0b00000000 })]
-            [InlineData(new byte[] { 0b00000010 }, 1, new byte[] { 0b00000000 })]
-            [InlineData(new byte[] { 0b10000001 }, 7, new byte[] { 0b00000001 })]
-            [InlineData(new byte[] { 0b11111111, 0b11111111 }, 15, new byte[] { 0b11111111, 0b01111111 })]
-            public void ClearsBitAtIndex(byte[] data, int index, byte[] expectedValue)
-            {
-                BitUtility.ClearBit(data, index);
-                Assert.Equal(expectedValue, data);
-            }
-        }
-
-        public class RoundUpToMultipleOf64
-        {
-            [Theory]
-            [InlineData(0, 0)]
-            [InlineData(1, 64)]
-            [InlineData(63, 64)]
-            [InlineData(64, 64)]
-            [InlineData(65, 128)]
-            [InlineData(129, 192)]
-            public void ReturnsNextMultiple(int size, int expectedSize)
-            {
-                Assert.Equal(expectedSize,
-                    BitUtility.RoundUpToMultipleOf64(size));
-            }
-
-            [Theory]
-            [InlineData(0)]
-            [InlineData(-1)]
-            public void ReturnsZeroWhenSizeIsLessThanOrEqualToZero(int size)
-            {
-                Assert.Equal(0,
-                    BitUtility.RoundUpToMultipleOf64(size));
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/BooleanArrayTests.cs b/csharp/test/Apache.Arrow.Tests/BooleanArrayTests.cs
deleted file mode 100644
index efac07d..0000000
--- a/csharp/test/Apache.Arrow.Tests/BooleanArrayTests.cs
+++ /dev/null
@@ -1,222 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Linq;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class BooleanArrayTests
-    {
-        public class Builder
-        {
-            public class Append
-            {
-                [Theory]
-                [InlineData(1)]
-                [InlineData(3)]
-                public void IncrementsLength(int count)
-                {
-                    var builder = new BooleanArray.Builder();
-
-                    for (var i = 0; i < count; i++)
-                    {
-                        builder.Append(true);
-                    }
-
-                    var array = builder.Build();
-
-                    Assert.Equal(count, array.Length);
-                }
-
-                [Fact]
-                public void AppendsExpectedBit()
-                {
-                    var array1 = new BooleanArray.Builder()
-                        .Append(false)
-                        .Build();
-
-                    Assert.False(array1.GetValue(0).Value);
-
-                    var array2 = new BooleanArray.Builder()
-                        .Append(true)
-                        .Build();
-
-                    Assert.True(array2.GetValue(0).Value);
-                }
-            }
-
-            public class Clear
-            {
-                [Fact]
-                public void SetsAllBitsToDefault()
-                {
-                    var array = new BooleanArray.Builder()
-                        .Resize(8)
-                        .Set(0, true)
-                        .Set(7, true)
-                        .Clear()
-                        .Build();
-
-                    for (var i = 0; i < array.Length; i++)
-                    {
-                        Assert.False(array.GetValue(i).Value);
-                    }
-                }
-            }
-
-            public class Toggle
-            {
-                [Theory]
-                [InlineData(8, 1)]
-                [InlineData(16, 13)]
-                public void TogglesExpectedBitToFalse(int length, int index)
-                {
-                    var array = new BooleanArray.Builder()
-                        .Resize(length)
-                        .Set(index, true)
-                        .Toggle(index)
-                        .Build();
-
-                    Assert.False(array.GetValue(index).Value);
-                }
-
-                [Theory]
-                [InlineData(8, 1)]
-                [InlineData(16, 13)]
-                public void TogglesExpectedBitToTreu(int length, int index)
-                {
-                    var array = new BooleanArray.Builder()
-                        .Resize(length)
-                        .Set(index, false)
-                        .Toggle(index)
-                        .Build();
-
-                    Assert.True(array.GetValue(index).Value);
-                }
-
-                [Fact]
-                public void ThrowsWhenIndexOutOfRange()
-                {
-                    Assert.Throws<ArgumentOutOfRangeException>(() =>
-                    {
-                        var builder = new BooleanArray.Builder();
-                        builder.Toggle(8);
-                    });
-                }
-            }
-
-            public class Swap
-            {
-                [Fact]
-                public void SwapsExpectedBits()
-                {
-                    var array = new BooleanArray.Builder()
-                        .AppendRange(Enumerable.Repeat(false, 8))
-                        .Set(0, true)
-                        .Swap(0, 7)
-                        .Build();
-
-                    Assert.True(array.GetValue(0).HasValue);
-                    Assert.False(array.GetValue(0).Value);
-                    Assert.True(array.GetValue(7).HasValue);
-                    Assert.True(array.GetValue(7).Value);
-                    #pragma warning disable CS0618
-                    Assert.False(array.GetBoolean(0));
-                    Assert.True(array.GetBoolean(7));
-                    #pragma warning restore CS0618
-                }
-
-                [Fact]
-                public void ThrowsWhenIndexOutOfRange()
-                {
-                    Assert.Throws<ArgumentOutOfRangeException>(() =>
-                    {
-                        var builder = new BooleanArray.Builder();
-                        builder.Swap(0, 1);
-                    });
-                }
-            }
-
-            public class Set
-            {
-                [Theory]
-                [InlineData(8, 0)]
-                [InlineData(8, 4)]
-                [InlineData(8, 7)]
-                [InlineData(16, 8)]
-                [InlineData(16, 15)]
-                public void SetsExpectedBitToTrue(int length, int index)
-                {
-                    var array = new BooleanArray.Builder()
-                        .Resize(length)
-                        .Set(index, true)
-                        .Build();
-
-                    Assert.True(array.GetValue(index).Value);
-                }
-
-                [Theory]
-                [InlineData(8, 0)]
-                [InlineData(8, 4)]
-                [InlineData(8, 7)]
-                [InlineData(16, 8)]
-                [InlineData(16, 15)]
-                public void SetsExpectedBitsToFalse(int length, int index)
-                {
-                    var array = new BooleanArray.Builder()
-                        .Resize(length)
-                        .Set(index, false)
-                        .Build();
-
-                    Assert.False(array.GetValue(index).Value);
-                }
-
-                [Theory]
-                [InlineData(4)]
-                public void UnsetBitsAreUnchanged(int index)
-                {
-                    var array = new BooleanArray.Builder()
-                        .AppendRange(Enumerable.Repeat(false, 8))
-                        .Set(index, true)
-                        .Build();
-
-                    for (var i = 0; i < 8; i++)
-                    {
-                        if (i != index)
-                        {
-                            Assert.True(array.GetValue(i).HasValue);
-                            Assert.False(array.GetValue(i).Value);
-                            #pragma warning disable CS0618
-                            Assert.False(array.GetBoolean(i));
-                            #pragma warning restore CS0618
-                        }
-                    }
-                }
-
-                [Fact]
-                public void ThrowsWhenIndexOutOfRange()
-                {
-                    Assert.Throws<ArgumentOutOfRangeException>(() =>
-                    {
-                        var builder = new BooleanArray.Builder();
-                        builder.Set(builder.Length, false);
-                    });
-                }
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/CDataInterfaceDataTests.cs b/csharp/test/Apache.Arrow.Tests/CDataInterfaceDataTests.cs
deleted file mode 100644
index 3081160..0000000
--- a/csharp/test/Apache.Arrow.Tests/CDataInterfaceDataTests.cs
+++ /dev/null
@@ -1,143 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Runtime.InteropServices;
-using Apache.Arrow.C;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class CDataInterfaceDataTests
-    {
-        private IArrowArray GetTestArray()
-        {
-            var builder = new StringArray.Builder();
-            builder.Append("hello");
-            builder.Append("world");
-            builder.AppendNull();
-            builder.Append("foo");
-            builder.Append("bar");
-            return builder.Build();
-        }
-
-        [Fact]
-        public unsafe void InitializeArrayZeroed()
-        {
-            CArrowArray* cArray = CArrowArray.Create();
-
-            Assert.Equal(0, cArray->length);
-            Assert.Equal(0, cArray->null_count);
-            Assert.Equal(0, cArray->offset);
-            Assert.Equal(0, cArray->n_buffers);
-            Assert.Equal(0, cArray->n_children);
-            Assert.True(cArray->buffers == null);
-            Assert.True(cArray->children == null);
-            Assert.True(cArray->dictionary == null);
-            Assert.True(cArray->release == default);
-            Assert.True(cArray->private_data == null);
-
-            CArrowArray.Free(cArray);
-        }
-
-        [Fact]
-        public unsafe void CallsReleaseForValid()
-        {
-            IArrowArray array = GetTestArray();
-            CArrowArray* cArray = CArrowArray.Create();
-            CArrowArrayExporter.ExportArray(array, cArray);
-            Assert.False(cArray->release == default);
-            CArrowArrayImporter.ImportArray(cArray, array.Data.DataType).Dispose();
-            Assert.True(cArray->release == default);
-            CArrowArray.Free(cArray);
-        }
-
-#if NET5_0_OR_GREATER
-        [Fact]
-        public unsafe void CallsReleaseForInvalid()
-        {
-            // Make sure we call release callback, even if the imported array is invalid.
-            CArrowArray* cArray = CArrowArray.Create();
-
-            bool wasCalled = false;
-            var releaseCallback = (CArrowArray* cArray) =>
-            {
-                wasCalled = true;
-                cArray->release = default;
-            };
-            cArray->release = (delegate* unmanaged<CArrowArray*, void>)Marshal.GetFunctionPointerForDelegate(
-                releaseCallback);
-
-            Assert.Throws<InvalidOperationException>(() =>
-            {
-                CArrowArrayImporter.ImportArray(cArray, GetTestArray().Data.DataType);
-            });
-            Assert.True(wasCalled);
-
-            CArrowArray.Free(cArray);
-
-            GC.KeepAlive(releaseCallback);
-        }
-#endif
-
-        [Fact]
-        public unsafe void RoundTripInt32ArrayWithOffset()
-        {
-            Int32Array array = new Int32Array.Builder()
-                .AppendRange(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 })
-                .Build();
-            IArrowArray sliced = array.Slice(2, 6);
-            CArrowArray* cArray = CArrowArray.Create();
-            CArrowArrayExporter.ExportArray(sliced, cArray);
-            using (var importedSlice = (Int32Array)CArrowArrayImporter.ImportArray(cArray, array.Data.DataType))
-            {
-                Assert.Equal(6, importedSlice.Length);
-                Assert.Equal(2, importedSlice.Offset);
-                Assert.Equal(2, importedSlice.GetValue(0));
-            }
-            CArrowArray.Free(cArray);
-        }
-
-        [Fact]
-        public unsafe void ExportRecordBatch_LargerThan2GB_Succeeds()
-        {
-            RecordBatch GetTestRecordBatch()
-            {
-                const int rows = 50_000;
-                var doubles = new double[rows];
-                for (var i = 0; i < rows; ++i)
-                {
-                    doubles[i] = i * 1.1;
-                }
-
-                var batchBuilder = new RecordBatch.Builder();
-                for (var i = 0; i < 10_000; i++)
-                {
-                    batchBuilder.Append($"doubles{i}", true, ab => ab.Double(b => b.Append(doubles)));
-                }
-
-                return batchBuilder.Build();
-            }
-
-            RecordBatch batch = GetTestRecordBatch();
-
-            CArrowArray* cArray = CArrowArray.Create();
-            CArrowArrayExporter.ExportRecordBatch(batch, cArray);
-
-            CArrowArray.Free(cArray);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/CDataInterfacePythonTests.cs b/csharp/test/Apache.Arrow.Tests/CDataInterfacePythonTests.cs
deleted file mode 100644
index 0ef8eba..0000000
--- a/csharp/test/Apache.Arrow.Tests/CDataInterfacePythonTests.cs
+++ /dev/null
@@ -1,990 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Apache.Arrow.C;
-using Apache.Arrow.Ipc;
-using Apache.Arrow.Scalars;
-using Apache.Arrow.Types;
-using Python.Runtime;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class CDataSchemaPythonTest : IClassFixture<CDataSchemaPythonTest.PythonNet>
-    {
-        public class PythonNet : IDisposable
-        {
-            public bool Initialized { get; }
-
-            public PythonNet()
-            {
-                bool pythonSet = Environment.GetEnvironmentVariable("PYTHONNET_PYDLL") != null;
-                if (!pythonSet)
-                {
-                    Initialized = false;
-                    return;
-                }
-
-                PythonEngine.Initialize();
-
-                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
-                    PythonEngine.PythonPath.IndexOf("dlls", StringComparison.OrdinalIgnoreCase) < 0)
-                {
-                    dynamic sys = Py.Import("sys");
-                    sys.path.append(Path.Combine(Path.GetDirectoryName(Environment.GetEnvironmentVariable("PYTHONNET_PYDLL")), "DLLs"));
-                }
-
-                Initialized = true;
-            }
-
-            public void Dispose()
-            {
-                PythonEngine.Shutdown();
-            }
-        }
-
-        public CDataSchemaPythonTest(PythonNet pythonNet)
-        {
-            if (!pythonNet.Initialized)
-            {
-                bool inCIJob = Environment.GetEnvironmentVariable("GITHUB_ACTIONS") == "true";
-                bool inVerificationJob = Environment.GetEnvironmentVariable("TEST_CSHARP") == "1";
-
-                // Skip these tests if this is not in CI or is a verification job and PythonNet couldn't be initialized
-                Skip.If(inVerificationJob || !inCIJob, "PYTHONNET_PYDLL not set; skipping C Data Interface tests.");
-
-                // Otherwise throw
-                throw new Exception("PYTHONNET_PYDLL not set; cannot run C Data Interface tests.");
-            }
-        }
-
-        private static Schema GetTestSchema()
-        {
-            using (Py.GIL())
-            {
-                var schema = new Schema.Builder()
-                    .Field(f => f.Name("null").DataType(NullType.Default).Nullable(true).Metadata("k0", "v0"))
-                    .Field(f => f.Name("bool").DataType(BooleanType.Default).Nullable(true))
-                    .Field(f => f.Name("i8").DataType(Int8Type.Default).Nullable(true))
-                    .Field(f => f.Name("u8").DataType(UInt8Type.Default).Nullable(true))
-                    .Field(f => f.Name("i16").DataType(Int16Type.Default).Nullable(true))
-                    .Field(f => f.Name("u16").DataType(UInt16Type.Default).Nullable(true))
-                    .Field(f => f.Name("i32").DataType(Int32Type.Default).Nullable(true))
-                    .Field(f => f.Name("u32").DataType(UInt32Type.Default).Nullable(true))
-                    .Field(f => f.Name("i64").DataType(Int64Type.Default).Nullable(true))
-                    .Field(f => f.Name("u64").DataType(UInt64Type.Default).Nullable(true))
-
-                    .Field(f => f.Name("f16").DataType(HalfFloatType.Default).Nullable(true).Metadata("k1a", "").Metadata("k1b", "断箭"))
-                    .Field(f => f.Name("f32").DataType(FloatType.Default).Nullable(true))
-                    .Field(f => f.Name("f64").DataType(DoubleType.Default).Nullable(true))
-
-                    .Field(f => f.Name("decimal128_19_3").DataType(new Decimal128Type(19, 3)).Nullable(true))
-                    .Field(f => f.Name("decimal256_19_3").DataType(new Decimal256Type(19, 3)).Nullable(true))
-                    .Field(f => f.Name("decimal256_40_2").DataType(new Decimal256Type(40, 2)).Nullable(false))
-
-                    .Field(f => f.Name("binary").DataType(BinaryType.Default).Nullable(false))
-                    .Field(f => f.Name("string").DataType(StringType.Default).Nullable(false))
-                    .Field(f => f.Name("fw_binary_10").DataType(new FixedSizeBinaryType(10)).Nullable(false))
-
-                    .Field(f => f.Name("date32").DataType(Date32Type.Default).Nullable(false))
-                    .Field(f => f.Name("date64").DataType(Date64Type.Default).Nullable(false))
-                    .Field(f => f.Name("time32_s").DataType(new Time32Type(TimeUnit.Second)).Nullable(false))
-                    .Field(f => f.Name("time32_ms").DataType(new Time32Type(TimeUnit.Millisecond)).Nullable(false))
-                    .Field(f => f.Name("time64_us").DataType(new Time64Type(TimeUnit.Microsecond)).Nullable(false))
-                    .Field(f => f.Name("time64_ns").DataType(new Time64Type(TimeUnit.Nanosecond)).Nullable(false))
-
-                    .Field(f => f.Name("timestamp_ns").DataType(new TimestampType(TimeUnit.Nanosecond, (string) null)).Nullable(false))
-                    .Field(f => f.Name("timestamp_us").DataType(new TimestampType(TimeUnit.Microsecond, (string) null)).Nullable(false))
-                    .Field(f => f.Name("timestamp_us_paris").DataType(new TimestampType(TimeUnit.Microsecond, "Europe/Paris")).Nullable(true))
-
-                    .Field(f => f.Name("list_string").DataType(new ListType(StringType.Default)).Nullable(false))
-                    .Field(f => f.Name("list_list_i32").DataType(new ListType(new ListType(Int32Type.Default))).Nullable(false))
-
-                    .Field(f => f.Name("fixed_length_list_i64").DataType(new FixedSizeListType(Int64Type.Default, 10)).Nullable(true))
-
-                    .Field(f => f.Name("dict_string").DataType(new DictionaryType(Int32Type.Default, StringType.Default, false)).Nullable(false))
-                    .Field(f => f.Name("dict_string_ordered").DataType(new DictionaryType(Int32Type.Default, StringType.Default, true)).Nullable(false))
-                    .Field(f => f.Name("list_dict_string").DataType(new ListType(new DictionaryType(Int32Type.Default, StringType.Default, false))).Nullable(false))
-
-                    .Field(f => f.Name("dense_union").DataType(new UnionType(new[] { new Field("i64", Int64Type.Default, false), new Field("f32", FloatType.Default, true), }, new[] { 0, 1 }, UnionMode.Dense)))
-                    .Field(f => f.Name("sparse_union").DataType(new UnionType(new[] { new Field("i32", Int32Type.Default, true), new Field("f64", DoubleType.Default, false), }, new[] { 0, 1 }, UnionMode.Sparse)))
-
-                    .Field(f => f.Name("map").DataType(new MapType(StringType.Default, Int32Type.Default)).Nullable(false))
-
-                    .Field(f => f.Name("duration_s").DataType(DurationType.Second).Nullable(false))
-                    .Field(f => f.Name("duration_ms").DataType(DurationType.Millisecond).Nullable(true))
-                    .Field(f => f.Name("duration_us").DataType(DurationType.Microsecond).Nullable(false))
-                    .Field(f => f.Name("duration_ns").DataType(DurationType.Nanosecond).Nullable(true))
-
-                    .Field(f => f.Name("interval").DataType(IntervalType.FromIntervalUnit(IntervalUnit.MonthDayNanosecond)))
-
-                    // Checking wider characters.
-                    .Field(f => f.Name("hello 你好 😄").DataType(BooleanType.Default).Nullable(true))
-
-                    .Metadata("k2a", "v2abc").Metadata("k2b", "v2abc").Metadata("k2c", "v2abc")
-                    .Build();
-                return schema;
-            }
-        }
-
-        private static IEnumerable<dynamic> GetPythonFields()
-        {
-            using (Py.GIL())
-            {
-                Dictionary<string, string> metadata0 = new Dictionary<string, string> { { "k0", "v0" } };
-                Dictionary<string, string> metadata1 = new Dictionary<string, string> { { "k1a", "" }, { "k1b", "断箭" } };
-
-                dynamic pa = Py.Import("pyarrow");
-                yield return pa.field("null", pa.GetAttr("null").Invoke(), true).with_metadata(metadata0);
-                yield return pa.field("bool", pa.bool_(), true);
-                yield return pa.field("i8", pa.int8(), true);
-                yield return pa.field("u8", pa.uint8(), true);
-                yield return pa.field("i16", pa.int16(), true);
-                yield return pa.field("u16", pa.uint16(), true);
-                yield return pa.field("i32", pa.int32(), true);
-                yield return pa.field("u32", pa.uint32(), true);
-                yield return pa.field("i64", pa.int64(), true);
-                yield return pa.field("u64", pa.uint64(), true);
-
-                yield return pa.field("f16", pa.float16(), true).with_metadata(metadata1);
-                yield return pa.field("f32", pa.float32(), true);
-                yield return pa.field("f64", pa.float64(), true);
-
-                yield return pa.field("decimal128_19_3", pa.decimal128(19, 3), true);
-                yield return pa.field("decimal256_19_3", pa.decimal256(19, 3), true);
-                yield return pa.field("decimal256_40_2", pa.decimal256(40, 2), false);
-
-                yield return pa.field("binary", pa.binary(), false);
-                yield return pa.field("string", pa.utf8(), false);
-                yield return pa.field("fw_binary_10", pa.binary(10), false);
-
-                yield return pa.field("date32", pa.date32(), false);
-                yield return pa.field("date64", pa.date64(), false);
-                yield return pa.field("time32_s", pa.time32("s"), false);
-                yield return pa.field("time32_ms", pa.time32("ms"), false);
-                yield return pa.field("time64_us", pa.time64("us"), false);
-                yield return pa.field("time64_ns", pa.time64("ns"), false);
-
-                yield return pa.field("timestamp_ns", pa.timestamp("ns"), false);
-                yield return pa.field("timestamp_us", pa.timestamp("us"), false);
-                yield return pa.field("timestamp_us_paris", pa.timestamp("us", "Europe/Paris"), true);
-
-                yield return pa.field("list_string", pa.list_(pa.utf8()), false);
-                yield return pa.field("list_list_i32", pa.list_(pa.list_(pa.int32())), false);
-
-                yield return pa.field("fixed_length_list_i64", pa.list_(pa.int64(), 10), true);
-
-                yield return pa.field("dict_string", pa.dictionary(pa.int32(), pa.utf8(), false), false);
-                yield return pa.field("dict_string_ordered", pa.dictionary(pa.int32(), pa.utf8(), true), false);
-                yield return pa.field("list_dict_string", pa.list_(pa.dictionary(pa.int32(), pa.utf8(), false)), false);
-
-                yield return pa.field("dense_union", pa.dense_union(List(pa.field("i64", pa.int64(), false), pa.field("f32", pa.float32(), true))));
-                yield return pa.field("sparse_union", pa.sparse_union(List(pa.field("i32", pa.int32(), true), pa.field("f64", pa.float64(), false))));
-
-                yield return pa.field("map", pa.map_(pa.@string(), pa.int32()), false);
-
-                yield return pa.field("duration_s", pa.duration("s"), false);
-                yield return pa.field("duration_ms", pa.duration("ms"), true);
-                yield return pa.field("duration_us", pa.duration("us"), false);
-                yield return pa.field("duration_ns", pa.duration("ns"), true);
-
-                yield return pa.field("interval", pa.month_day_nano_interval());
-
-                yield return pa.field("hello 你好 😄", pa.bool_(), true);
-            }
-        }
-
-        private static dynamic GetPythonSchema()
-        {
-            using (Py.GIL())
-            {
-                Dictionary<string, string> metadata = new Dictionary<string, string> { { "k2a", "v2abc" }, { "k2b", "v2abc" }, { "k2c", "v2abc" } };
-
-                dynamic pa = Py.Import("pyarrow");
-                return pa.schema(GetPythonFields().ToList()).with_metadata(metadata);
-            }
-        }
-
-        private IArrowArray GetTestArray()
-        {
-            var builder = new StringArray.Builder();
-            builder.Append("hello");
-            builder.Append("world");
-            builder.AppendNull();
-            builder.Append("foo");
-            builder.Append("bar");
-            return builder.Build();
-        }
-
-        private dynamic GetPythonArray()
-        {
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                return pa.array(new[] { "hello", "world", null, "foo", "bar" });
-            }
-        }
-
-        private RecordBatch GetTestRecordBatch()
-        {
-            Field[] fields = new[]
-            {
-                new Field("col1", Int64Type.Default, true),
-                new Field("col2", StringType.Default, true),
-                new Field("col3", DoubleType.Default, true),
-            };
-            return new RecordBatch(
-                new Schema(fields, null),
-                new IArrowArray[]
-                {
-                    new Int64Array.Builder().AppendRange(new long[] { 1, 2, 3 }).AppendNull().Append(5).Build(),
-                    GetTestArray(),
-                    new DoubleArray.Builder().AppendRange(new double[] { 0.0, 1.4, 2.5, 3.6, 4.7 }).Build(),
-                },
-                5);
-        }
-
-        private dynamic GetPythonRecordBatch()
-        {
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic table = pa.table(
-                    new PyList(new PyObject[]
-                    {
-                        pa.array(new long?[] { 1, 2, 3, null, 5 }),
-                        pa.array(new[] { "hello", "world", null, "foo", "bar" }),
-                        pa.array(new[] { 0.0, 1.4, 2.5, 3.6, 4.7 })
-                    }),
-                    new[] { "col1", "col2", "col3" });
-
-                return table.to_batches()[0];
-            }
-        }
-
-        private IArrowArrayStream GetTestArrayStream()
-        {
-            RecordBatch recordBatch = GetTestRecordBatch();
-            return new TestArrayStream(recordBatch.Schema, recordBatch);
-        }
-
-        private dynamic GetPythonRecordBatchReader()
-        {
-            dynamic recordBatch = GetPythonRecordBatch();
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                return pa.RecordBatchReader.from_batches(recordBatch.schema, new PyList(new PyObject[] { recordBatch }));
-            }
-        }
-
-        // Schemas created in Python, used in CSharp
-        [SkippableFact]
-        public unsafe void ImportType()
-        {
-            Schema schema = GetTestSchema();
-            IEnumerable<dynamic> pyFields = GetPythonFields();
-
-            foreach ((Field field, dynamic pyField) in schema.FieldsList
-                .Zip(pyFields))
-            {
-                CArrowSchema* cSchema = CArrowSchema.Create();
-
-                using (Py.GIL())
-                {
-                    dynamic pyDatatype = pyField.type;
-                    // Python expects the pointer as an integer
-                    long longPtr = ((IntPtr)cSchema).ToInt64();
-                    pyDatatype._export_to_c(longPtr);
-                }
-
-                var dataTypeComparer = new ArrayTypeComparer(field.DataType);
-                ArrowType importedType = CArrowSchemaImporter.ImportType(cSchema);
-                dataTypeComparer.Visit(importedType);
-
-                if (importedType is DictionaryType importedDictType)
-                {
-                    Assert.Equal(((DictionaryType)field.DataType).Ordered, importedDictType.Ordered);
-                }
-
-                // Since we allocated, we are responsible for freeing the pointer.
-                CArrowSchema.Free(cSchema);
-            }
-        }
-
-        [SkippableFact]
-        public unsafe void ImportField()
-        {
-            Schema schema = GetTestSchema();
-            IEnumerable<dynamic> pyFields = GetPythonFields();
-
-            foreach ((Field field, dynamic pyField) in schema.FieldsList
-                .Zip(pyFields))
-            {
-                CArrowSchema* cSchema = CArrowSchema.Create();
-
-                using (Py.GIL())
-                {
-                    long longPtr = ((IntPtr)cSchema).ToInt64();
-                    pyField._export_to_c(longPtr);
-                }
-
-                Field importedField = CArrowSchemaImporter.ImportField(cSchema);
-                FieldComparer.Compare(field, importedField);
-
-                // Since we allocated, we are responsible for freeing the pointer.
-                CArrowSchema.Free(cSchema);
-            }
-        }
-
-        [SkippableFact]
-        public unsafe void ImportSchema()
-        {
-            Schema schema = GetTestSchema();
-            dynamic pySchema = GetPythonSchema();
-
-            CArrowSchema* cSchema = CArrowSchema.Create();
-
-            using (Py.GIL())
-            {
-                long longPtr = ((IntPtr)cSchema).ToInt64();
-                pySchema._export_to_c(longPtr);
-            }
-
-            Schema importedSchema = CArrowSchemaImporter.ImportSchema(cSchema);
-            SchemaComparer.Compare(schema, importedSchema);
-
-            // Since we allocated, we are responsible for freeing the pointer.
-            CArrowSchema.Free(cSchema);
-        }
-
-
-        // Schemas created in CSharp, exported to Python
-        [SkippableFact]
-        public unsafe void ExportType()
-        {
-            Schema schema = GetTestSchema();
-            IEnumerable<dynamic> pyFields = GetPythonFields();
-
-            foreach ((Field field, dynamic pyField) in schema.FieldsList
-                .Zip(pyFields))
-            {
-                IArrowType datatype = field.DataType;
-                CArrowSchema* cSchema = CArrowSchema.Create();
-                CArrowSchemaExporter.ExportType(datatype, cSchema);
-
-                // For Python, we need to provide the pointer
-                long longPtr = ((IntPtr)cSchema).ToInt64();
-
-                using (Py.GIL())
-                {
-                    dynamic pa = Py.Import("pyarrow");
-                    dynamic expectedPyType = pyField.type;
-                    dynamic exportedPyType = pa.DataType._import_from_c(longPtr);
-                    Assert.True(exportedPyType == expectedPyType);
-
-                    if (pa.types.is_dictionary(exportedPyType))
-                    {
-                        Assert.Equal(expectedPyType.ordered, exportedPyType.ordered);
-                    }
-                }
-
-                // Python should have called release once `exportedPyType` went out-of-scope.
-                Assert.True(cSchema->release == default);
-                Assert.True(cSchema->format == null);
-                Assert.Equal(0, cSchema->flags);
-                Assert.Equal(0, cSchema->n_children);
-                Assert.True(cSchema->dictionary == null);
-
-                // Since we allocated, we are responsible for freeing the pointer.
-                CArrowSchema.Free(cSchema);
-            }
-        }
-
-        [SkippableFact]
-        public unsafe void ExportField()
-        {
-            Schema schema = GetTestSchema();
-            IEnumerable<dynamic> pyFields = GetPythonFields();
-
-            foreach ((Field field, dynamic pyField) in schema.FieldsList
-                .Zip(pyFields))
-            {
-                CArrowSchema* cSchema = CArrowSchema.Create();
-                CArrowSchemaExporter.ExportField(field, cSchema);
-
-                // For Python, we need to provide the pointer
-                long longPtr = ((IntPtr)cSchema).ToInt64();
-
-                using (Py.GIL())
-                {
-                    dynamic pa = Py.Import("pyarrow");
-                    dynamic exportedPyField = pa.Field._import_from_c(longPtr);
-                    Assert.True(exportedPyField == pyField);
-                }
-
-                // Python should have called release once `exportedPyField` went out-of-scope.
-                Assert.True(cSchema->name == null);
-                Assert.True(cSchema->release == default);
-                Assert.True(cSchema->format == null);
-
-                // Since we allocated, we are responsible for freeing the pointer.
-                CArrowSchema.Free(cSchema);
-            }
-        }
-
-        [SkippableFact]
-        public unsafe void ExportSchema()
-        {
-            Schema schema = GetTestSchema();
-            dynamic pySchema = GetPythonSchema();
-
-            CArrowSchema* cSchema = CArrowSchema.Create();
-            CArrowSchemaExporter.ExportSchema(schema, cSchema);
-
-            // For Python, we need to provide the pointer
-            long longPtr = ((IntPtr)cSchema).ToInt64();
-
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic exportedPySchema = pa.Schema._import_from_c(longPtr);
-                Assert.True(exportedPySchema == pySchema);
-            }
-
-            // Since we allocated, we are responsible for freeing the pointer.
-            CArrowSchema.Free(cSchema);
-        }
-
-        [SkippableFact]
-        public unsafe void ImportArray()
-        {
-            CArrowArray* cArray = CArrowArray.Create();
-            CArrowSchema* cSchema = CArrowSchema.Create();
-
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic array = pa.array(new[] { "hello", "world", null, "foo", "bar" });
-
-                long arrayPtr = ((IntPtr)cArray).ToInt64();
-                long schemaPtr = ((IntPtr)cSchema).ToInt64();
-                array._export_to_c(arrayPtr, schemaPtr);
-            }
-
-            ArrowType type = CArrowSchemaImporter.ImportType(cSchema);
-            StringArray importedArray = (StringArray)CArrowArrayImporter.ImportArray(cArray, type);
-
-            Assert.Equal(5, importedArray.Length);
-            Assert.Equal("hello", importedArray.GetString(0));
-            Assert.Equal("world", importedArray.GetString(1));
-            Assert.Null(importedArray.GetString(2));
-            Assert.Equal("foo", importedArray.GetString(3));
-            Assert.Equal("bar", importedArray.GetString(4));
-
-            CArrowArray.Free(cArray);
-        }
-
-        [SkippableFact]
-        public unsafe void ImportRecordBatch()
-        {
-            CArrowArray* cArray = CArrowArray.Create();
-            CArrowSchema* cSchema = CArrowSchema.Create();
-
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic table = pa.table(
-                    new PyList(new PyObject[]
-                    {
-                        pa.array(new object[] { null, null, null, null, null }),
-                        pa.array(List(1, 2, 3, null, 5)),
-                        pa.array(List("hello", "world", null, "foo", "bar")),
-                        pa.array(List(0.0, 1.4, 2.5, 3.6, 4.7)),
-                        pa.array(new PyObject[] { List(1, 2), List(3, 4), PyObject.None, PyObject.None, List(5, 4, 3) }),
-                        pa.StructArray.from_arrays(
-                            List(
-                                List(10, 9, null, null, null),
-                                List("banana", "apple", "orange", "cherry", "grape"),
-                                List(null, 4.3, -9, 123.456, 0)
-                            ),
-                            new[] { "fld1", "fld2", "fld3" }),
-                        pa.DictionaryArray.from_arrays(
-                            pa.array(List(1, 0, 1, 1, null)),
-                            pa.array(List("foo", "bar"))),
-                        pa.FixedSizeListArray.from_arrays(
-                            pa.array(List(1, 2, 3, 4, null, 6, 7, null, null, null)),
-                            2),
-                        pa.UnionArray.from_dense(
-                            pa.array(List(0, 1, 1, 0, 0), type: "int8"),
-                            pa.array(List(0, 0, 1, 1, 2), type: "int32"),
-                            List(
-                                pa.array(List(1, 4, null)),
-                                pa.array(List("two", "three"))
-                            ),
-                            /* field name */ List("i32", "s"),
-                            /* type codes */ List(3, 2)),
-                        pa.MapArray.from_arrays(
-                            List(0, 0, 1, 2, 4, 10),
-                            pa.array(List("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten")),
-                            pa.array(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))),
-                        pa.array(List(1234, 2345, 3456, null, 6789), pa.duration("ms")),
-                        pa.array(
-                            List(Tuple(1, 2, 3), PyObject.None, Tuple(-1, -2, -3), Tuple(10, 0, 0), Tuple(0, 0, 20)),
-                            pa.month_day_nano_interval()),
-                    }),
-                    new[] { "col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8", "col9", "col10", "col11", "col12" });
-
-                dynamic batch = table.to_batches()[0];
-
-                long batchPtr = ((IntPtr)cArray).ToInt64();
-                long schemaPtr = ((IntPtr)cSchema).ToInt64();
-                batch._export_to_c(batchPtr, schemaPtr);
-            }
-
-            Schema schema = CArrowSchemaImporter.ImportSchema(cSchema);
-            RecordBatch recordBatch = CArrowArrayImporter.ImportRecordBatch(cArray, schema);
-            CArrowArray.Free(cArray);
-
-            Assert.Equal(5, recordBatch.Length);
-
-            NullArray col1 = (NullArray)recordBatch.Column("col1");
-            Assert.Equal(5, col1.Length);
-
-            Int64Array col2 = (Int64Array)recordBatch.Column("col2");
-            Assert.Equal(new long[] { 1, 2, 3, 0, 5 }, col2.Values.ToArray());
-            Assert.False(col2.IsValid(3));
-
-            StringArray col3 = (StringArray)recordBatch.Column("col3");
-            Assert.Equal(5, col3.Length);
-            Assert.Equal("hello", col3.GetString(0));
-            Assert.Equal("world", col3.GetString(1));
-            Assert.Null(col3.GetString(2));
-            Assert.Equal("foo", col3.GetString(3));
-            Assert.Equal("bar", col3.GetString(4));
-
-            DoubleArray col4 = (DoubleArray)recordBatch.Column("col4");
-            Assert.Equal(new double[] { 0.0, 1.4, 2.5, 3.6, 4.7 }, col4.Values.ToArray());
-
-            ListArray col5 = (ListArray)recordBatch.Column("col5");
-            Assert.Equal(new long[] { 1, 2, 3, 4, 5, 4, 3 }, ((Int64Array)col5.Values).Values.ToArray());
-            Assert.Equal(new int[] { 0, 2, 4, 4, 4, 7 }, col5.ValueOffsets.ToArray());
-            Assert.False(col5.IsValid(2));
-            Assert.False(col5.IsValid(3));
-
-            StructArray col6 = (StructArray)recordBatch.Column("col6");
-            Assert.Equal(5, col6.Length);
-            Int64Array col6a = (Int64Array)col6.Fields[0];
-            Assert.Equal(new long[] { 10, 9, 0, 0, 0 }, col6a.Values.ToArray());
-            StringArray col6b = (StringArray)col6.Fields[1];
-            Assert.Equal("banana", col6b.GetString(0));
-            Assert.Equal("apple", col6b.GetString(1));
-            Assert.Equal("orange", col6b.GetString(2));
-            Assert.Equal("cherry", col6b.GetString(3));
-            Assert.Equal("grape", col6b.GetString(4));
-            DoubleArray col6c = (DoubleArray)col6.Fields[2];
-            Assert.Equal(new double[] { 0, 4.3, -9, 123.456, 0 }, col6c.Values.ToArray());
-
-            DictionaryArray col7 = (DictionaryArray)recordBatch.Column("col7");
-            Assert.Equal(5, col7.Length);
-            Int64Array col7a = (Int64Array)col7.Indices;
-            Assert.Equal(new long[] { 1, 0, 1, 1, 0 }, col7a.Values.ToArray());
-            Assert.False(col7a.IsValid(4));
-            StringArray col7b = (StringArray)col7.Dictionary;
-            Assert.Equal(2, col7b.Length);
-            Assert.Equal("foo", col7b.GetString(0));
-            Assert.Equal("bar", col7b.GetString(1));
-
-            FixedSizeListArray col8 = (FixedSizeListArray)recordBatch.Column("col8");
-            Assert.Equal(5, col8.Length);
-            Int64Array col8a = (Int64Array)col8.Values;
-            Assert.Equal(new long[] { 1, 2, 3, 4, 0, 6, 7, 0, 0, 0 }, col8a.Values.ToArray());
-            Assert.True(col8a.IsValid(3));
-            Assert.False(col8a.IsValid(9));
-
-            UnionArray col9 = (UnionArray)recordBatch.Column("col9");
-            Assert.Equal(5, col9.Length);
-            Assert.True(col9 is DenseUnionArray);
-
-            MapArray col10 = (MapArray)recordBatch.Column("col10");
-            Assert.Equal(5, col10.Length);
-            Assert.Equal(new int[] { 0, 0, 1, 2, 4, 10}, col10.ValueOffsets.ToArray());
-            Assert.Equal(new long?[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, ((Int64Array)col10.Values).ToList().ToArray());
-
-            DurationArray col11 = (DurationArray)recordBatch.Column("col11");
-            Assert.Equal(5, col11.Length);
-
-            MonthDayNanosecondIntervalArray col12 = (MonthDayNanosecondIntervalArray)recordBatch.Column("col12");
-            Assert.Equal(5, col12.Length);
-            Assert.Equal(new MonthDayNanosecondInterval(1, 2, 3), col12.GetValue(0));
-            Assert.Null(col12.GetValue(1));
-            Assert.Equal(new MonthDayNanosecondInterval(-1, -2, -3), col12.GetValue(2));
-            Assert.Equal(new MonthDayNanosecondInterval(10, 0, 0), col12.GetValue(3));
-            Assert.Equal(new MonthDayNanosecondInterval(0, 0, 20), col12.GetValue(4));
-        }
-
-        [SkippableFact]
-        public unsafe void ImportArrayStream()
-        {
-            CArrowArrayStream* cArrayStream = CArrowArrayStream.Create();
-
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic table = pa.table(
-                    new PyList(new PyObject[]
-                    {
-                        pa.array(new long?[] { 1, 2, 3, null, 5 }),
-                        pa.array(new[] { "hello", "world", null, "foo", "bar" }),
-                        pa.array(new[] { 0.0, 1.4, 2.5, 3.6, 4.7 })
-                    }),
-                    new[] { "col1", "col2", "col3" });
-
-                dynamic batchReader = pa.RecordBatchReader.from_batches(table.schema, table.to_batches());
-
-                long streamPtr = ((IntPtr)cArrayStream).ToInt64();
-                batchReader._export_to_c(streamPtr);
-            }
-
-            IArrowArrayStream stream = CArrowArrayStreamImporter.ImportArrayStream(cArrayStream);
-            CArrowArrayStream.Free(cArrayStream);
-
-            var batch1 = stream.ReadNextRecordBatchAsync().Result;
-            Assert.Equal(5, batch1.Length);
-
-            Int64Array col1 = (Int64Array)batch1.Column("col1");
-            Assert.Equal(5, col1.Length);
-            Assert.Equal(1, col1.GetValue(0));
-            Assert.Equal(2, col1.GetValue(1));
-            Assert.Equal(3, col1.GetValue(2));
-            Assert.Null(col1.GetValue(3));
-            Assert.Equal(5, col1.GetValue(4));
-
-            StringArray col2 = (StringArray)batch1.Column("col2");
-            Assert.Equal(5, col2.Length);
-            Assert.Equal("hello", col2.GetString(0));
-            Assert.Equal("world", col2.GetString(1));
-            Assert.Null(col2.GetString(2));
-            Assert.Equal("foo", col2.GetString(3));
-            Assert.Equal("bar", col2.GetString(4));
-
-            DoubleArray col3 = (DoubleArray)batch1.Column("col3");
-            Assert.Equal(new double[] { 0.0, 1.4, 2.5, 3.6, 4.7 }, col3.Values.ToArray());
-
-            var batch2 = stream.ReadNextRecordBatchAsync().Result;
-            Assert.Null(batch2);
-        }
-
-        [SkippableFact]
-        public unsafe void ExportArray()
-        {
-            IArrowArray array = GetTestArray();
-            dynamic pyArray = GetPythonArray();
-
-            CArrowArray* cArray = CArrowArray.Create();
-            CArrowArrayExporter.ExportArray(array, cArray);
-
-            CArrowSchema* cSchema = CArrowSchema.Create();
-            CArrowSchemaExporter.ExportType(array.Data.DataType, cSchema);
-
-            // For Python, we need to provide the pointers
-            long arrayPtr = ((IntPtr)cArray).ToInt64();
-            long schemaPtr = ((IntPtr)cSchema).ToInt64();
-
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic exportedPyArray = pa.Array._import_from_c(arrayPtr, schemaPtr);
-                Assert.True(exportedPyArray == pyArray);
-            }
-
-            // Since we allocated, we are responsible for freeing the pointer.
-            CArrowArray.Free(cArray);
-            CArrowSchema.Free(cSchema);
-        }
-
-        [SkippableFact]
-        public unsafe void ExportBatch()
-        {
-            RecordBatch batch = GetTestRecordBatch();
-            dynamic pyBatch = GetPythonRecordBatch();
-
-            CArrowArray* cArray = CArrowArray.Create();
-            CArrowArrayExporter.ExportRecordBatch(batch, cArray);
-
-            CArrowSchema* cSchema = CArrowSchema.Create();
-            CArrowSchemaExporter.ExportSchema(batch.Schema, cSchema);
-
-            // For Python, we need to provide the pointers
-            long arrayPtr = ((IntPtr)cArray).ToInt64();
-            long schemaPtr = ((IntPtr)cSchema).ToInt64();
-
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic exportedPyArray = pa.RecordBatch._import_from_c(arrayPtr, schemaPtr);
-                Assert.True(exportedPyArray == pyBatch);
-            }
-
-            // Since we allocated, we are responsible for freeing the pointer.
-            CArrowArray.Free(cArray);
-            CArrowSchema.Free(cSchema);
-        }
-
-        [SkippableFact]
-        public unsafe void RoundTripTestBatch()
-        {
-            // TODO: Enable these once this the version of pyarrow referenced during testing supports them
-            HashSet<ArrowTypeId> unsupported = new HashSet<ArrowTypeId> { ArrowTypeId.ListView, ArrowTypeId.BinaryView, ArrowTypeId.StringView, ArrowTypeId.Decimal32, ArrowTypeId.Decimal64 };
-            RecordBatch batch1 = TestData.CreateSampleRecordBatch(4, excludedTypes: unsupported);
-            RecordBatch batch2 = batch1.Clone();
-
-            CArrowArray* cExportArray = CArrowArray.Create();
-            CArrowArrayExporter.ExportRecordBatch(batch1, cExportArray);
-
-            CArrowSchema* cExportSchema = CArrowSchema.Create();
-            CArrowSchemaExporter.ExportSchema(batch1.Schema, cExportSchema);
-
-            CArrowArray* cImportArray = CArrowArray.Create();
-            CArrowSchema* cImportSchema = CArrowSchema.Create();
-
-            // For Python, we need to provide the pointers
-            long exportArrayPtr = ((IntPtr)cExportArray).ToInt64();
-            long exportSchemaPtr = ((IntPtr)cExportSchema).ToInt64();
-            long importArrayPtr = ((IntPtr)cImportArray).ToInt64();
-            long importSchemaPtr = ((IntPtr)cImportSchema).ToInt64();
-
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic exportedPyArray = pa.RecordBatch._import_from_c(exportArrayPtr, exportSchemaPtr);
-                exportedPyArray._export_to_c(importArrayPtr, importSchemaPtr);
-            }
-
-            Schema schema = CArrowSchemaImporter.ImportSchema(cImportSchema);
-            RecordBatch importedBatch = CArrowArrayImporter.ImportRecordBatch(cImportArray, schema);
-
-            ArrowReaderVerifier.CompareBatches(batch2, importedBatch, strictCompare: false); // Non-strict because span lengths won't match.
-
-            // Since we allocated, we are responsible for freeing the pointer.
-            CArrowArray.Free(cExportArray);
-            CArrowSchema.Free(cExportSchema);
-            CArrowArray.Free(cImportArray);
-            CArrowSchema.Free(cImportSchema);
-        }
-
-        [SkippableFact]
-        public unsafe void RoundTripTestSlicedBatch()
-        {
-            // TODO: Enable these once this the version of pyarrow referenced during testing supports them
-            HashSet<ArrowTypeId> unsupported = new HashSet<ArrowTypeId> { ArrowTypeId.ListView, ArrowTypeId.BinaryView, ArrowTypeId.StringView, ArrowTypeId.Decimal32, ArrowTypeId.Decimal64 };
-            RecordBatch batch1 = TestData.CreateSampleRecordBatch(4, excludedTypes: unsupported);
-            RecordBatch batch1slice = batch1.Slice(1, 2);
-            RecordBatch batch2 = batch1slice.Clone();
-
-            CArrowArray* cExportArray = CArrowArray.Create();
-            CArrowArrayExporter.ExportRecordBatch(batch1slice, cExportArray);
-
-            CArrowSchema* cExportSchema = CArrowSchema.Create();
-            CArrowSchemaExporter.ExportSchema(batch1.Schema, cExportSchema);
-
-            CArrowArray* cImportArray = CArrowArray.Create();
-            CArrowSchema* cImportSchema = CArrowSchema.Create();
-
-            // For Python, we need to provide the pointers
-            long exportArrayPtr = ((IntPtr)cExportArray).ToInt64();
-            long exportSchemaPtr = ((IntPtr)cExportSchema).ToInt64();
-            long importArrayPtr = ((IntPtr)cImportArray).ToInt64();
-            long importSchemaPtr = ((IntPtr)cImportSchema).ToInt64();
-
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic exportedPyArray = pa.RecordBatch._import_from_c(exportArrayPtr, exportSchemaPtr);
-                exportedPyArray._export_to_c(importArrayPtr, importSchemaPtr);
-            }
-
-            Schema schema = CArrowSchemaImporter.ImportSchema(cImportSchema);
-            RecordBatch importedBatch = CArrowArrayImporter.ImportRecordBatch(cImportArray, schema);
-
-            ArrowReaderVerifier.CompareBatches(batch2, importedBatch, strictCompare: false); // Non-strict because span lengths won't match.
-
-            // Since we allocated, we are responsible for freeing the pointer.
-            CArrowArray.Free(cExportArray);
-            CArrowSchema.Free(cExportSchema);
-            CArrowArray.Free(cImportArray);
-            CArrowSchema.Free(cImportSchema);
-        }
-
-        [SkippableFact]
-        public unsafe void ExportBatchReader()
-        {
-            RecordBatch batch = GetTestRecordBatch();
-            dynamic pyBatch = GetPythonRecordBatch();
-
-            CArrowArray* cArray = CArrowArray.Create();
-            CArrowArrayExporter.ExportRecordBatch(batch, cArray);
-
-            CArrowSchema* cSchema = CArrowSchema.Create();
-            CArrowSchemaExporter.ExportSchema(batch.Schema, cSchema);
-
-            // For Python, we need to provide the pointers
-            long arrayPtr = ((IntPtr)cArray).ToInt64();
-            long schemaPtr = ((IntPtr)cSchema).ToInt64();
-
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic exportedPyArray = pa.RecordBatch._import_from_c(arrayPtr, schemaPtr);
-                Assert.True(exportedPyArray == pyBatch);
-            }
-
-            // Since we allocated, we are responsible for freeing the pointer.
-            CArrowArray.Free(cArray);
-            CArrowSchema.Free(cSchema);
-        }
-
-        [SkippableFact]
-        public unsafe void ExportArrayStream()
-        {
-            IArrowArrayStream arrayStream = GetTestArrayStream();
-            dynamic pyRecordBatchReader = GetPythonRecordBatchReader();
-
-            CArrowArrayStream* cArrayStream = CArrowArrayStream.Create();
-            CArrowArrayStreamExporter.ExportArrayStream(arrayStream, cArrayStream);
-
-            // For Python, we need to provide the pointers
-            long arrayStreamPtr = ((IntPtr)cArrayStream).ToInt64();
-
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic exportedPyReader = pa.RecordBatchReader._import_from_c(arrayStreamPtr);
-                Assert.True(exportedPyReader.read_all() == pyRecordBatchReader.read_all());
-            }
-
-            // Since we allocated, we are responsible for freeing the pointer.
-            CArrowArrayStream.Free(cArrayStream);
-        }
-
-        [SkippableFact]
-        public unsafe void ImportRecordBatchFromBuffer()
-        {
-            using (Py.GIL())
-            {
-                dynamic pa = Py.Import("pyarrow");
-                dynamic batch = pa.record_batch(
-                    new PyList(new PyObject[]
-                    {
-                        pa.array(new long?[] { 1, 2, 3, null, 5 }),
-                        pa.array(new[] { "hello", "world", null, "foo", "bar" }),
-                        pa.array(new[] { 0.0, 1.4, 2.5, 3.6, 4.7 }),
-                        pa.array(new bool?[] { true, false, null, false, true }),
-                    }),
-                    new[] { null, "", "column", "column" });
-
-                dynamic sink = pa.BufferOutputStream();
-                dynamic writer = pa.ipc.new_stream(sink, batch.schema);
-                writer.write_batch(batch);
-                ((IDisposable)writer).Dispose();
-
-                dynamic buf = sink.getvalue();
-                // buf.address, buf.size
-
-                IntPtr address = (IntPtr)(long)buf.address;
-                int size = buf.size;
-                byte[] buffer = new byte[size];
-                byte* ptr = (byte*)address.ToPointer();
-                for (int i = 0; i < size; i++)
-                {
-                    buffer[i] = ptr[i];
-                }
-
-                using (ArrowStreamReader reader = new ArrowStreamReader(new ReadOnlyMemory<byte>(buffer)))
-                {
-                    RecordBatch batch2 = reader.ReadNextRecordBatch();
-                    Assert.Equal("None", batch2.Schema.FieldsList[0].Name);
-                    Assert.Equal("", batch2.Schema.FieldsList[1].Name);
-                    Assert.Equal("column", batch2.Schema.FieldsList[2].Name);
-                    Assert.Equal("column", batch2.Schema.FieldsList[3].Name);
-                }
-            }
-        }
-
-        private static PyObject List(params int?[] values)
-        {
-            return new PyList(values.Select(i => i == null ? PyObject.None : new PyInt(i.Value)).ToArray());
-        }
-
-        private static PyObject List(params long?[] values)
-        {
-            return new PyList(values.Select(i => i == null ? PyObject.None : new PyInt(i.Value)).ToArray());
-        }
-
-        private static PyObject List(params double?[] values)
-        {
-            return new PyList(values.Select(i => i == null ? PyObject.None : new PyFloat(i.Value)).ToArray());
-        }
-
-        private static PyObject List(params string[] values)
-        {
-            return new PyList(values.Select(i => i == null ? PyObject.None : new PyString(i)).ToArray());
-        }
-
-        private static PyObject List(params PyObject[] values)
-        {
-            return new PyList(values);
-        }
-
-        private static PyObject Tuple(params int?[] values)
-        {
-            return new PyTuple(values.Select(i => i == null ? PyObject.None : new PyInt(i.Value)).ToArray());
-        }
-
-        sealed class TestArrayStream : IArrowArrayStream
-        {
-            private readonly RecordBatch[] _batches;
-            private int _index;
-
-            public TestArrayStream(Schema schema, params RecordBatch[] batches)
-            {
-                Schema = schema;
-                _batches = batches;
-            }
-
-            public Schema Schema { get; }
-
-            public ValueTask<RecordBatch> ReadNextRecordBatchAsync(CancellationToken cancellationToken = default)
-            {
-                if (_index < 0) { throw new ObjectDisposedException(nameof(TestArrayStream)); }
-
-                RecordBatch result = _index < _batches.Length ? _batches[_index++] : null;
-                return new ValueTask<RecordBatch>(result);
-            }
-
-            public void Dispose()
-            {
-                _index = -1;
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/CDataInterfaceSchemaTests.cs b/csharp/test/Apache.Arrow.Tests/CDataInterfaceSchemaTests.cs
deleted file mode 100644
index 4aa5eb6..0000000
--- a/csharp/test/Apache.Arrow.Tests/CDataInterfaceSchemaTests.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Runtime.InteropServices;
-using Apache.Arrow.C;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class CDataSchemaTest
-    {
-        [Fact]
-        public unsafe void InitializeZeroed()
-        {
-            CArrowSchema* cSchema = CArrowSchema.Create();
-
-            Assert.True(cSchema->format == null);
-            Assert.True(cSchema->name == null);
-            Assert.True(cSchema->metadata == null);
-            Assert.Equal(0, cSchema->flags);
-            Assert.Equal(0, cSchema->n_children);
-            Assert.True(cSchema->children == null);
-            Assert.True(cSchema->dictionary == null);
-            Assert.True(cSchema->release == default);
-            Assert.True(cSchema->private_data == null);
-
-            CArrowSchema.Free(cSchema);
-        }
-
-        [Fact]
-        public unsafe void FlagsSet()
-        {
-            // Non-nullable field
-            {
-                var nonNullField = new Field("non_null", Int32Type.Default, false);
-                CArrowSchema* cSchema = CArrowSchema.Create();
-                CArrowSchemaExporter.ExportField(nonNullField, cSchema);
-                Assert.False(cSchema->GetFlag(CArrowSchema.ArrowFlagNullable));
-                CArrowSchema.Free(cSchema);
-            }
-
-            // Nullable field
-            {
-                var nullableField = new Field("nullable", Int32Type.Default, true);
-                CArrowSchema* cSchema = CArrowSchema.Create();
-                CArrowSchemaExporter.ExportField(nullableField, cSchema);
-                Assert.True(cSchema->GetFlag(CArrowSchema.ArrowFlagNullable));
-                CArrowSchema.Free(cSchema);
-            }
-
-            // dictionary ordered
-            {
-                var orderedDictionary = new DictionaryType(Int32Type.Default, StringType.Default, true);
-                CArrowSchema* cSchema = CArrowSchema.Create();
-                CArrowSchemaExporter.ExportType(orderedDictionary, cSchema);
-                Assert.True(cSchema->GetFlag(CArrowSchema.ArrowFlagDictionaryOrdered));
-                CArrowSchema.Free(cSchema);
-            }
-
-            // dictionary unordered
-            {
-                var unorderedDictionary = new DictionaryType(Int32Type.Default, StringType.Default, false);
-                CArrowSchema* cSchema = CArrowSchema.Create();
-                CArrowSchemaExporter.ExportType(unorderedDictionary, cSchema);
-                Assert.False(cSchema->GetFlag(CArrowSchema.ArrowFlagDictionaryOrdered));
-                CArrowSchema.Free(cSchema);
-            }
-        }
-
-        [Fact]
-        public unsafe void CallsReleaseForValid()
-        {
-            CArrowSchema* cSchema = CArrowSchema.Create();
-            CArrowSchemaExporter.ExportType(Int32Type.Default, cSchema);
-            Assert.False(cSchema->release == default);
-            CArrowSchemaImporter.ImportType(cSchema);
-            Assert.True(cSchema->release == default);
-            CArrowSchema.Free(cSchema);
-        }
-
-#if NET5_0_OR_GREATER // can't round-trip marshaled delegate
-        [Fact]
-        public unsafe void CallsReleaseForInvalid()
-        {
-            // Make sure we call release callback, even if the imported schema
-            // is invalid.
-            CArrowSchema* cSchema = CArrowSchema.Create();
-
-            bool wasCalled = false;
-            var releaseCallback = (CArrowSchema* cSchema) =>
-            {
-                wasCalled = true;
-                cSchema->release = default;
-            };
-            cSchema->release = (delegate* unmanaged<CArrowSchema*, void>)Marshal.GetFunctionPointerForDelegate(
-                releaseCallback);
-
-            Assert.Throws<NullReferenceException>(() =>
-            {
-                CArrowSchemaImporter.ImportType(cSchema);
-            });
-            Assert.True(wasCalled);
-            CArrowSchema.Free(cSchema);
-
-            GC.KeepAlive(releaseCallback);
-        }
-#endif
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/ColumnTests.cs b/csharp/test/Apache.Arrow.Tests/ColumnTests.cs
deleted file mode 100644
index 2d867b7..0000000
--- a/csharp/test/Apache.Arrow.Tests/ColumnTests.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Linq;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class ColumnTests
-    {
-        public static Array MakeIntArray(int length)
-        {
-            // The following should be improved once the ArrayBuilder PR goes in
-            var intBuilder = new ArrowBuffer.Builder<int>();
-            intBuilder.AppendRange(Enumerable.Range(0, length).Select(x => x));
-            ArrowBuffer buffer = intBuilder.Build();
-            ArrayData intData = new ArrayData(Int32Type.Default, length, 0, 0, new[] { ArrowBuffer.Empty, buffer });
-            Array intArray = ArrowArrayFactory.BuildArray(intData) as Array;
-            return intArray;
-        }
-
-        [Fact]
-        public void TestColumn()
-        {
-            Array intArray = MakeIntArray(10);
-            Array intArrayCopy = MakeIntArray(10);
-
-            Field field = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-            Column column = new Column(field, new IArrowArray[] { intArray, intArrayCopy });
-
-            Assert.True(column.Name == field.Name);
-            Assert.True(column.Field == field);
-            Assert.Equal(20, column.Length);
-            Assert.Equal(0, column.NullCount);
-            Assert.Equal(field.DataType, column.Type);
-            
-            Column slice5 = column.Slice(0, 5);
-            Assert.Equal(5, slice5.Length);
-            Column sliceFull = column.Slice(2);
-            Assert.Equal(18, sliceFull.Length);
-            Column sliceMore = column.Slice(0, 25);
-            Assert.Equal(20, sliceMore.Length);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/Date32ArrayTests.cs b/csharp/test/Apache.Arrow.Tests/Date32ArrayTests.cs
deleted file mode 100644
index 6e4742c..0000000
--- a/csharp/test/Apache.Arrow.Tests/Date32ArrayTests.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class Date32ArrayTests
-    {
-        public static IEnumerable<object[]> GetDatesData() =>
-            TestDateAndTimeData.ExampleDates.Select(d => new object[] { d });
-
-        public static IEnumerable<object[]> GetDateTimesData() =>
-            TestDateAndTimeData.ExampleDateTimes.Select(dt => new object[] { dt });
-
-        public static IEnumerable<object[]> GetDateTimeOffsetsData() =>
-            TestDateAndTimeData.ExampleDateTimeOffsets.Select(dto => new object[] { dto });
-
-#if NET6_0_OR_GREATER
-        public static IEnumerable<object[]> GetDateOnlyData() =>
-            TestDateAndTimeData.ExampleDates.Select(d => new object[] { DateOnly.FromDateTime(d) });
-#endif
-
-        public class AppendNull
-        {
-            [Fact]
-            public void AppendThenGetGivesNull()
-            {
-                // Arrange
-                var builder = new Date32Array.Builder();
-
-                // Act
-                builder = builder.AppendNull();
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Null(array.GetDateTime(0));
-                Assert.Null(array.GetDateTimeOffset(0));
-                Assert.Null(array.GetValue(0));
-            }
-        }
-
-        public class AppendDateTime
-        {
-            [Theory]
-            [MemberData(nameof(GetDatesData), MemberType = typeof(Date32ArrayTests))]
-            public void AppendDateGivesSameDate(DateTime date)
-            {
-                // Arrange
-                var builder = new Date32Array.Builder();
-                var expectedDateTime = date;
-                var expectedDateTimeOffset =
-                    new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Unspecified), TimeSpan.Zero);
-                int expectedValue = (int)date.Subtract(new DateTime(1970, 1, 1)).TotalDays;
-
-                // Act
-                builder = builder.Append(date);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(expectedDateTime, array.GetDateTime(0));
-                Assert.Equal(expectedDateTimeOffset, array.GetDateTimeOffset(0));
-                Assert.Equal(expectedValue, array.GetValue(0));
-            }
-
-            [Theory]
-            [MemberData(nameof(GetDateTimesData), MemberType = typeof(Date32ArrayTests))]
-            public void AppendWithTimeGivesSameWithTimeIgnored(DateTime dateTime)
-            {
-                // Arrange
-                var builder = new Date32Array.Builder();
-                var expectedDateTime = dateTime.Date;
-                var expectedDateTimeOffset =
-                    new DateTimeOffset(DateTime.SpecifyKind(dateTime.Date, DateTimeKind.Unspecified), TimeSpan.Zero);
-                int expectedValue = (int)dateTime.Date.Subtract(new DateTime(1970, 1, 1)).TotalDays;
-
-                // Act
-                builder = builder.Append(dateTime);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(expectedDateTime, array.GetDateTime(0));
-                Assert.Equal(expectedDateTimeOffset, array.GetDateTimeOffset(0));
-                Assert.Equal(expectedValue, array.GetValue(0));
-            }
-        }
-
-        public class AppendDateTimeOffset
-        {
-            [Theory]
-            [MemberData(nameof(GetDateTimeOffsetsData), MemberType = typeof(Date32ArrayTests))]
-            public void AppendGivesUtcDate(DateTimeOffset dateTimeOffset)
-            {
-                // Arrange
-                var builder = new Date32Array.Builder();
-                var expectedDateTime = dateTimeOffset.UtcDateTime.Date;
-                var expectedDateTimeOffset = new DateTimeOffset(dateTimeOffset.UtcDateTime.Date, TimeSpan.Zero);
-                int expectedValue = (int)dateTimeOffset.UtcDateTime.Date.Subtract(new DateTime(1970, 1, 1)).TotalDays;
-
-                // Act
-                builder = builder.Append(dateTimeOffset);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(expectedDateTime, array.GetDateTime(0));
-                Assert.Equal(expectedDateTimeOffset, array.GetDateTimeOffset(0));
-                Assert.Equal(expectedValue, array.GetValue(0));
-            }
-        }
-
-#if NET6_0_OR_GREATER
-        public class AppendDateOnly
-        {
-            [Theory]
-            [MemberData(nameof(GetDateOnlyData), MemberType = typeof(Date32ArrayTests))]
-            public void AppendDateGivesSameDate(DateOnly date)
-            {
-                // Arrange
-                var builder = new Date32Array.Builder();
-                var expectedDateTime = date.ToDateTime(TimeOnly.MinValue);
-                var expectedDateTimeOffset = new DateTimeOffset(expectedDateTime, TimeSpan.Zero);
-                int expectedValue = date.DayNumber - new DateOnly(1970, 1, 1).DayNumber;
-
-                // Act
-                builder = builder.Append(date);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(date, array.GetDateOnly(0));
-                Assert.Equal(expectedDateTime, array.GetDateTime(0));
-                Assert.Equal(expectedDateTimeOffset, array.GetDateTimeOffset(0));
-                Assert.Equal(expectedValue, array.GetValue(0));
-            }
-        }
-#endif
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/Date64ArrayTests.cs b/csharp/test/Apache.Arrow.Tests/Date64ArrayTests.cs
deleted file mode 100644
index 22ae08a..0000000
--- a/csharp/test/Apache.Arrow.Tests/Date64ArrayTests.cs
+++ /dev/null
@@ -1,166 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class Date64ArrayTests
-    {
-        private const long MillisecondsPerDay = 86400000;
-
-        public static IEnumerable<object[]> GetDatesData() =>
-            TestDateAndTimeData.ExampleDates.Select(d => new object[] { d });
-
-        public static IEnumerable<object[]> GetDateTimesData() =>
-            TestDateAndTimeData.ExampleDateTimes.Select(dt => new object[] { dt });
-
-        public static IEnumerable<object[]> GetDateTimeOffsetsData() =>
-            TestDateAndTimeData.ExampleDateTimeOffsets.Select(dto => new object[] { dto });
-
-#if NET6_0_OR_GREATER
-        public static IEnumerable<object[]> GetDateOnlyData() =>
-            TestDateAndTimeData.ExampleDates.Select(d => new object[] { DateOnly.FromDateTime(d) });
-#endif
-
-        public class AppendNull
-        {
-            [Fact]
-            public void AppendThenGetGivesNull()
-            {
-                // Arrange
-                var builder = new Date64Array.Builder();
-
-                // Act
-                builder = builder.AppendNull();
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Null(array.GetDateTime(0));
-                Assert.Null(array.GetDateTimeOffset(0));
-                Assert.Null(array.GetValue(0));
-            }
-        }
-
-        public class AppendDateTime
-        {
-            [Theory]
-            [MemberData(nameof(GetDatesData), MemberType = typeof(Date64ArrayTests))]
-            public void AppendDateGivesSameDate(DateTime date)
-            {
-                // Arrange
-                var builder = new Date64Array.Builder();
-                var expectedDateTime = date;
-                var expectedDateTimeOffset =
-                    new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Unspecified), TimeSpan.Zero);
-                long expectedValue = (long)date.Subtract(new DateTime(1970, 1, 1)).TotalDays * MillisecondsPerDay;
-
-                // Act
-                builder = builder.Append(date);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(expectedDateTime, array.GetDateTime(0));
-                Assert.Equal(expectedDateTimeOffset, array.GetDateTimeOffset(0));
-                Assert.Equal(expectedValue, array.GetValue(0));
-                Assert.Equal(0, array.GetValue(0).Value % MillisecondsPerDay);
-            }
-
-            [Theory]
-            [MemberData(nameof(GetDateTimesData), MemberType = typeof(Date64ArrayTests))]
-            public void AppendWithTimeGivesSameWithTimeIgnored(DateTime dateTime)
-            {
-                // Arrange
-                var builder = new Date64Array.Builder();
-                var expectedDateTime = dateTime.Date;
-                var expectedDateTimeOffset =
-                    new DateTimeOffset(DateTime.SpecifyKind(dateTime.Date, DateTimeKind.Unspecified), TimeSpan.Zero);
-                long expectedValue =
-                    (long)dateTime.Date.Subtract(new DateTime(1970, 1, 1)).TotalDays * MillisecondsPerDay;
-
-                // Act
-                builder = builder.Append(dateTime);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(expectedDateTime, array.GetDateTime(0));
-                Assert.Equal(expectedDateTimeOffset, array.GetDateTimeOffset(0));
-                Assert.Equal(expectedValue, array.GetValue(0));
-                Assert.Equal(0, array.GetValue(0).Value % MillisecondsPerDay);
-            }
-        }
-
-        public class AppendDateTimeOffset
-        {
-            [Theory]
-            [MemberData(nameof(GetDateTimeOffsetsData), MemberType = typeof(Date64ArrayTests))]
-            public void AppendGivesUtcDate(DateTimeOffset dateTimeOffset)
-            {
-                // Arrange
-                var builder = new Date64Array.Builder();
-                var expectedDateTime = dateTimeOffset.UtcDateTime.Date;
-                var expectedDateTimeOffset = new DateTimeOffset(dateTimeOffset.UtcDateTime.Date, TimeSpan.Zero);
-                long expectedValue =
-                    (long)dateTimeOffset.UtcDateTime.Date.Subtract(new DateTime(1970, 1, 1)).TotalDays *
-                    MillisecondsPerDay;
-
-                // Act
-                builder = builder.Append(dateTimeOffset);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(expectedDateTime, array.GetDateTime(0));
-                Assert.Equal(expectedDateTimeOffset, array.GetDateTimeOffset(0));
-                Assert.Equal(expectedValue, array.GetValue(0));
-                Assert.Equal(0, array.GetValue(0).Value % MillisecondsPerDay);
-            }
-        }
-
-#if NET6_0_OR_GREATER
-        public class AppendDateOnly
-        {
-            [Theory]
-            [MemberData(nameof(GetDateOnlyData), MemberType = typeof(Date64ArrayTests))]
-            public void AppendDateGivesSameDate(DateOnly date)
-            {
-                // Arrange
-                var builder = new Date64Array.Builder();
-                var expectedDateTime = date.ToDateTime(TimeOnly.MinValue);
-                var expectedDateTimeOffset = new DateTimeOffset(expectedDateTime, TimeSpan.Zero);
-                long expectedValue = (date.DayNumber - new DateOnly(1970, 1, 1).DayNumber) * MillisecondsPerDay;
-
-                // Act
-                builder = builder.Append(date);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(date, array.GetDateOnly(0));
-                Assert.Equal(expectedDateTime, array.GetDateTime(0));
-                Assert.Equal(expectedDateTimeOffset, array.GetDateTimeOffset(0));
-                Assert.Equal(expectedValue, array.GetValue(0));
-                Assert.Equal(0, array.GetValue(0).Value % MillisecondsPerDay);
-            }
-        }
-#endif
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/Decimal128ArrayTests.cs b/csharp/test/Apache.Arrow.Tests/Decimal128ArrayTests.cs
deleted file mode 100644
index c5e0647..0000000
--- a/csharp/test/Apache.Arrow.Tests/Decimal128ArrayTests.cs
+++ /dev/null
@@ -1,505 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Data.SqlTypes;
-using System.Linq;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class Decimal128ArrayTests
-    {
-        static SqlDecimal? Convert(decimal? value)
-        {
-            return value == null ? null : new SqlDecimal(value.Value);
-        }
-
-        static decimal? Convert(SqlDecimal? value)
-        {
-            return value == null ? null : value.Value.Value;
-        }
-
-        public class Builder
-        {
-            public class AppendNull
-            {
-                [Fact]
-                public void AppendThenGetGivesNull()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(8, 2));
-
-                    // Act
-
-                    builder = builder.AppendNull();
-                    builder = builder.AppendNull();
-                    builder = builder.AppendNull();
-                    // Assert
-                    var array = builder.Build();
-
-                    Assert.Equal(3, array.Length);
-                    Assert.Equal(array.Data.Buffers[1].Length, array.ByteWidth * 3);
-                    Assert.Null(array.GetValue(0));
-                    Assert.Null(array.GetValue(1));
-                    Assert.Null(array.GetValue(2));
-
-                    Assert.Null(array.GetSqlDecimal(0));
-                    Assert.Null(array.GetSqlDecimal(1));
-                    Assert.Null(array.GetSqlDecimal(2));
-                }
-            }
-
-            public class Append
-            {
-                [Theory]
-                [InlineData(200)]
-                public void AppendDecimal(int count)
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(14, 10));
-
-                    // Act
-                    decimal?[] testData = new decimal?[count];
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (i == count - 2)
-                        {
-                            builder.AppendNull();
-                            testData[i] = null;
-                            continue;
-                        }
-                        decimal rnd = i * (decimal)Math.Round(new Random().NextDouble(), 10);
-                        testData[i] = rnd;
-                        builder.Append(rnd);
-                    }
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(count, array.Length);
-                    for (int i = 0; i < count; i++)
-                    {
-                        Assert.Equal(testData[i], array.GetValue(i));
-                        Assert.Equal(Convert(testData[i]), array.GetSqlDecimal(i));
-                    }
-                }
-
-                [Fact]
-                public void AppendLargeDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(26, 2));
-                    decimal large = 999999999999909999999999.80M;
-                    // Act
-                    builder.Append(large);
-                    builder.Append(-large);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(large, array.GetValue(0));
-                    Assert.Equal(-large, array.GetValue(1));
-
-                    Assert.Equal(Convert(large), array.GetSqlDecimal(0));
-                    Assert.Equal(Convert(-large), array.GetSqlDecimal(1));
-                }
-
-                [Fact]
-                public void AppendMaxAndMinDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(29, 0));
-
-                    // Act
-                    builder.Append(Decimal.MaxValue);
-                    builder.Append(Decimal.MinValue);
-                    builder.Append(Decimal.MaxValue - 10);
-                    builder.Append(Decimal.MinValue + 10);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(Decimal.MaxValue, array.GetValue(0));
-                    Assert.Equal(Decimal.MinValue, array.GetValue(1));
-                    Assert.Equal(Decimal.MaxValue - 10, array.GetValue(2));
-                    Assert.Equal(Decimal.MinValue + 10, array.GetValue(3));
-
-                    Assert.Equal(Convert(Decimal.MaxValue), array.GetSqlDecimal(0));
-                    Assert.Equal(Convert(Decimal.MinValue), array.GetSqlDecimal(1));
-                    Assert.Equal(Convert(Decimal.MaxValue) - 10, array.GetSqlDecimal(2));
-                    Assert.Equal(Convert(Decimal.MinValue) + 10, array.GetSqlDecimal(3));
-                }
-
-                [Fact]
-                public void AppendFractionalDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(26, 20));
-                    decimal fraction = 0.99999999999990999992M;
-                    // Act
-                    builder.Append(fraction);
-                    builder.Append(-fraction);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(fraction, array.GetValue(0));
-                    Assert.Equal(-fraction, array.GetValue(1));
-
-                    Assert.Equal(Convert(fraction), array.GetSqlDecimal(0));
-                    Assert.Equal(Convert(-fraction), array.GetSqlDecimal(1));
-                }
-
-                [Fact]
-                public void AppendRangeDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(24, 8));
-                    var range = new decimal[] { 2.123M, 1.5984M, -0.0000001M, 9878987987987987.1235407M };
-
-                    // Act
-                    builder.AppendRange(range);
-                    builder.AppendNull();
-
-                    // Assert
-                    var array = builder.Build();
-                    for (int i = 0; i < range.Length; i++)
-                    {
-                        Assert.Equal(range[i], array.GetValue(i));
-                        Assert.Equal(Convert(range[i]), array.GetSqlDecimal(i));
-                    }
-
-                    Assert.Null(array.GetValue(range.Length));
-                }
-
-                [Fact]
-                public void AppendClearAppendDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(24, 8));
-
-                    // Act
-                    builder.Append(1);
-                    builder.Clear();
-                    builder.Append(10);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(10, array.GetValue(0));
-                }
-
-                [Fact]
-                public void AppendInvalidPrecisionAndScaleDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(2, 1));
-
-                    // Assert
-                    Assert.Throws<OverflowException>(() => builder.Append(100));
-                    Assert.Throws<OverflowException>(() => builder.Append(0.01M));
-                    builder.Append(-9.9M);
-                    builder.Append(0);
-                    builder.Append(9.9M);
-                }
-            }
-
-            public class Set
-            {
-                [Fact]
-                public void SetDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(24, 8))
-                        .Resize(1);
-
-                    // Act
-                    builder.Set(0, 50.123456M);
-                    builder.Set(0, 1.01M);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(1.01M, array.GetValue(0));
-                }
-
-                [Fact]
-                public void SetNull()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(24, 8))
-                        .Resize(1);
-
-                    // Act
-                    builder.Set(0, 50.123456M);
-                    builder.SetNull(0);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Null(array.GetValue(0));
-                }
-            }
-
-            public class Swap
-            {
-                [Fact]
-                public void SetDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(24, 8));
-
-                    // Act
-                    builder.Append(123.45M);
-                    builder.Append(678.9M);
-                    builder.Swap(0, 1);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(678.9M, array.GetValue(0));
-                    Assert.Equal(123.45M, array.GetValue(1));
-                }
-
-                [Fact]
-                public void SwapNull()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(24, 8));
-
-                    // Act
-                    builder.Append(123.456M);
-                    builder.AppendNull();
-                    builder.Swap(0, 1);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Null(array.GetValue(0));
-                    Assert.Equal(123.456M, array.GetValue(1));
-                }
-            }
-
-            public class SqlDecimals
-            {
-                [Theory]
-                [InlineData(200)]
-                public void AppendSqlDecimal(int count)
-                {
-                    // Arrange
-                    const int precision = 10;
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(14, precision));
-
-                    // Act
-                    SqlDecimal?[] testData = new SqlDecimal?[count];
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (i == count - 2)
-                        {
-                            builder.AppendNull();
-                            testData[i] = null;
-                            continue;
-                        }
-                        SqlDecimal rnd = i * (SqlDecimal)Math.Round(new Random().NextDouble(), 10);
-                        builder.Append(rnd);
-                        testData[i] = SqlDecimal.Round(rnd, precision);
-                    }
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(count, array.Length);
-                    for (int i = 0; i < count; i++)
-                    {
-                        Assert.Equal(testData[i], array.GetSqlDecimal(i));
-                        Assert.Equal(Convert(testData[i]), array.GetValue(i));
-                    }
-
-                    IReadOnlyList<SqlDecimal?> asList = array;
-                    for (int i = 0; i < asList.Count; i++)
-                    {
-                        Assert.Equal(testData[i], asList[i]);
-                    }
-                }
-
-                [Fact]
-                public void AppendMaxAndMinSqlDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(38, 0));
-
-                    // Act
-                    builder.Append(SqlDecimal.MaxValue);
-                    builder.Append(SqlDecimal.MinValue);
-                    builder.Append(SqlDecimal.MaxValue - 10);
-                    builder.Append(SqlDecimal.MinValue + 10);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(SqlDecimal.MaxValue, array.GetSqlDecimal(0));
-                    Assert.Equal(SqlDecimal.MinValue, array.GetSqlDecimal(1));
-                    Assert.Equal(SqlDecimal.MaxValue - 10, array.GetSqlDecimal(2));
-                    Assert.Equal(SqlDecimal.MinValue + 10, array.GetSqlDecimal(3));
-                }
-
-                [Fact]
-                public void AppendRangeSqlDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(24, 8));
-                    var range = new SqlDecimal[] { 2.123M, 1.5984M, -0.0000001M, 9878987987987987.1235407M };
-
-                    // Act
-                    builder.AppendRange(range);
-                    builder.AppendNull();
-
-                    // Assert
-                    var array = builder.Build();
-                    for (int i = 0; i < range.Length; i++)
-                    {
-                        Assert.Equal(range[i], array.GetSqlDecimal(i));
-                        Assert.Equal(Convert(range[i]), array.GetValue(i));
-                    }
-
-                    Assert.Null(array.GetValue(range.Length));
-                }
-            }
-
-            public class Strings
-            {
-                [Theory]
-                [InlineData(200)]
-                public void AppendString(int count)
-                {
-                    // Arrange
-                    const int precision = 10;
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(14, precision));
-
-                    // Act
-                    string[] testData = new string[count];
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (i == count - 2)
-                        {
-                            builder.AppendNull();
-                            testData[i] = null;
-                            continue;
-                        }
-                        SqlDecimal rnd = i * (SqlDecimal)Math.Round(new Random().NextDouble(), 10);
-                        builder.Append(rnd);
-                        testData[i] = SqlDecimal.Round(rnd, precision).ToString();
-                    }
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(count, array.Length);
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (testData[i] == null)
-                        {
-                            Assert.Null(array.GetString(i));
-                            Assert.Null(array.GetSqlDecimal(i));
-                        }
-                        else
-                        {
-                            Assert.Equal(testData[i].TrimEnd('0'), array.GetString(i).TrimEnd('0'));
-                            Assert.Equal(SqlDecimal.Parse(testData[i]), array.GetSqlDecimal(i));
-                        }
-                    }
-                }
-
-                [Fact]
-                public void AppendMaxAndMinSqlDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(38, 0));
-
-                    // Act
-                    builder.Append(SqlDecimal.MaxValue.ToString());
-                    builder.Append(SqlDecimal.MinValue.ToString());
-                    string maxMinusTen = (SqlDecimal.MaxValue - 10).ToString();
-                    string minPlusTen = (SqlDecimal.MinValue + 10).ToString();
-                    builder.Append(maxMinusTen);
-                    builder.Append(minPlusTen);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(SqlDecimal.MaxValue.ToString(), array.GetString(0));
-                    Assert.Equal(SqlDecimal.MinValue.ToString(), array.GetString(1));
-                    Assert.Equal(maxMinusTen, array.GetString(2));
-                    Assert.Equal(minPlusTen, array.GetString(3));
-                }
-
-                [Fact]
-                public void AppendRangeSqlDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal128Array.Builder(new Decimal128Type(24, 8));
-                    var range = new SqlDecimal[] { 2.123M, 1.5984M, -0.0000001M, 9878987987987987.1235407M };
-
-                    // Act
-                    builder.AppendRange(range.Select(d => d.ToString()));
-                    builder.AppendNull();
-
-                    // Assert
-                    var array = builder.Build();
-                    for (int i = 0; i < range.Length; i++)
-                    {
-                        Assert.Equal(range[i], array.GetSqlDecimal(i));
-                        Assert.Equal(range[i].ToString(), array.GetString(i).TrimEnd('0'));
-                    }
-
-                    Assert.Null(array.GetValue(range.Length));
-                }
-            }
-        }
-
-        [Fact]
-        public void SliceDecimal128Array()
-        {
-            // Arrange
-            const int originalLength = 50;
-            const int offset = 3;
-            const int sliceLength = 32;
-
-            var builder = new Decimal128Array.Builder(new Decimal128Type(14, 10));
-            var random = new Random();
-
-            for (int i = 0; i < originalLength; i++)
-            {
-                if (random.NextDouble() < 0.2)
-                {
-                    builder.AppendNull();
-                }
-                else
-                {
-                    builder.Append(i * (decimal)Math.Round(random.NextDouble(), 10));
-                }
-            }
-
-            var array = builder.Build();
-
-            // Act
-            var slice = (Decimal128Array)array.Slice(offset, sliceLength);
-
-            // Assert
-            Assert.NotNull(slice);
-            Assert.Equal(sliceLength, slice.Length);
-            for (int i = 0; i < sliceLength; ++i)
-            {
-                Assert.Equal(array.GetValue(offset + i), slice.GetValue(i));
-                Assert.Equal(array.GetSqlDecimal(offset + i), slice.GetSqlDecimal(i));
-                Assert.Equal(array.GetString(offset + i), slice.GetString(i));
-            }
-
-            Assert.Equal(
-                array.ToList(includeNulls: true).Skip(offset).Take(sliceLength).ToList(),
-                slice.ToList(includeNulls: true));
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/Decimal256ArrayTests.cs b/csharp/test/Apache.Arrow.Tests/Decimal256ArrayTests.cs
deleted file mode 100644
index ba0eb5f..0000000
--- a/csharp/test/Apache.Arrow.Tests/Decimal256ArrayTests.cs
+++ /dev/null
@@ -1,531 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Data.SqlTypes;
-using System.Linq;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class Decimal256ArrayTests
-    {
-        static SqlDecimal? GetSqlDecimal(Decimal256Array array, int index)
-        {
-            SqlDecimal? result;
-            Assert.True(array.TryGetSqlDecimal(index, out result));
-            return result;
-        }
-
-        static SqlDecimal? Convert(decimal? value)
-        {
-            return value == null ? null : new SqlDecimal(value.Value);
-        }
-
-        static decimal? Convert(SqlDecimal? value)
-        {
-            return value == null ? null : value.Value.Value;
-        }
-
-        static decimal? Convert(string value)
-        {
-            return value == null ? null : decimal.Parse(value);
-        }
-
-        public class Builder
-        {
-            public class AppendNull
-            {
-                [Fact]
-                public void AppendThenGetGivesNull()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(8,2));
-
-                    // Act
-
-                    builder = builder.AppendNull();
-                    builder = builder.AppendNull();
-                    builder = builder.AppendNull();
-                    // Assert
-                    var array = builder.Build();
-
-                    Assert.Equal(3, array.Length);
-                    Assert.Equal(array.Data.Buffers[1].Length, array.ByteWidth * 3);
-                    Assert.Null(array.GetValue(0));
-                    Assert.Null(array.GetValue(1));
-                    Assert.Null(array.GetValue(2));
-
-                    Assert.Null(GetSqlDecimal(array, 0));
-                    Assert.Null(GetSqlDecimal(array, 1));
-                    Assert.Null(GetSqlDecimal(array, 2));
-                }
-            }
-
-            public class Append
-            {
-                [Theory]
-                [InlineData(200)]
-                public void AppendDecimal(int count)
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(14, 10));
-
-                    // Act
-                    decimal?[] testData = new decimal?[count];
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (i == count - 2)
-                        {
-                            builder.AppendNull();
-                            testData[i] = null;
-                            continue;
-                        }
-                        decimal rnd = i * (decimal)Math.Round(new Random().NextDouble(),10);
-                        testData[i] = rnd;
-                        builder.Append(rnd);
-                    }
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(count, array.Length);
-                    for (int i = 0; i < count; i++)
-                    {
-                        Assert.Equal(testData[i], array.GetValue(i));
-                        Assert.Equal(Convert(testData[i]), GetSqlDecimal(array, i));
-                    }
-                }
-
-                [Fact]
-                public void AppendLargeDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(26, 2));
-                    decimal large = 999999999999909999999999.80M;
-                    // Act
-                    builder.Append(large);
-                    builder.Append(-large);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(large, array.GetValue(0));
-                    Assert.Equal(-large, array.GetValue(1));
-
-                    Assert.Equal(Convert(large), GetSqlDecimal(array, 0));
-                    Assert.Equal(Convert(-large), GetSqlDecimal(array, 1));
-                }
-
-                [Fact]
-                public void AppendMaxAndMinDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(29, 0));
-
-                    // Act
-                    builder.Append(Decimal.MaxValue);
-                    builder.Append(Decimal.MinValue);
-                    builder.Append(Decimal.MaxValue - 10);
-                    builder.Append(Decimal.MinValue + 10);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(Decimal.MaxValue, array.GetValue(0));
-                    Assert.Equal(Decimal.MinValue, array.GetValue(1));
-                    Assert.Equal(Decimal.MaxValue - 10, array.GetValue(2));
-                    Assert.Equal(Decimal.MinValue + 10, array.GetValue(3));
-
-                    Assert.Equal(Convert(Decimal.MaxValue), GetSqlDecimal(array, 0));
-                    Assert.Equal(Convert(Decimal.MinValue), GetSqlDecimal(array, 1));
-                    Assert.Equal(Convert(Decimal.MaxValue) - 10, GetSqlDecimal(array, 2));
-                    Assert.Equal(Convert(Decimal.MinValue) + 10, GetSqlDecimal(array, 3));
-                }
-
-                [Fact]
-                public void AppendFractionalDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(26, 20));
-                    decimal fraction = 0.99999999999990999992M;
-                    // Act
-                    builder.Append(fraction);
-                    builder.Append(-fraction);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(fraction, array.GetValue(0));
-                    Assert.Equal(-fraction, array.GetValue(1));
-
-                    Assert.Equal(Convert(fraction), GetSqlDecimal(array, 0));
-                    Assert.Equal(Convert(-fraction), GetSqlDecimal(array, 1));
-                }
-
-                [Fact]
-                public void AppendRangeDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(24, 8));
-                    var range = new decimal[] {2.123M, 1.5984M, -0.0000001M, 9878987987987987.1235407M};
-
-                    // Act
-                    builder.AppendRange(range);
-                    builder.AppendNull();
-
-                    // Assert
-                    var array = builder.Build();
-                    for(int i = 0; i < range.Length; i ++)
-                    {
-                        Assert.Equal(range[i], array.GetValue(i));
-                        Assert.Equal(Convert(range[i]), GetSqlDecimal(array, i));
-                    }
-
-                    Assert.Null( array.GetValue(range.Length));
-                }
-
-                [Fact]
-                public void AppendClearAppendDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(24, 8));
-                    
-                    // Act
-                    builder.Append(1);
-                    builder.Clear();
-                    builder.Append(10);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(10, array.GetValue(0));
-                }
-
-                [Fact]
-                public void AppendInvalidPrecisionAndScaleDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(2, 1));
-
-                    // Assert
-                    Assert.Throws<OverflowException>(() => builder.Append(100));
-                    Assert.Throws<OverflowException>(() => builder.Append(0.01M));
-                    builder.Append(-9.9M);
-                    builder.Append(0);
-                    builder.Append(9.9M);
-                }
-            }
-
-            public class Set
-            {
-                [Fact]
-                public void SetDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(24, 8))
-                        .Resize(1);
-                    
-                    // Act
-                    builder.Set(0, 50.123456M);
-                    builder.Set(0, 1.01M);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(1.01M, array.GetValue(0));
-                }
-
-                [Fact]
-                public void SetNull()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(24, 8))
-                        .Resize(1);
-
-                    // Act
-                    builder.Set(0, 50.123456M);
-                    builder.SetNull(0);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Null(array.GetValue(0));
-                }
-            }
-
-            public class Swap
-            {
-                [Fact]
-                public void SetDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(24, 8));
-
-                    // Act
-                    builder.Append(123.45M);
-                    builder.Append(678.9M);
-                    builder.Swap(0, 1);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(678.9M, array.GetValue(0));
-                    Assert.Equal(123.45M, array.GetValue(1));
-                }
-
-                [Fact]
-                public void SwapNull()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(24, 8));
-
-                    // Act
-                    builder.Append(123.456M);
-                    builder.AppendNull();
-                    builder.Swap(0, 1);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Null(array.GetValue(0));
-                    Assert.Equal(123.456M, array.GetValue(1));
-                }
-            }
-
-            public class SqlDecimals
-            {
-                [Theory]
-                [InlineData(200)]
-                public void AppendSqlDecimal(int count)
-                {
-                    // Arrange
-                    const int precision = 10;
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(14, precision));
-
-                    // Act
-                    SqlDecimal?[] testData = new SqlDecimal?[count];
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (i == count - 2)
-                        {
-                            builder.AppendNull();
-                            testData[i] = null;
-                            continue;
-                        }
-                        SqlDecimal rnd = i * (SqlDecimal)Math.Round(new Random().NextDouble(), 10);
-                        builder.Append(rnd);
-                        testData[i] = SqlDecimal.Round(rnd, precision);
-                    }
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(count, array.Length);
-                    for (int i = 0; i < count; i++)
-                    {
-                        Assert.Equal(testData[i], GetSqlDecimal(array, i));
-                        Assert.Equal(Convert(testData[i]), array.GetValue(i));
-                    }
-
-                    IReadOnlyList<SqlDecimal?> asDecimalList = array;
-                    for (int i = 0; i < asDecimalList.Count; i++)
-                    {
-                        Assert.Equal(testData[i], asDecimalList[i]);
-                    }
-
-                    IReadOnlyList<string> asStringList = array;
-                    for (int i = 0; i < asStringList.Count; i++)
-                    {
-                        Assert.Equal(Convert(testData[i]?.ToString()), Convert(asStringList[i]));
-                    }
-                }
-
-                [Fact]
-                public void AppendMaxAndMinSqlDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(38, 0));
-
-                    // Act
-                    builder.Append(SqlDecimal.MaxValue);
-                    builder.Append(SqlDecimal.MinValue);
-                    builder.Append(SqlDecimal.MaxValue - 10);
-                    builder.Append(SqlDecimal.MinValue + 10);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(SqlDecimal.MaxValue, GetSqlDecimal(array, 0));
-                    Assert.Equal(SqlDecimal.MinValue, GetSqlDecimal(array, 1));
-                    Assert.Equal(SqlDecimal.MaxValue - 10, GetSqlDecimal(array, 2));
-                    Assert.Equal(SqlDecimal.MinValue + 10, GetSqlDecimal(array, 3));
-                }
-
-                [Fact]
-                public void AppendRangeSqlDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(24, 8));
-                    var range = new SqlDecimal[] { 2.123M, 1.5984M, -0.0000001M, 9878987987987987.1235407M };
-
-                    // Act
-                    builder.AppendRange(range);
-                    builder.AppendNull();
-
-                    // Assert
-                    var array = builder.Build();
-                    for (int i = 0; i < range.Length; i++)
-                    {
-                        Assert.Equal(range[i], GetSqlDecimal(array, i));
-                        Assert.Equal(Convert(range[i]), array.GetValue(i));
-                    }
-
-                    Assert.Null(array.GetValue(range.Length));
-                }
-            }
-
-            public class Strings
-            {
-                [Theory]
-                [InlineData(200)]
-                public void AppendString(int count)
-                {
-                    // Arrange
-                    const int precision = 10;
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(14, precision));
-
-                    // Act
-                    string[] testData = new string[count];
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (i == count - 2)
-                        {
-                            builder.AppendNull();
-                            testData[i] = null;
-                            continue;
-                        }
-                        SqlDecimal rnd = i * (SqlDecimal)Math.Round(new Random().NextDouble(), 10);
-                        builder.Append(rnd);
-                        testData[i] = SqlDecimal.Round(rnd, precision).ToString();
-                    }
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(count, array.Length);
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (testData[i] == null)
-                        {
-                            Assert.Null(array.GetString(i));
-                            Assert.Null(GetSqlDecimal(array, i));
-                        }
-                        else
-                        {
-                            Assert.Equal(testData[i].TrimEnd('0'), array.GetString(i).TrimEnd('0'));
-                            Assert.Equal(SqlDecimal.Parse(testData[i]), GetSqlDecimal(array, i));
-                        }
-                    }
-                }
-
-                [Fact]
-                public void AppendMaxAndMinSqlDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(38, 0));
-
-                    // Act
-                    builder.Append(SqlDecimal.MaxValue.ToString());
-                    builder.Append(SqlDecimal.MinValue.ToString());
-                    string maxMinusTen = (SqlDecimal.MaxValue - 10).ToString();
-                    string minPlusTen = (SqlDecimal.MinValue + 10).ToString();
-                    builder.Append(maxMinusTen);
-                    builder.Append(minPlusTen);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(SqlDecimal.MaxValue.ToString(), array.GetString(0));
-                    Assert.Equal(SqlDecimal.MinValue.ToString(), array.GetString(1));
-                    Assert.Equal(maxMinusTen, array.GetString(2));
-                    Assert.Equal(minPlusTen, array.GetString(3));
-                }
-
-                [Fact]
-                public void AppendRangeSqlDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal256Array.Builder(new Decimal256Type(24, 8));
-                    var range = new SqlDecimal[] { 2.123M, 1.5984M, -0.0000001M, 9878987987987987.1235407M };
-
-                    // Act
-                    builder.AppendRange(range.Select(d => d.ToString()));
-                    builder.AppendNull();
-
-                    // Assert
-                    var array = builder.Build();
-                    for (int i = 0; i < range.Length; i++)
-                    {
-                        Assert.Equal(range[i], GetSqlDecimal(array, i));
-                        Assert.Equal(range[i].ToString().TrimEnd('0'), array.GetString(i).TrimEnd('0'));
-                    }
-
-                    Assert.Null(array.GetValue(range.Length));
-                }
-            }
-        }
-
-        [Fact]
-        public void SliceDecimal256Array()
-        {
-            // Arrange
-            const int originalLength = 50;
-            const int offset = 3;
-            const int sliceLength = 32;
-
-            var builder = new Decimal256Array.Builder(new Decimal256Type(14, 10));
-            var random = new Random();
-
-            for (int i = 0; i < originalLength; i++)
-            {
-                if (random.NextDouble() < 0.2)
-                {
-                    builder.AppendNull();
-                }
-                else
-                {
-                    builder.Append(i * (decimal)Math.Round(random.NextDouble(), 10));
-                }
-            }
-
-            var array = builder.Build();
-
-            // Act
-            var slice = (Decimal256Array)array.Slice(offset, sliceLength);
-
-            // Assert
-            Assert.NotNull(slice);
-            Assert.Equal(sliceLength, slice.Length);
-            for (int i = 0; i < sliceLength; ++i)
-            {
-                Assert.Equal(array.GetValue(offset + i), slice.GetValue(i));
-                if (array.TryGetSqlDecimal(offset + i, out var expectedSqlDecimal))
-                {
-                    Assert.True(slice.TryGetSqlDecimal(i, out var actualSqlDecimal));
-                    Assert.Equal(expectedSqlDecimal, actualSqlDecimal);
-                }
-                else
-                {
-                    Assert.False(slice.TryGetSqlDecimal(i, out _));
-                }
-                Assert.Equal(array.GetString(offset + i), slice.GetString(i));
-            }
-
-            Assert.Equal(
-                array.ToList(includeNulls: true).Skip(offset).Take(sliceLength).ToList(),
-                slice.ToList(includeNulls: true));
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/Decimal32ArrayTests.cs b/csharp/test/Apache.Arrow.Tests/Decimal32ArrayTests.cs
deleted file mode 100644
index f7b7d40..0000000
--- a/csharp/test/Apache.Arrow.Tests/Decimal32ArrayTests.cs
+++ /dev/null
@@ -1,337 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Linq;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class Decimal32ArrayTests
-    {
-        public class Builder
-        {
-            public class AppendNull
-            {
-                [Fact]
-                public void AppendThenGetGivesNull()
-                {
-                    // Arrange
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(7, 3));
-
-                    // Act
-
-                    builder = builder.AppendNull();
-                    builder = builder.AppendNull();
-                    builder = builder.AppendNull();
-                    // Assert
-                    var array = builder.Build();
-
-                    Assert.Equal(3, array.Length);
-                    Assert.Equal(array.Data.Buffers[1].Length, array.ByteWidth * 3);
-                    Assert.Null(array.GetValue(0));
-                    Assert.Null(array.GetValue(1));
-                    Assert.Null(array.GetValue(2));
-                }
-            }
-
-            public class Append
-            {
-                [Theory]
-                [InlineData(200)]
-                public void AppendDecimal(int count)
-                {
-                    // Arrange
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(7, 3));
-
-                    // Act
-                    decimal?[] testData = new decimal?[count];
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (i == count - 2)
-                        {
-                            builder.AppendNull();
-                            testData[i] = null;
-                            continue;
-                        }
-                        decimal rnd = i * (decimal)Math.Round(new Random().NextDouble(), 2);
-                        testData[i] = rnd;
-                        builder.Append(rnd);
-                    }
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(count, array.Length);
-                    for (int i = 0; i < count; i++)
-                    {
-                        Assert.Equal(testData[i], array.GetValue(i));
-                    }
-                }
-
-                [Fact]
-                public void AppendLargeDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(7, 3));
-                    decimal large = 9999.999M;
-                    // Act
-                    builder.Append(large);
-                    builder.Append(-large);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(large, array.GetValue(0));
-                    Assert.Equal(-large, array.GetValue(1));
-                }
-
-                [Fact]
-                public void AppendFractionalDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(9, 9));
-                    decimal fraction = 0.999999999M;
-                    // Act
-                    builder.Append(fraction);
-                    builder.Append(-fraction);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(fraction, array.GetValue(0));
-                    Assert.Equal(-fraction, array.GetValue(1));
-                }
-
-                [Fact]
-                public void AppendRangeDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(7, 3));
-                    var range = new decimal[] { 2.123M, 1.598M, -0.001M, 7987.123M };
-
-                    // Act
-                    builder.AppendRange(range);
-                    builder.AppendNull();
-
-                    // Assert
-                    var array = builder.Build();
-                    for (int i = 0; i < range.Length; i++)
-                    {
-                        Assert.Equal(range[i], array.GetValue(i));
-                    }
-
-                    Assert.Null(array.GetValue(range.Length));
-                }
-
-                [Fact]
-                public void AppendClearAppendDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(7, 3));
-
-                    // Act
-                    builder.Append(1);
-                    builder.Clear();
-                    builder.Append(10);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(10, array.GetValue(0));
-                }
-
-                [Fact]
-                public void AppendInvalidPrecisionAndScaleDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(2, 1));
-
-                    // Assert
-                    Assert.Throws<OverflowException>(() => builder.Append(100));
-                    Assert.Throws<OverflowException>(() => builder.Append(0.01M));
-                    builder.Append(-9.9M);
-                    builder.Append(0);
-                    builder.Append(9.9M);
-                }
-            }
-
-            public class Set
-            {
-                [Fact]
-                public void SetDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(7, 3))
-                        .Resize(1);
-
-                    // Act
-                    builder.Set(0, 50.123M);
-                    builder.Set(0, 1.01M);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(1.01M, array.GetValue(0));
-                }
-
-                [Fact]
-                public void SetNull()
-                {
-                    // Arrange
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(7, 3))
-                        .Resize(1);
-
-                    // Act
-                    builder.Set(0, 50.123M);
-                    builder.SetNull(0);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Null(array.GetValue(0));
-                }
-            }
-
-            public class Swap
-            {
-                [Fact]
-                public void SetDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(7, 3));
-
-                    // Act
-                    builder.Append(123.45M);
-                    builder.Append(678.9M);
-                    builder.Swap(0, 1);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(678.9M, array.GetValue(0));
-                    Assert.Equal(123.45M, array.GetValue(1));
-                }
-
-                [Fact]
-                public void SwapNull()
-                {
-                    // Arrange
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(7, 3));
-
-                    // Act
-                    builder.Append(123.456M);
-                    builder.AppendNull();
-                    builder.Swap(0, 1);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Null(array.GetValue(0));
-                    Assert.Equal(123.456M, array.GetValue(1));
-                }
-            }
-
-            public class Strings
-            {
-                [Theory]
-                [InlineData(200)]
-                public void AppendString(int count)
-                {
-                    // Arrange
-                    const int precision = 4;
-                    var builder = new Decimal32Array.Builder(new Decimal32Type(9, precision));
-
-                    // Act
-                    string[] testData = new string[count];
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (i == count - 2)
-                        {
-                            builder.AppendNull();
-                            testData[i] = null;
-                            continue;
-                        }
-                        decimal rnd = i * (decimal)Math.Round(new Random().NextDouble(), precision - 2);
-                        builder.Append(rnd);
-                        testData[i] = decimal.Round(rnd, precision - 1).ToString();
-                    }
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(count, array.Length);
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (testData[i] == null)
-                        {
-                            Assert.Null(array.GetString(i));
-                            Assert.Null(array.GetDecimal(i));
-                        }
-                        else
-                        {
-                            Assert.Equal(NormalizeNumber(testData[i]), NormalizeNumber(array.GetString(i)));
-                            Assert.Equal(Decimal.Parse(testData[i]), array.GetDecimal(i));
-                        }
-                    }
-                }
-
-                static string NormalizeNumber(string number)
-                {
-                    if (number.IndexOf('.') > 0)
-                    {
-                        number = number.TrimEnd('0');
-                        number = number.TrimEnd('.');
-                    }
-                    return number;
-                }
-            }
-        }
-
-        [Fact]
-        public void SliceDecimal32Array()
-        {
-            // Arrange
-            const int originalLength = 50;
-            const int offset = 3;
-            const int sliceLength = 32;
-
-            var builder = new Decimal32Array.Builder(new Decimal32Type(7, 3));
-            var random = new Random();
-
-            for (int i = 0; i < originalLength; i++)
-            {
-                if (random.NextDouble() < 0.2)
-                {
-                    builder.AppendNull();
-                }
-                else
-                {
-                    builder.Append(i * (decimal)Math.Round(random.NextDouble(), 2));
-                }
-            }
-
-            var array = builder.Build();
-
-            // Act
-            var slice = (Decimal32Array)array.Slice(offset, sliceLength);
-
-            // Assert
-            Assert.NotNull(slice);
-            Assert.Equal(sliceLength, slice.Length);
-            for (int i = 0; i < sliceLength; ++i)
-            {
-                Assert.Equal(array.GetValue(offset + i), slice.GetValue(i));
-                Assert.Equal(array.GetString(offset + i), slice.GetString(i));
-            }
-
-            Assert.Equal(
-                array.ToList(includeNulls: true).Skip(offset).Take(sliceLength).ToList(),
-                slice.ToList(includeNulls: true));
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/Decimal64ArrayTests.cs b/csharp/test/Apache.Arrow.Tests/Decimal64ArrayTests.cs
deleted file mode 100644
index b37a44a..0000000
--- a/csharp/test/Apache.Arrow.Tests/Decimal64ArrayTests.cs
+++ /dev/null
@@ -1,337 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Linq;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class Decimal64ArrayTests
-    {
-        public class Builder
-        {
-            public class AppendNull
-            {
-                [Fact]
-                public void AppendThenGetGivesNull()
-                {
-                    // Arrange
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(7, 3));
-
-                    // Act
-
-                    builder = builder.AppendNull();
-                    builder = builder.AppendNull();
-                    builder = builder.AppendNull();
-                    // Assert
-                    var array = builder.Build();
-
-                    Assert.Equal(3, array.Length);
-                    Assert.Equal(array.Data.Buffers[1].Length, array.ByteWidth * 3);
-                    Assert.Null(array.GetValue(0));
-                    Assert.Null(array.GetValue(1));
-                    Assert.Null(array.GetValue(2));
-                }
-            }
-
-            public class Append
-            {
-                [Theory]
-                [InlineData(200)]
-                public void AppendDecimal(int count)
-                {
-                    // Arrange
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(7, 3));
-
-                    // Act
-                    decimal?[] testData = new decimal?[count];
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (i == count - 2)
-                        {
-                            builder.AppendNull();
-                            testData[i] = null;
-                            continue;
-                        }
-                        decimal rnd = i * (decimal)Math.Round(new Random().NextDouble(), 2);
-                        testData[i] = rnd;
-                        builder.Append(rnd);
-                    }
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(count, array.Length);
-                    for (int i = 0; i < count; i++)
-                    {
-                        Assert.Equal(testData[i], array.GetValue(i));
-                    }
-                }
-
-                [Fact]
-                public void AppendLargeDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(19, 6));
-                    decimal large = 9199999999999.999999M;
-                    // Act
-                    builder.Append(large);
-                    builder.Append(-large);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(large, array.GetValue(0));
-                    Assert.Equal(-large, array.GetValue(1));
-                }
-
-                [Fact]
-                public void AppendFractionalDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(9, 9));
-                    decimal fraction = 0.999999999M;
-                    // Act
-                    builder.Append(fraction);
-                    builder.Append(-fraction);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(fraction, array.GetValue(0));
-                    Assert.Equal(-fraction, array.GetValue(1));
-                }
-
-                [Fact]
-                public void AppendRangeDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(17, 4));
-                    var range = new decimal[] { 2.123M, 12345678.598M, -0.001M, 7987.1237M };
-
-                    // Act
-                    builder.AppendRange(range);
-                    builder.AppendNull();
-
-                    // Assert
-                    var array = builder.Build();
-                    for (int i = 0; i < range.Length; i++)
-                    {
-                        Assert.Equal(range[i], array.GetValue(i));
-                    }
-
-                    Assert.Null(array.GetValue(range.Length));
-                }
-
-                [Fact]
-                public void AppendClearAppendDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(7, 3));
-
-                    // Act
-                    builder.Append(1);
-                    builder.Clear();
-                    builder.Append(10);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(10, array.GetValue(0));
-                }
-
-                [Fact]
-                public void AppendInvalidPrecisionAndScaleDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(2, 1));
-
-                    // Assert
-                    Assert.Throws<OverflowException>(() => builder.Append(100));
-                    Assert.Throws<OverflowException>(() => builder.Append(0.01M));
-                    builder.Append(-9.9M);
-                    builder.Append(0);
-                    builder.Append(9.9M);
-                }
-            }
-
-            public class Set
-            {
-                [Fact]
-                public void SetDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(7, 3))
-                        .Resize(1);
-
-                    // Act
-                    builder.Set(0, 50.123M);
-                    builder.Set(0, 1.01M);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(1.01M, array.GetValue(0));
-                }
-
-                [Fact]
-                public void SetNull()
-                {
-                    // Arrange
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(7, 3))
-                        .Resize(1);
-
-                    // Act
-                    builder.Set(0, 50.123M);
-                    builder.SetNull(0);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Null(array.GetValue(0));
-                }
-            }
-
-            public class Swap
-            {
-                [Fact]
-                public void SetDecimal()
-                {
-                    // Arrange
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(7, 3));
-
-                    // Act
-                    builder.Append(123.45M);
-                    builder.Append(678.9M);
-                    builder.Swap(0, 1);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(678.9M, array.GetValue(0));
-                    Assert.Equal(123.45M, array.GetValue(1));
-                }
-
-                [Fact]
-                public void SwapNull()
-                {
-                    // Arrange
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(7, 3));
-
-                    // Act
-                    builder.Append(123.456M);
-                    builder.AppendNull();
-                    builder.Swap(0, 1);
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Null(array.GetValue(0));
-                    Assert.Equal(123.456M, array.GetValue(1));
-                }
-            }
-
-            public class Strings
-            {
-                [Theory]
-                [InlineData(200)]
-                public void AppendString(int count)
-                {
-                    // Arrange
-                    const int precision = 4;
-                    var builder = new Decimal64Array.Builder(new Decimal64Type(9, precision));
-
-                    // Act
-                    string[] testData = new string[count];
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (i == count - 2)
-                        {
-                            builder.AppendNull();
-                            testData[i] = null;
-                            continue;
-                        }
-                        decimal rnd = i * (decimal)Math.Round(new Random().NextDouble(), precision - 2);
-                        builder.Append(rnd);
-                        testData[i] = decimal.Round(rnd, precision - 1).ToString();
-                    }
-
-                    // Assert
-                    var array = builder.Build();
-                    Assert.Equal(count, array.Length);
-                    for (int i = 0; i < count; i++)
-                    {
-                        if (testData[i] == null)
-                        {
-                            Assert.Null(array.GetString(i));
-                            Assert.Null(array.GetDecimal(i));
-                        }
-                        else
-                        {
-                            Assert.Equal(NormalizeNumber(testData[i]), NormalizeNumber(array.GetString(i)));
-                            Assert.Equal(Decimal.Parse(testData[i]), array.GetDecimal(i));
-                        }
-                    }
-                }
-
-                static string NormalizeNumber(string number)
-                {
-                    if (number.IndexOf('.') > 0)
-                    {
-                        number = number.TrimEnd('0');
-                        number = number.TrimEnd('.');
-                    }
-                    return number;
-                }
-            }
-        }
-
-        [Fact]
-        public void SliceDecimal64Array()
-        {
-            // Arrange
-            const int originalLength = 50;
-            const int offset = 3;
-            const int sliceLength = 32;
-
-            var builder = new Decimal64Array.Builder(new Decimal64Type(7, 3));
-            var random = new Random();
-
-            for (int i = 0; i < originalLength; i++)
-            {
-                if (random.NextDouble() < 0.2)
-                {
-                    builder.AppendNull();
-                }
-                else
-                {
-                    builder.Append(i * (decimal)Math.Round(random.NextDouble(), 2));
-                }
-            }
-
-            var array = builder.Build();
-
-            // Act
-            var slice = (Decimal64Array)array.Slice(offset, sliceLength);
-
-            // Assert
-            Assert.NotNull(slice);
-            Assert.Equal(sliceLength, slice.Length);
-            for (int i = 0; i < sliceLength; ++i)
-            {
-                Assert.Equal(array.GetValue(offset + i), slice.GetValue(i));
-                Assert.Equal(array.GetString(offset + i), slice.GetString(i));
-            }
-
-            Assert.Equal(
-                array.ToList(includeNulls: true).Skip(offset).Take(sliceLength).ToList(),
-                slice.ToList(includeNulls: true));
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/DecimalUtilityTests.cs b/csharp/test/Apache.Arrow.Tests/DecimalUtilityTests.cs
deleted file mode 100644
index 1156ecb..0000000
--- a/csharp/test/Apache.Arrow.Tests/DecimalUtilityTests.cs
+++ /dev/null
@@ -1,205 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Data.SqlTypes;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class DecimalUtilityTests
-    {
-        public class Overflow
-        {
-            [Theory]
-            [InlineData(100.123, 10, 4, false)]
-            [InlineData(100.123, 6, 4, false)]
-            [InlineData(100.123, 3, 3, true)]
-            [InlineData(100.123, 10, 2, true)]
-            [InlineData(100.123, 5, 2, true)]
-            [InlineData(100.123, 5, 3, true)]
-            [InlineData(100.123, 6, 3, false)]
-            public void HasExpectedResultOrThrows(decimal d, int precision, int scale, bool shouldThrow)
-            {
-                var builder = new Decimal128Array.Builder(new Decimal128Type(precision, scale));
-
-                if (shouldThrow)
-                {
-                    Assert.Throws<OverflowException>(() => builder.Append(d));
-                }
-                else
-                {
-                    builder.Append(d);
-                    var result = builder.Build(new TestMemoryAllocator());
-                    Assert.Equal(d, result.GetValue(0));
-                }
-            }
-
-            [Theory]
-            [InlineData(4.56, 38, 9, false)]
-            [InlineData(7.89, 76, 38, true)]
-            public void Decimal256HasExpectedResultOrThrows(decimal d, int precision, int scale, bool shouldThrow)
-            {
-                var builder = new Decimal256Array.Builder(new Decimal256Type(precision, scale));
-                builder.Append(d);
-                Decimal256Array result = builder.Build(new TestMemoryAllocator()); ;
-
-                if (shouldThrow)
-                {
-                    Assert.Throws<OverflowException>(() => result.GetValue(0));
-                }
-                else
-                {
-                    Assert.Equal(d, result.GetValue(0));
-                }
-            }
-        }
-
-        public class SqlDecimals
-        {
-            [Fact]
-            public void NegativeSqlDecimal()
-            {
-                const int precision = 38;
-                const int scale = 0;
-                const int bitWidth = 16;
-
-                var negative = new SqlDecimal(precision, scale, false, 0, 0, 1, 0);
-                var bytes = new byte[16];
-                DecimalUtility.GetBytes(negative.Value, precision, scale, bitWidth, bytes);
-                var sqlNegative = DecimalUtility.GetSqlDecimal128(new ArrowBuffer(bytes), 0, precision, scale);
-                Assert.Equal(negative, sqlNegative);
-
-                DecimalUtility.GetBytes(sqlNegative, precision, scale, bytes);
-                var decimalNegative = DecimalUtility.GetDecimal(new ArrowBuffer(bytes), 0, scale, bitWidth);
-                Assert.Equal(negative.Value, decimalNegative);
-            }
-
-            [Fact]
-            public void LargeScale()
-            {
-                string digits = "1.2345678901234567890123456789012345678";
-
-                var positive = SqlDecimal.Parse(digits);
-                Assert.Equal(38, positive.Precision);
-                Assert.Equal(37, positive.Scale);
-
-                var bytes = new byte[16];
-                DecimalUtility.GetBytes(positive, positive.Precision, positive.Scale, bytes);
-                var sqlPositive = DecimalUtility.GetSqlDecimal128(new ArrowBuffer(bytes), 0, positive.Precision, positive.Scale);
-
-                Assert.Equal(positive, sqlPositive);
-                Assert.Equal(digits, sqlPositive.ToString());
-
-                digits = "-" + digits;
-                var negative = SqlDecimal.Parse(digits);
-                Assert.Equal(38, positive.Precision);
-                Assert.Equal(37, positive.Scale);
-
-                DecimalUtility.GetBytes(negative, negative.Precision, negative.Scale, bytes);
-                var sqlNegative = DecimalUtility.GetSqlDecimal128(new ArrowBuffer(bytes), 0, negative.Precision, negative.Scale);
-
-                Assert.Equal(negative, sqlNegative);
-                Assert.Equal(digits, sqlNegative.ToString());
-            }
-        }
-
-        public class Strings
-        {
-            [Theory]
-            [InlineData(100.12, 10, 2, "100.12")]
-            [InlineData(100.12, 8, 3, "100.120")]
-            [InlineData(100.12, 7, 4, "100.1200")]
-            [InlineData(.12, 6, 3, "0.120")]
-            [InlineData(.0012, 5, 4, "0.0012")]
-            [InlineData(-100.12, 10, 2, "-100.12")]
-            [InlineData(-100.12, 8, 3, "-100.120")]
-            [InlineData(-100.12, 7, 4, "-100.1200")]
-            [InlineData(-.12, 6, 3, "-0.120")]
-            [InlineData(-.0012, 5, 4, "-0.0012")]
-            [InlineData(7.89, 76, 38, "7.89000000000000000000000000000000000000")]
-            public void FromDecimal(decimal d, int precision, int scale, string result)
-            {
-                if (precision <= 38)
-                {
-                    TestFromDecimal(d, precision, scale, 16, result);
-                }
-                TestFromDecimal(d, precision, scale, 32, result);
-            }
-
-            private void TestFromDecimal(decimal d, int precision, int scale, int byteWidth, string result)
-            {
-                var bytes = new byte[byteWidth];
-                DecimalUtility.GetBytes(d, precision, scale, byteWidth, bytes);
-                Assert.Equal(result, DecimalUtility.GetString(new ArrowBuffer(bytes), 0, precision, scale, byteWidth));
-            }
-
-            [Theory]
-            [InlineData("100.12", 10, 2, "100.12")]
-            [InlineData("100.12", 8, 3, "100.120")]
-            [InlineData("100.12", 7, 4, "100.1200")]
-            [InlineData(".12", 6, 3, "0.120")]
-            [InlineData(".0012", 5, 4, "0.0012")]
-            [InlineData("-100.12", 10, 2, "-100.12")]
-            [InlineData("-100.12", 8, 3, "-100.120")]
-            [InlineData("-100.12", 7, 4, "-100.1200")]
-            [InlineData("-.12", 6, 3, "-0.120")]
-            [InlineData("-.0012", 5, 4, "-0.0012")]
-            [InlineData("+.0012", 5, 4, "0.0012")]
-            [InlineData("99999999999999999999999999999999999999", 38, 0, "99999999999999999999999999999999999999")]
-            [InlineData("-99999999999999999999999999999999999999", 38, 0, "-99999999999999999999999999999999999999")]
-            public void FromString(string s, int precision, int scale, string result)
-            {
-                TestFromString(s, precision, scale, 16, result);
-                TestFromString(s, precision, scale, 32, result);
-            }
-
-            [Fact]
-            public void ThroughDecimal256()
-            {
-                var seventysix = new string('9', 76);
-                TestFromString(seventysix, 76, 0, 32, seventysix);
-                TestFromString("0000" + seventysix, 76, 0, 32, seventysix);
-
-                seventysix = "-" + seventysix;
-                TestFromString(seventysix, 76, 0, 32, seventysix);
-
-                var seventyseven = new string('9', 77);
-                Assert.Throws<OverflowException>(() => TestFromString(seventyseven, 76, 0, 32, seventyseven));
-            }
-
-            private void TestFromString(string s, int precision, int scale, int byteWidth, string result)
-            {
-                var bytes = new byte[byteWidth];
-                DecimalUtility.GetBytes(s, precision, scale, byteWidth, bytes);
-                Assert.Equal(result, DecimalUtility.GetString(new ArrowBuffer(bytes), 0, precision, scale, byteWidth));
-            }
-
-            [Theory]
-            [InlineData("", 10, 2, 16, typeof(ArgumentException))]
-            [InlineData("", 10, 2, 32, typeof(ArgumentException))]
-            [InlineData(null, 10, 2, 32, typeof(ArgumentException))]
-            [InlineData("1.23", 10, 1, 16, typeof(OverflowException))]
-            [InlineData("12345678901234567890", 24, 1, 8, typeof(OverflowException))]
-            [InlineData("abc", 24, 1, 8, typeof(ArgumentException))]
-            public void ParseErrors(string s, int precision, int scale, int byteWidth, Type exceptionType)
-            {
-                byte[] bytes = new byte[byteWidth];
-                Assert.Throws(exceptionType, () => DecimalUtility.GetBytes(s, precision, scale, byteWidth, bytes));
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/DictionaryArrayTests.cs b/csharp/test/Apache.Arrow.Tests/DictionaryArrayTests.cs
deleted file mode 100644
index da67856..0000000
--- a/csharp/test/Apache.Arrow.Tests/DictionaryArrayTests.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class DictionaryArrayTests
-    {
-        [Fact]
-        public void CreateTest()
-        {
-            (StringArray originalDictionary, Int32Array originalIndicesArray, DictionaryArray dictionaryArray) =
-                CreateSimpleTestData();
-
-            Assert.Equal(dictionaryArray.Dictionary, originalDictionary);
-            Assert.Equal(dictionaryArray.Indices, originalIndicesArray);
-        }
-
-        [Fact]
-        public void SliceTest()
-        {
-            (StringArray originalDictionary, Int32Array originalIndicesArray, DictionaryArray dictionaryArray) =
-                CreateSimpleTestData();
-
-            int batchLength = originalIndicesArray.Length;
-            for (int offset = 0; offset < batchLength; offset++)
-            {
-                for (int length = 1; offset + length <= batchLength; length++)
-                {
-                    var sliced = dictionaryArray.Slice(offset, length) as DictionaryArray;
-                    var actualSlicedDictionary = sliced.Dictionary as StringArray;
-                    var actualSlicedIndicesArray = sliced.Indices as Int32Array;
-
-                    var expectedSlicedIndicesArray = originalIndicesArray.Slice(offset, length) as Int32Array;
-
-                    //Dictionary is not sliced.
-                    Assert.Equal(originalDictionary.Data, actualSlicedDictionary.Data);
-                    Assert.Equal(expectedSlicedIndicesArray.ToList(), actualSlicedIndicesArray.ToList());
-                }
-            }
-        }
-
-        private Tuple<StringArray, Int32Array, DictionaryArray> CreateSimpleTestData()
-        {
-            StringArray originalDictionary = new StringArray.Builder().AppendRange(new[] { "a", "b", "c" }).Build();
-            Int32Array originalIndicesArray = new Int32Array.Builder().AppendRange(new[] { 0, 0, 1, 1, 2, 2 }).Build();
-            var dictionaryArray = new DictionaryArray(new DictionaryType(Int32Type.Default, StringType.Default, false), originalIndicesArray, originalDictionary);
-
-            return Tuple.Create(originalDictionary, originalIndicesArray, dictionaryArray);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/DurationArrayTests.cs b/csharp/test/Apache.Arrow.Tests/DurationArrayTests.cs
deleted file mode 100644
index 412f67d..0000000
--- a/csharp/test/Apache.Arrow.Tests/DurationArrayTests.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class DurationArrayTests
-    {
-        private const long TicksPerMicrosecond = 10;
-
-        private static readonly TimeSpan?[] _exampleTimeSpans =
-        {
-            null,
-            TimeSpan.FromDays(10.5),
-            TimeSpan.FromHours(10.5),
-            TimeSpan.FromMinutes(10.5),
-            TimeSpan.FromSeconds(10.5),
-            TimeSpan.FromMilliseconds(10.5),
-            TimeSpan.FromTicks(11),
-        };
-
-        private static readonly long?[] _exampleDurations =
-        {
-            null,
-            1,
-            1000,
-            1000000,
-            1000000000,
-            1000000000000,
-        };
-
-        private static readonly DurationType[] _durationTypes =
-        {
-            DurationType.Second,
-            DurationType.Millisecond,
-            DurationType.Microsecond,
-            DurationType.Nanosecond,
-        };
-
-        public static IEnumerable<object[]> GetTimeSpansData() =>
-            from timeSpan in _exampleTimeSpans
-            from type in _durationTypes
-            where type.Unit >= RequiredPrecision(timeSpan)
-            select new object[] { timeSpan, type };
-
-        public static IEnumerable<object[]> GetDurationsData() =>
-            from duration in _exampleDurations
-            from type in _durationTypes
-            select new object[] { duration, type };
-
-        static TimeUnit RequiredPrecision(TimeSpan? timeSpan)
-        {
-            if (timeSpan == null) { return TimeUnit.Second; }
-            if ((timeSpan.Value.Ticks % TicksPerMicrosecond) > 0) { return TimeUnit.Nanosecond; }
-#if NET5_0_OR_GREATER
-            if (timeSpan.Value.Microseconds > 0) { return TimeUnit.Microsecond; }
-#else
-            if ((timeSpan.Value.Ticks % (TicksPerMicrosecond * 1000)) > 0) { return TimeUnit.Microsecond; }
-#endif
-            if (timeSpan.Value.Milliseconds > 0) { return TimeUnit.Millisecond; }
-            return TimeUnit.Second;
-        }
-
-        public class AppendNull
-        {
-            [Fact]
-            public void AppendThenGetGivesNull()
-            {
-                // Arrange
-                var builder = new DurationArray.Builder(DurationType.Millisecond);
-
-                // Act
-                builder = builder.AppendNull();
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Null(array.GetValue(0));
-                Assert.Null(array.GetTimeSpan(0));
-            }
-        }
-
-        public class AppendTimeSpan
-        {
-            [Theory]
-            [MemberData(nameof(GetTimeSpansData), MemberType = typeof(DurationArrayTests))]
-            public void AppendTimeSpanGivesSameTimeSpan(TimeSpan? timeSpan, DurationType type)
-            {
-                // Arrange
-                var builder = new DurationArray.Builder(type);
-
-                // Act
-                builder = builder.Append(timeSpan);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(timeSpan, array.GetTimeSpan(0));
-
-                IReadOnlyList<TimeSpan?> asList = array;
-                Assert.Single(asList);
-                Assert.Equal(timeSpan, asList[0]);
-            }
-        }
-
-        public class AppendDuration
-        {
-            [Theory]
-            [MemberData(nameof(GetDurationsData), MemberType = typeof(DurationArrayTests))]
-            public void AppendDurationGivesSameDuration(long? duration, DurationType type)
-            {
-                // Arrange
-                var builder = new DurationArray.Builder(type);
-
-                // Act
-                builder = builder.Append(duration);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(duration, array.GetValue(0));
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/Extensions/DateTimeOffsetExtensions.cs b/csharp/test/Apache.Arrow.Tests/Extensions/DateTimeOffsetExtensions.cs
deleted file mode 100644
index 01809735..0000000
--- a/csharp/test/Apache.Arrow.Tests/Extensions/DateTimeOffsetExtensions.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Apache.Arrow.Tests
-{
-    public static class DateTimeOffsetExtensions
-    {
-        public static DateTimeOffset Truncate(this DateTimeOffset dateTimeOffset, TimeSpan offset)
-        {
-            if (offset == TimeSpan.Zero)
-            {
-                return dateTimeOffset;
-            }
-
-            if (dateTimeOffset == DateTimeOffset.MinValue || dateTimeOffset == DateTimeOffset.MaxValue)
-            {
-                return dateTimeOffset;
-            }
-
-            return dateTimeOffset.AddTicks(-(dateTimeOffset.Ticks % offset.Ticks));
-        }
-            
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/Extensions/Net472Extensions.cs b/csharp/test/Apache.Arrow.Tests/Extensions/Net472Extensions.cs
deleted file mode 100644
index 0b298de..0000000
--- a/csharp/test/Apache.Arrow.Tests/Extensions/Net472Extensions.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Collections.Generic;
-
-namespace Apache.Arrow.Tests
-{
-    internal static class Net472Extensions
-    {
-        public static IEnumerable<(TFirst First, TSecond Second)> Zip<TFirst, TSecond>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second)
-        {
-            using (var enumerator1 = first.GetEnumerator())
-            using (var enumerator2 = second.GetEnumerator())
-            {
-                while (enumerator1.MoveNext() && enumerator2.MoveNext())
-                {
-                    yield return (enumerator1.Current, enumerator2.Current);
-                }
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/FieldComparer.cs b/csharp/test/Apache.Arrow.Tests/FieldComparer.cs
deleted file mode 100644
index 06fd2ab..0000000
--- a/csharp/test/Apache.Arrow.Tests/FieldComparer.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Linq;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public static class FieldComparer
-    {
-        public static void Compare(Field expected, Field actual)
-        {
-            if (ReferenceEquals(expected, actual))
-            {
-                return;
-            }
-
-            Assert.Equal(expected.Name, actual.Name);
-            Assert.Equal(expected.IsNullable, actual.IsNullable);
-
-            Assert.Equal(expected.HasMetadata, actual.HasMetadata);
-            if (expected.HasMetadata)
-            {
-                Assert.Equal(expected.Metadata.Keys.Count(), actual.Metadata.Keys.Count());
-                Assert.True(expected.Metadata.Keys.All(k => actual.Metadata.ContainsKey(k) && expected.Metadata[k] == actual.Metadata[k]));
-                Assert.True(actual.Metadata.Keys.All(k => expected.Metadata.ContainsKey(k) && actual.Metadata[k] == expected.Metadata[k]));
-            }
-
-            actual.DataType.Accept(new ArrayTypeComparer(expected.DataType));
-        }
-
-        public static void Compare(IRecordType expected, IRecordType actual)
-        {
-            Assert.Equal(expected.FieldCount, actual.FieldCount);
-
-            for (int i = 0; i < expected.FieldCount; i++)
-            {
-                Compare(expected.GetFieldByIndex(i), actual.GetFieldByIndex(i));
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/FixedSizeBinaryArrayTests.cs b/csharp/test/Apache.Arrow.Tests/FixedSizeBinaryArrayTests.cs
deleted file mode 100644
index abc66d6..0000000
--- a/csharp/test/Apache.Arrow.Tests/FixedSizeBinaryArrayTests.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Linq;
-using Apache.Arrow.Arrays;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests;
-
-public class FixedSizeBinaryArrayTests
-{
-    [Fact]
-    public void SliceFixedSizeBinaryArray()
-    {
-        const int byteWidth = 2;
-        const int length = 5;
-        const int nullCount = 1;
-
-        var validityBuffer = new ArrowBuffer.BitmapBuilder()
-            .AppendRange(true, 2)
-            .Append(false)
-            .AppendRange(true, 2)
-            .Build();
-        var dataBuffer = new ArrowBuffer.Builder<byte>()
-            .AppendRange(Enumerable.Range(0, length * byteWidth).Select(i => (byte)i))
-            .Build();
-        var arrayData = new ArrayData(
-            new FixedSizeBinaryType(byteWidth),
-            length, nullCount, 0, new [] {validityBuffer, dataBuffer});
-        var array = new FixedSizeBinaryArray(arrayData);
-
-        var slice = (FixedSizeBinaryArray)array.Slice(1, 3);
-
-        Assert.Equal(3, slice.Length);
-        Assert.Equal(new byte[] {2, 3}, slice.GetBytes(0).ToArray());
-        Assert.True(slice.GetBytes(1).IsEmpty);
-        Assert.Equal(new byte[] {6, 7}, slice.GetBytes(2).ToArray());
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/Fixtures/DefaultMemoryAllocatorFixture.cs b/csharp/test/Apache.Arrow.Tests/Fixtures/DefaultMemoryAllocatorFixture.cs
deleted file mode 100644
index 276caf1..0000000
--- a/csharp/test/Apache.Arrow.Tests/Fixtures/DefaultMemoryAllocatorFixture.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Memory;
-
-namespace Apache.Arrow.Tests.Fixtures
-{
-    public class DefaultMemoryAllocatorFixture
-    {
-        public MemoryAllocator MemoryAllocator { get; }
-
-        public DefaultMemoryAllocatorFixture()
-        {
-            const int alignment = 64;
-
-            MemoryAllocator = new NativeMemoryAllocator(alignment);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/IntervalScalarTests.cs b/csharp/test/Apache.Arrow.Tests/IntervalScalarTests.cs
deleted file mode 100644
index 52c403c..0000000
--- a/csharp/test/Apache.Arrow.Tests/IntervalScalarTests.cs
+++ /dev/null
@@ -1,250 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Apache.Arrow.Scalars;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class IntervalScalarTests
-    {
-        private static TimeSpan[] timeSpans = new[] { TimeSpan.FromHours(0), TimeSpan.FromHours(-1), TimeSpan.FromHours(1), TimeSpan.FromHours(11.5), TimeSpan.FromHours(-11.5) };
-
-        private static IEnumerable<object[]> ToDateTimeOffsets(IEnumerable<object[]> datetimes) =>
-            from dtdata in datetimes
-            from ts in timeSpans
-            select new object[] { new DateTimeOffset((DateTime)dtdata[0], ts), dtdata[1], new DateTimeOffset((DateTime)dtdata[2], ts) };
-
-#if NET6_0_OR_GREATER
-        private static IEnumerable<object[]> ToDateOnlys(IEnumerable<object[]> datetimes) =>
-            from dtdata in datetimes
-            select new object[] { DateOnly.FromDateTime((DateTime)dtdata[0]), dtdata[1], DateOnly.FromDateTime((DateTime)dtdata[2]) };
-#endif
-
-        public class YearMonth
-        {
-            public static IEnumerable<object[]> GetGoodDateTimeArithmeticData()
-            {
-                yield return new object[] { new DateTime(2020, 3, 4, 12, 14, 15), new YearMonthInterval(-3), new DateTime(2019, 12, 4, 12, 14, 15) };
-                yield return new object[] { new DateTime(2020, 1, 31), new YearMonthInterval(14), new DateTime(2021, 3, 31) };
-                yield return new object[] { new DateTime(2020, 1, 1, 23, 59, 59), new YearMonthInterval(-95), new DateTime(2012, 2, 1, 23, 59, 59) };
-            }
-
-            public static IEnumerable<object[]> GetBadDateTimeArithmeticData()
-            {
-                yield return new object[] { new DateTime(2020, 3, 4, 0, 0, 1), new YearMonthInterval(-2), new DateTime(2019, 1, 4, 0, 0, 0) };
-                yield return new object[] { new DateTime(2019, 12, 1), new YearMonthInterval(15), new DateTime(2021, 3, 2) };
-            }
-
-            public static IEnumerable<object[]> GetGoodDateTimeOffsetArithmeticData() => ToDateTimeOffsets(GetGoodDateTimeArithmeticData());
-            public static IEnumerable<object[]> GetBadDateTimeOffsetArithmeticData() => ToDateTimeOffsets(GetBadDateTimeArithmeticData());
-
-#if NET6_0_OR_GREATER
-            public static IEnumerable<object[]> GetGoodDateOnlyArithmeticData() => ToDateOnlys(GetGoodDateTimeArithmeticData());
-            public static IEnumerable<object[]> GetBadDateOnlyArithmeticData() => ToDateOnlys(GetBadDateTimeArithmeticData());
-#endif
-
-            [Fact]
-            public void Equality()
-            {
-                Assert.Equal(new YearMonthInterval(10), new YearMonthInterval(1, -2));
-                Assert.NotEqual(new YearMonthInterval(9), new YearMonthInterval(1, -2));
-            }
-
-            [Theory]
-            [MemberData(nameof(GetGoodDateTimeArithmeticData))]
-            public void CorrectDateTimeMath(DateTime a, YearMonthInterval b, DateTime c)
-            {
-                Assert.Equal(c, a + b);
-                Assert.Equal(c, b + a);
-                Assert.Equal(a, c - b);
-            }
-
-            [Theory]
-            [MemberData(nameof(GetBadDateTimeArithmeticData))]
-            public void IncorrectDateTimeMath(DateTime a, YearMonthInterval b, DateTime c)
-            {
-                Assert.NotEqual(c, a + b);
-                Assert.NotEqual(c, b + a);
-                Assert.NotEqual(a, c - b);
-            }
-
-            [Theory]
-            [MemberData(nameof(GetGoodDateTimeOffsetArithmeticData))]
-            public void CorrectDateTimeOffsetMath(DateTimeOffset a, YearMonthInterval b, DateTimeOffset c)
-            {
-                Assert.Equal(c, a + b);
-                Assert.Equal(c, b + a);
-                Assert.Equal(a, c - b);
-            }
-
-            [Theory]
-            [MemberData(nameof(GetBadDateTimeOffsetArithmeticData))]
-            public void IncorrectDateTimeOffsetMath(DateTimeOffset a, YearMonthInterval b, DateTimeOffset c)
-            {
-                Assert.NotEqual(c, a + b);
-                Assert.NotEqual(c, b + a);
-                Assert.NotEqual(a, c - b);
-            }
-
-#if NET6_0_OR_GREATER
-            [Theory]
-            [MemberData(nameof(GetGoodDateOnlyArithmeticData))]
-            public void CorrectDateOnlyMath(DateOnly a, YearMonthInterval b, DateOnly c)
-            {
-                Assert.Equal(c, a + b);
-                Assert.Equal(c, b + a);
-                Assert.Equal(a, c - b);
-            }
-
-            [Theory]
-            [MemberData(nameof(GetBadDateOnlyArithmeticData))]
-            public void IncorrectDateOnlyMath(DateOnly a, YearMonthInterval b, DateOnly c)
-            {
-                Assert.NotEqual(c, a + b);
-                Assert.NotEqual(c, b + a);
-                Assert.NotEqual(a, c - b);
-            }
-#endif
-        }
-
-        public class DayTime
-        {
-            public static IEnumerable<object[]> GetGoodDateTimeArithmeticData()
-            {
-                yield return new object[] { new DateTime(2020, 3, 4, 12, 14, 15), new DayTimeInterval(-3, 123456), new DateTime(2020, 3, 1, 12, 16, 18, 456) };
-                yield return new object[] { new DateTime(2020, 1, 31), new DayTimeInterval(14, 0), new DateTime(2020, 2, 14) };
-                yield return new object[] { new DateTime(2020, 1, 1, 23, 59, 59), new DayTimeInterval(300, -300000), new DateTime(2020, 10, 27, 23, 54, 59) };
-            }
-
-            public static IEnumerable<object[]> GetBadDateTimeArithmeticData()
-            {
-                yield return new object[] { new DateTime(2020, 3, 4, 0, 0, 1), new DayTimeInterval(-2, 0), new DateTime(2019, 1, 4, 0, 0, 0) };
-                yield return new object[] { new DateTime(2019, 12, 1), new DayTimeInterval(15, 0), new DateTime(2021, 3, 2) };
-            }
-
-            public static IEnumerable<object[]> GetGoodDateTimeOffsetArithmeticData() => ToDateTimeOffsets(GetGoodDateTimeArithmeticData());
-            public static IEnumerable<object[]> GetBadDateTimeOffsetArithmeticData() => ToDateTimeOffsets(GetBadDateTimeArithmeticData());
-
-            [Fact]
-            public void Equality()
-            {
-                Assert.Equal(new DayTimeInterval(10, -1), new DayTimeInterval(10, -1));
-                Assert.NotEqual(new DayTimeInterval(10, 0), new DayTimeInterval(9, 86400*1000));
-            }
-
-            [Theory]
-            [MemberData(nameof(GetGoodDateTimeArithmeticData))]
-            public void CorrectDateTimeMath(DateTime a, DayTimeInterval b, DateTime c)
-            {
-                Assert.Equal(c, a + b);
-                Assert.Equal(c, b + a);
-                Assert.Equal(a, c - b);
-            }
-
-            [Theory]
-            [MemberData(nameof(GetBadDateTimeArithmeticData))]
-            public void IncorrectDateTimeMath(DateTime a, DayTimeInterval b, DateTime c)
-            {
-                Assert.NotEqual(c, a + b);
-                Assert.NotEqual(c, b + a);
-                Assert.NotEqual(a, c - b);
-            }
-
-            [Theory]
-            [MemberData(nameof(GetGoodDateTimeOffsetArithmeticData))]
-            public void CorrectDateTimeOffsetMath(DateTimeOffset a, DayTimeInterval b, DateTimeOffset c)
-            {
-                Assert.Equal(c, a + b);
-                Assert.Equal(c, b + a);
-                Assert.Equal(a, c - b);
-            }
-
-            [Theory]
-            [MemberData(nameof(GetBadDateTimeOffsetArithmeticData))]
-            public void IncorrectDateTimeOffsetMath(DateTimeOffset a, DayTimeInterval b, DateTimeOffset c)
-            {
-                Assert.NotEqual(c, a + b);
-                Assert.NotEqual(c, b + a);
-                Assert.NotEqual(a, c - b);
-            }
-        }
-
-        public class MonthDayNanosecond
-        {
-            public static IEnumerable<object[]> GetGoodDateTimeArithmeticData()
-            {
-                yield return new object[] { new DateTime(2020, 3, 4, 12, 14, 15), new MonthDayNanosecondInterval(-3, 0, 100), new DateTime(2019, 12, 4, 12, 14, 15).AddTicks(1) };
-                yield return new object[] { new DateTime(2020, 1, 31), new MonthDayNanosecondInterval(14, -2, -200), new DateTime(2021, 3, 29).AddTicks(-2) };
-                yield return new object[] { new DateTime(2020, 1, 1, 23, 59, 59), new MonthDayNanosecondInterval(-95, 0, 0), new DateTime(2012, 2, 1, 23, 59, 59) };
-            }
-
-            public static IEnumerable<object[]> GetBadDateTimeArithmeticData()
-            {
-                yield return new object[] { new DateTime(2020, 3, 4, 0, 0, 1), new MonthDayNanosecondInterval(-2, 0, 0), new DateTime(2019, 1, 4, 0, 0, 0) };
-                yield return new object[] { new DateTime(2019, 12, 1), new MonthDayNanosecondInterval(15, 0, 0), new DateTime(2021, 3, 2) };
-            }
-
-            public static IEnumerable<object[]> GetGoodDateTimeOffsetArithmeticData() => ToDateTimeOffsets(GetGoodDateTimeArithmeticData());
-            public static IEnumerable<object[]> GetBadDateTimeOffsetArithmeticData() => ToDateTimeOffsets(GetBadDateTimeArithmeticData());
-
-            [Fact]
-            public void Equality()
-            {
-                Assert.Equal(new MonthDayNanosecondInterval(1, -2, 3), new MonthDayNanosecondInterval(1, -2, 3));
-                Assert.NotEqual(new MonthDayNanosecondInterval(1, -2, 3), new MonthDayNanosecondInterval(1, -2, 4));
-            }
-
-            [Theory]
-            [MemberData(nameof(GetGoodDateTimeArithmeticData))]
-            public void CorrectDateTimeMath(DateTime a, MonthDayNanosecondInterval b, DateTime c)
-            {
-                Assert.Equal(c, a + b);
-                Assert.Equal(c, b + a);
-                Assert.Equal(a, c - b);
-            }
-
-            [Theory]
-            [MemberData(nameof(GetBadDateTimeArithmeticData))]
-            public void IncorrectDateTimeMath(DateTime a, MonthDayNanosecondInterval b, DateTime c)
-            {
-                Assert.NotEqual(c, a + b);
-                Assert.NotEqual(c, b + a);
-                Assert.NotEqual(a, c - b);
-            }
-
-            [Theory]
-            [MemberData(nameof(GetGoodDateTimeOffsetArithmeticData))]
-            public void CorrectDateTimeOffsetMath(DateTimeOffset a, MonthDayNanosecondInterval b, DateTimeOffset c)
-            {
-                Assert.Equal(c, a + b);
-                Assert.Equal(c, b + a);
-                Assert.Equal(a, c - b);
-            }
-
-            [Theory]
-            [MemberData(nameof(GetBadDateTimeOffsetArithmeticData))]
-            public void IncorrectDateTimeOffsetMath(DateTimeOffset a, MonthDayNanosecondInterval b, DateTimeOffset c)
-            {
-                Assert.NotEqual(c, a + b);
-                Assert.NotEqual(c, b + a);
-                Assert.NotEqual(a, c - b);
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/LargeBinaryArrayTests.cs b/csharp/test/Apache.Arrow.Tests/LargeBinaryArrayTests.cs
deleted file mode 100644
index 4ee1f1d..0000000
--- a/csharp/test/Apache.Arrow.Tests/LargeBinaryArrayTests.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests;
-
-public class LargeBinaryArrayTests
-{
-    [Fact]
-    public void GetBytesReturnsCorrectValue()
-    {
-        var byteArrays = new byte[][]
-        {
-            new byte[] {0, 1, 2, 255},
-            new byte[] {3, 4, 5},
-            new byte[] {},
-            null,
-            new byte[] {254, 253, 252},
-        };
-        var array = BuildArray(byteArrays);
-
-        Assert.Equal(array.Length, byteArrays.Length);
-        for (var i = 0; i < byteArrays.Length; ++i)
-        {
-            var byteSpan = array.GetBytes(i, out var isNull);
-            var byteArray = isNull ? null : byteSpan.ToArray();
-            Assert.Equal(byteArrays[i], byteArray);
-        }
-    }
-
-    [Fact]
-    public void GetBytesChecksForOffsetOverflow()
-    {
-        var valueBuffer = new ArrowBuffer.Builder<byte>();
-        var offsetBuffer = new ArrowBuffer.Builder<long>();
-        var validityBuffer = new ArrowBuffer.BitmapBuilder();
-
-        offsetBuffer.Append(0);
-        offsetBuffer.Append((long)int.MaxValue + 1);
-        validityBuffer.Append(true);
-
-        var array = new LargeBinaryArray(
-            LargeBinaryType.Default, length: 1,
-            offsetBuffer.Build(), valueBuffer.Build(), validityBuffer.Build(),
-            validityBuffer.UnsetBitCount);
-
-        Assert.Throws<OverflowException>(() => array.GetBytes(0));
-    }
-
-    private static LargeBinaryArray BuildArray(IReadOnlyCollection<byte[]> byteArrays)
-    {
-        var valueBuffer = new ArrowBuffer.Builder<byte>();
-        var offsetBuffer = new ArrowBuffer.Builder<long>();
-        var validityBuffer = new ArrowBuffer.BitmapBuilder();
-
-        long offset = 0;
-        offsetBuffer.Append(offset);
-        foreach (var bytes in byteArrays)
-        {
-            if (bytes == null)
-            {
-                validityBuffer.Append(false);
-                offsetBuffer.Append(offset);
-            }
-            else
-            {
-                valueBuffer.Append(bytes);
-                offset += bytes.Length;
-                offsetBuffer.Append(offset);
-                validityBuffer.Append(true);
-            }
-        }
-
-        return new LargeBinaryArray(
-            LargeBinaryType.Default, byteArrays.Count,
-            offsetBuffer.Build(), valueBuffer.Build(), validityBuffer.Build(),
-            validityBuffer.UnsetBitCount);
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/LargeListArrayTests.cs b/csharp/test/Apache.Arrow.Tests/LargeListArrayTests.cs
deleted file mode 100644
index 1d35a8f..0000000
--- a/csharp/test/Apache.Arrow.Tests/LargeListArrayTests.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Linq;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests;
-
-public class LargeListArrayTests
-{
-    [Fact]
-    public void GetSlicedValuesReturnsCorrectValues()
-    {
-        var values = new int?[][]
-        {
-            new int?[] {0, 1, 2},
-            System.Array.Empty<int?>(),
-            null,
-            new int?[] {3, 4, null, 6},
-        };
-
-        var array = BuildArray(values);
-
-        Assert.Equal(values.Length, array.Length);
-        for (int i = 0; i < values.Length; ++i)
-        {
-            Assert.Equal(values[i] == null, array.IsNull(i));
-            var arrayItem = (Int32Array) array.GetSlicedValues(i);
-            if (values[i] == null)
-            {
-                Assert.Null(arrayItem);
-            }
-            else
-            {
-                Assert.Equal(values[i], arrayItem.ToArray());
-            }
-        }
-    }
-
-    [Fact]
-    public void GetSlicedValuesChecksForOffsetOverflow()
-    {
-        var valuesArray = new Int32Array.Builder().Build();
-        var offsetBuffer = new ArrowBuffer.Builder<long>();
-        var validityBuffer = new ArrowBuffer.BitmapBuilder();
-
-        offsetBuffer.Append(0);
-        offsetBuffer.Append((long)int.MaxValue + 1);
-        validityBuffer.Append(true);
-
-        var array = new LargeListArray(
-            new LargeListType(new Int32Type()), length: 1,
-            offsetBuffer.Build(), valuesArray, validityBuffer.Build(),
-            validityBuffer.UnsetBitCount);
-
-        Assert.Throws<OverflowException>(() => array.GetSlicedValues(0));
-    }
-
-    private static LargeListArray BuildArray(int?[][] values)
-    {
-        var valuesBuilder = new Int32Array.Builder();
-        var offsetBuffer = new ArrowBuffer.Builder<long>();
-        var validityBuffer = new ArrowBuffer.BitmapBuilder();
-
-        long offset = 0;
-        offsetBuffer.Append(offset);
-        foreach (var listValue in values)
-        {
-            if (listValue == null)
-            {
-                validityBuffer.Append(false);
-                offsetBuffer.Append(offset);
-            }
-            else
-            {
-                foreach (var value in listValue)
-                {
-                    valuesBuilder.Append(value);
-                }
-                offset += listValue.Length;
-                offsetBuffer.Append(offset);
-                validityBuffer.Append(true);
-            }
-        }
-
-        return new LargeListArray(
-            new LargeListType(new Int32Type()), values.Length,
-            offsetBuffer.Build(), valuesBuilder.Build(), validityBuffer.Build(),
-            validityBuffer.UnsetBitCount);
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/LargeStringArrayTests.cs b/csharp/test/Apache.Arrow.Tests/LargeStringArrayTests.cs
deleted file mode 100644
index aba97ba..0000000
--- a/csharp/test/Apache.Arrow.Tests/LargeStringArrayTests.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using Xunit;
-
-namespace Apache.Arrow.Tests;
-
-public class LargeStringArrayTests
-{
-    [Fact]
-    public void GetStringReturnsCorrectValue()
-    {
-        var strings = new string[]
-        {
-            "abc",
-            "defg",
-            "",
-            null,
-            "123",
-        };
-        var array = BuildArray(strings);
-
-        Assert.Equal(array.Length, strings.Length);
-        for (var i = 0; i < strings.Length; ++i)
-        {
-            Assert.Equal(strings[i], array.GetString(i));
-        }
-    }
-
-    [Fact]
-    public void GetStringChecksForOffsetOverflow()
-    {
-        var valueBuffer = new ArrowBuffer.Builder<byte>();
-        var offsetBuffer = new ArrowBuffer.Builder<long>();
-        var validityBuffer = new ArrowBuffer.BitmapBuilder();
-
-        offsetBuffer.Append(0);
-        offsetBuffer.Append((long)int.MaxValue + 1);
-        validityBuffer.Append(true);
-
-        var array = new LargeStringArray(
-            length: 1, offsetBuffer.Build(), valueBuffer.Build(), validityBuffer.Build(),
-            validityBuffer.UnsetBitCount);
-
-        Assert.Throws<OverflowException>(() => array.GetString(0));
-    }
-
-    private static LargeStringArray BuildArray(IReadOnlyCollection<string> strings)
-    {
-        var valueBuffer = new ArrowBuffer.Builder<byte>();
-        var offsetBuffer = new ArrowBuffer.Builder<long>();
-        var validityBuffer = new ArrowBuffer.BitmapBuilder();
-
-        long offset = 0;
-        offsetBuffer.Append(offset);
-        foreach (var value in strings)
-        {
-            if (value == null)
-            {
-                validityBuffer.Append(false);
-                offsetBuffer.Append(offset);
-            }
-            else
-            {
-                var bytes = LargeStringArray.DefaultEncoding.GetBytes(value);
-                valueBuffer.Append(bytes);
-                offset += value.Length;
-                offsetBuffer.Append(offset);
-                validityBuffer.Append(true);
-            }
-        }
-
-        return new LargeStringArray(
-            strings.Count, offsetBuffer.Build(), valueBuffer.Build(), validityBuffer.Build(),
-            validityBuffer.UnsetBitCount);
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/MapArrayTests.cs b/csharp/test/Apache.Arrow.Tests/MapArrayTests.cs
deleted file mode 100644
index 21decda..0000000
--- a/csharp/test/Apache.Arrow.Tests/MapArrayTests.cs
+++ /dev/null
@@ -1,202 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class MapArrayTests
-    {
-        [Fact]
-        public void MapArray_Should_GetTuple()
-        {
-            MapType type = new MapType(StringType.Default, Int64Type.Default);
-            MapArray.Builder builder = new MapArray.Builder(type);
-            var keyBuilder = builder.KeyBuilder as StringArray.Builder;
-            var valueBuilder = builder.ValueBuilder as Int64Array.Builder;
-
-            Tuple<string, long?> kv0 = Tuple.Create("test", (long?)1);
-            Tuple<string, long?> kv1 = Tuple.Create("other", (long?)123);
-            Tuple<string, long?> kv2 = Tuple.Create("kv", (long?)null);
-
-            builder.Append();
-            keyBuilder.Append("test");
-            valueBuilder.Append(1);
-
-            builder.AppendNull();
-
-            builder.Append();
-            keyBuilder.Append("other");
-            valueBuilder.Append(123);
-            keyBuilder.Append("kv");
-            valueBuilder.AppendNull();
-
-            MapArray array = builder.Build();
-
-            Assert.Equal(new Tuple<string, long?>[] { kv0 }, array.GetTuples<StringArray, string, Int64Array, long?>(0, GetKey, GetValue).ToArray());
-            Assert.True(array.IsNull(1));
-            Assert.Equal(new Tuple<string, long?>[] { kv1, kv2 }, array.GetTuples<StringArray, string, Int64Array, long?>(2, GetKey, GetValue).ToArray());
-        }
-
-        [Fact]
-        public void MapArray_Should_GetKeyValuePairs()
-        {
-            MapType type = new MapType(StringType.Default, Int32Type.Default);
-            MapArray.Builder builder = new MapArray.Builder(type);
-            var keyBuilder = builder.KeyBuilder as StringArray.Builder;
-            var valueBuilder = builder.ValueBuilder as Int32Array.Builder;
-
-            KeyValuePair<string, int?> kv0 = new KeyValuePair<string, int?>("test", (int?)1);
-            KeyValuePair<string, int?> kv1 = new KeyValuePair<string, int?>("other", (int?)123);
-            KeyValuePair<string, int?> kv2 = new KeyValuePair<string, int?>("kv", (int?)null);
-
-            builder.Append();
-            keyBuilder.Append("test");
-            valueBuilder.Append(1);
-
-            builder.AppendNull();
-
-            builder.Append();
-            keyBuilder.Append("other");
-            valueBuilder.Append(123);
-            keyBuilder.Append("kv");
-            valueBuilder.AppendNull();
-
-            MapArray array = builder.Build();
-
-            Assert.Equal(new KeyValuePair<string, int?>[] { kv0 }, array.GetKeyValuePairs<StringArray, string, Int32Array, int?>(0, GetKey, GetValue).ToArray());
-            Assert.True(array.IsNull(1));
-            Assert.Equal(new KeyValuePair<string, int?>[] { kv1, kv2 }, array.GetKeyValuePairs<StringArray, string, Int32Array, int?>(2, GetKey, GetValue).ToArray());
-        }
-
-        [Fact]
-        public void MapArray_Should_AcceptMapVisitor()
-        {
-            var mapArray = BuildMapArray();
-            var visitor = new MapOnlyVisitor();
-            mapArray.Accept(visitor);
-
-            Assert.True(visitor.MapVisited);
-            Assert.False(visitor.BaseVisited);
-        }
-
-        [Fact]
-        public void MapArray_Should_AcceptListVisitor()
-        {
-            var mapArray = BuildMapArray();
-            var visitor = new ListOnlyVisitor();
-            mapArray.Accept(visitor);
-
-            Assert.True(visitor.ListVisited);
-            Assert.False(visitor.BaseVisited);
-        }
-
-        [Fact]
-        public void MapArray_Should_AcceptListAndMapVisitor()
-        {
-            var mapArray = BuildMapArray();
-            var visitor = new MapAndListVisitor();
-            mapArray.Accept(visitor);
-
-            Assert.True(visitor.MapVisited);
-            Assert.False(visitor.ListVisited);
-            Assert.False(visitor.BaseVisited);
-        }
-
-        private static MapArray BuildMapArray()
-        {
-            MapType type = new MapType(StringType.Default, Int64Type.Default);
-            MapArray.Builder builder = new MapArray.Builder(type);
-            var keyBuilder = builder.KeyBuilder as StringArray.Builder;
-            var valueBuilder = builder.ValueBuilder as Int64Array.Builder;
-
-            builder.Append();
-            keyBuilder.Append("test");
-            valueBuilder.Append(1);
-
-            builder.AppendNull();
-
-            builder.Append();
-            keyBuilder.Append("other");
-            valueBuilder.Append(123);
-            keyBuilder.Append("kv");
-            valueBuilder.AppendNull();
-
-            return builder.Build();
-        }
-
-        private static string GetKey(StringArray array, int index) => array.GetString(index);
-        private static int? GetValue(Int32Array array, int index) => array.GetValue(index);
-        private static long? GetValue(Int64Array array, int index) => array.GetValue(index);
-
-        private sealed class MapOnlyVisitor : IArrowArrayVisitor<MapArray>
-        {
-            public bool MapVisited = false;
-            public bool BaseVisited = false;
-
-            public void Visit(MapArray array)
-            {
-                MapVisited = true;
-            }
-
-            public void Visit(IArrowArray array)
-            {
-                BaseVisited = true;
-            }
-        }
-
-        private sealed class ListOnlyVisitor : IArrowArrayVisitor<ListArray>
-        {
-            public bool ListVisited = false;
-            public bool BaseVisited = false;
-
-            public void Visit(ListArray array)
-            {
-                ListVisited = true;
-            }
-
-            public void Visit(IArrowArray array)
-            {
-                BaseVisited = true;
-            }
-        }
-
-        private sealed class MapAndListVisitor : IArrowArrayVisitor<MapArray>, IArrowArrayVisitor<ListArray>
-        {
-            public bool MapVisited = false;
-            public bool ListVisited = false;
-            public bool BaseVisited = false;
-
-            public void Visit(MapArray array)
-            {
-                MapVisited = true;
-            }
-
-            public void Visit(ListArray array)
-            {
-                ListVisited = true;
-            }
-
-            public void Visit(IArrowArray array)
-            {
-                BaseVisited = true;
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/NullArrayTests.cs b/csharp/test/Apache.Arrow.Tests/NullArrayTests.cs
deleted file mode 100644
index 8cb5b32..0000000
--- a/csharp/test/Apache.Arrow.Tests/NullArrayTests.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class NullArrayTests
-    {
-        public class Builder
-        {
-            public class Append
-            {
-                [Theory]
-                [InlineData(1)]
-                [InlineData(3)]
-                public void IncrementsLength(int count)
-                {
-                    var builder = new NullArray.Builder();
-
-                    for (var i = 0; i < count; i++)
-                    {
-                        builder.AppendNull();
-                    }
-
-                    var array = builder.Build();
-
-                    Assert.Equal(count, array.Length);
-                }
-            }
-
-            public class Clear
-            {
-                [Fact]
-                public void ClearsArray()
-                {
-                    var array = new NullArray.Builder()
-                        .Resize(8)
-                        .AppendNull()
-                        .AppendNull()
-                        .Clear()
-                        .Build();
-
-                    Assert.Equal(0, array.Length);
-                }
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/RecordTests.cs b/csharp/test/Apache.Arrow.Tests/RecordTests.cs
deleted file mode 100644
index cfca455..0000000
--- a/csharp/test/Apache.Arrow.Tests/RecordTests.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Text;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class RecordTests
-    {
-        [Fact]
-        public void StructArraysAndRecordBatchesAreSimilar()
-        {
-            Field stringField = new Field("column1", StringType.Default, true);
-            StringArray.Builder stringBuilder = new StringArray.Builder();
-            StringArray stringArray = stringBuilder.Append("joe").AppendNull().AppendNull().Append("mark").Build();
-
-            Field intField = new Field("column2", Int32Type.Default, true);
-            Int32Array.Builder intBuilder = new Int32Array.Builder();
-            Int32Array intArray = intBuilder.Append(1).Append(2).AppendNull().Append(4).Build();
-
-            Schema schema = new Schema(new[] { stringField, intField }, null);
-            RecordBatch batch = new RecordBatch(schema, new IArrowArray[] { stringArray, intArray }, intArray.Length);
-            IArrowRecord structArray1 = batch;
-
-            StructType structType = new StructType(new[] { stringField, intField });
-            StructArray structArray = new StructArray(structType, intArray.Length, new IArrowArray[] { stringArray, intArray }, ArrowBuffer.Empty);
-            IArrowRecord structArray2 = structArray;
-
-            FieldComparer.Compare(structArray1.Schema, structArray2.Schema);
-            Assert.Equal(structArray1.Length, structArray2.Length);
-            Assert.Equal(structArray1.ColumnCount, structArray2.ColumnCount);
-            Assert.Equal(structArray1.NullCount, structArray2.NullCount);
-
-            for (int i = 0; i < structArray1.ColumnCount; i++)
-            {
-                ArrowReaderVerifier.CompareArrays(structArray1.Column(i), structArray2.Column(i));
-            }
-        }
-
-        [Fact]
-        public void VisitStructAndBatch()
-        {
-            Field stringField = new Field("column1", StringType.Default, true);
-            StructType level1 = new StructType(new[] { stringField });
-            Field level1Field = new Field("column2", level1, false);
-            StructType level2 = new StructType(new[] { level1Field });
-            Field level2Field = new Field("column3", level2, true);
-            Schema schema = new Schema(new[] { level2Field }, null);
-
-            var visitor1 = new TestTypeVisitor1();
-            visitor1.Visit(schema);
-            Assert.Equal("111utf8", visitor1.stringBuilder.ToString());
-            var visitor2 = new TestTypeVisitor2();
-            visitor2.Visit(schema);
-            Assert.Equal("322utf8", visitor2.stringBuilder.ToString());
-
-            StringArray stringArray = new StringArray.Builder().Append("one").AppendNull().AppendNull().Append("four").Build();
-            StructArray level1Array = new StructArray(level1, stringArray.Length, new[] { stringArray }, ArrowBuffer.Empty);
-            ArrowBuffer nulls = new ArrowBuffer.BitmapBuilder(stringArray.Length).Append(false).Append(false).Append(true).Append(false).Build();
-            StructArray level2Array = new StructArray(level2, stringArray.Length, new[] { level1Array }, nulls);
-            RecordBatch batch = new RecordBatch(schema, new IArrowArray[] { level2Array }, stringArray.Length);
-
-            var visitor3 = new TestArrayVisitor1();
-            visitor3.Visit(batch);
-            Assert.Equal("111utf8", visitor3.stringBuilder.ToString());
-            var visitor4 = new TestArrayVisitor2();
-            visitor4.Visit(batch);
-            Assert.Equal("322utf8", visitor4.stringBuilder.ToString());
-        }
-
-        [Fact]
-        public void LazyStructInitialization()
-        {
-            StringArray stringArray = new StringArray.Builder().Append("one").AppendNull().AppendNull().Append("four").Build();
-            Field stringField = new Field("column1", StringType.Default, true);
-            StructType structType = new StructType(new[] { stringField });
-            ArrayData structData = new ArrayData(structType, stringArray.Length, 0, 0, new[] { ArrowBuffer.Empty }, new[] { stringArray.Data });
-            IArrowRecord structArray = new StructArray(structData);
-
-            Assert.Equal(1, structArray.ColumnCount);
-            Assert.Equal(structArray.Length, structArray.Column(0).Length);
-        }
-
-        private class TestTypeVisitor1 : IArrowTypeVisitor, IArrowTypeVisitor<IRecordType>
-        {
-            public StringBuilder stringBuilder = new StringBuilder();
-
-            public void Visit(IArrowType type) { stringBuilder.Append(type.Name); }
-            public void Visit(IRecordType type) { stringBuilder.Append('1'); VisitFields(type); }
-
-            protected void VisitFields(IRecordType type)
-            {
-                for (int i = 0; i < type.FieldCount; i++) { type.GetFieldByIndex(i).DataType.Accept(this); }
-            }
-        }
-
-        private class TestTypeVisitor2 : TestTypeVisitor1,
-            IArrowTypeVisitor<StructType>,
-            IArrowTypeVisitor<Schema>
-        {
-            public void Visit(StructType type) { stringBuilder.Append('2'); VisitFields(type); }
-            public void Visit(Schema type) { stringBuilder.Append('3'); VisitFields(type); }
-        }
-
-        private class TestArrayVisitor1 : IArrowArrayVisitor, IArrowArrayVisitor<IArrowRecord>
-        {
-            public StringBuilder stringBuilder = new StringBuilder();
-
-            public void Visit(IArrowArray array) { stringBuilder.Append(array.Data.DataType.Name); }
-            public void Visit(IArrowRecord array) { stringBuilder.Append('1'); VisitFields(array); }
-
-            protected void VisitFields(IArrowRecord array)
-            {
-                for (int i = 0; i < array.ColumnCount; i++) { array.Column(i).Accept(this); }
-            }
-        }
-
-        private class TestArrayVisitor2 : TestArrayVisitor1,
-            IArrowArrayVisitor<StructArray>,
-            IArrowArrayVisitor<RecordBatch>
-        {
-            public void Visit(StructArray array) { stringBuilder.Append('2'); VisitFields(array); }
-            public void Visit(RecordBatch batch) { stringBuilder.Append('3'); VisitFields(batch); }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/SchemaBuilderTests.cs b/csharp/test/Apache.Arrow.Tests/SchemaBuilderTests.cs
deleted file mode 100644
index 19c7039..0000000
--- a/csharp/test/Apache.Arrow.Tests/SchemaBuilderTests.cs
+++ /dev/null
@@ -1,288 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Xunit;
-using Xunit.Sdk;
-
-namespace Apache.Arrow.Tests
-{
-    public class SchemaBuilderTests
-    {
-        public class Build
-        {
-            [Fact]
-            public void FieldsAreNullableByDefault()
-            {
-                var schema = new Schema.Builder()
-                    .Field(f => f.Name("f0").DataType(Int32Type.Default))
-                    .Build();
-
-                Assert.True(schema.FieldsList[0].IsNullable);
-            }
-
-            [Fact]
-            public void FieldsHaveNullTypeByDefault()
-            {
-                var schema = new Schema.Builder()
-                    .Field(f => f.Name("f0"))
-                    .Build();
-
-                Assert.Equal(typeof(NullType), schema.FieldsList[0].DataType.GetType());
-            }
-
-            [Fact]
-            public void FieldNameIsRequired()
-            {
-                Assert.Throws<ArgumentNullException>(() =>
-                {
-                    var schema = new Schema.Builder()
-                        .Field(f => f.DataType(Int32Type.Default))
-                        .Build();
-                });
-            }
-
-            [Fact]
-            public void FieldNamesAreCaseSensitive()
-            {
-                var schema = new Schema.Builder()
-                    .Field(f => f.Name("f0").DataType(Int32Type.Default))
-                    .Field(f => f.Name("F0").DataType(Int8Type.Default))
-                    .Build();
-
-                Assert.Equal(2, schema.FieldsList.Count);
-            }
-
-            [Fact]
-            public void FieldNamesCanBeTheSame()
-            {
-                var schema = new Schema.Builder()
-                    .Field(f => f.Name("f0").DataType(Int32Type.Default))
-                    .Field(f => f.Name("f0").DataType(Int8Type.Default))
-                    .Build();
-
-                Assert.Equal(2, schema.FieldsList.Count);
-            }
-
-            [Fact]
-            public void GetFieldIndex()
-            {
-                var schema = new Schema.Builder()
-                    .Field(f => f.Name("f0").DataType(Int32Type.Default))
-                    .Field(f => f.Name("f1").DataType(Int8Type.Default))
-                    .Build();
-
-                Assert.Equal(0, schema.GetFieldIndex("f0"));
-                Assert.Equal(1, schema.GetFieldIndex("f1"));
-            }
-
-            [Fact]
-            public void GetFieldIndexIsCaseSensitive()
-            {
-                var schema = new Schema.Builder()
-                    .Field(f => f.Name("f0").DataType(Int32Type.Default))
-                    .Field(f => f.Name("F0").DataType(Int8Type.Default))
-                    .Build();
-
-                Assert.Equal(0, schema.GetFieldIndex("f0"));
-                Assert.Equal(1, schema.GetFieldIndex("F0"));
-            }
-
-            [Fact]
-            public void GetFieldIndexGetsFirstMatch()
-            {
-                var schema = new Schema.Builder()
-                    .Field(f => f.Name("f0").DataType(Int32Type.Default))
-                    .Field(f => f.Name("f0").DataType(Int8Type.Default))
-                    .Field(f => f.Name("f1").DataType(Int32Type.Default))
-                    .Field(f => f.Name("f1").DataType(Int8Type.Default))
-                    .Build();
-
-                Assert.Equal(0, schema.GetFieldIndex("f0"));
-                Assert.Equal(2, schema.GetFieldIndex("f1"));
-            }
-
-            [Fact]
-            public void GetFieldByName()
-            {
-                Field f0 = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-                Field f1 = new Field.Builder().Name("f1").DataType(Int8Type.Default).Build();
-
-                var schema = new Schema.Builder()
-                    .Field(f0)
-                    .Field(f1)
-                    .Build();
-
-                Assert.Equal(f0, schema.GetFieldByName("f0"));
-                Assert.Equal(f1, schema.GetFieldByName("f1"));
-            }
-
-            [Fact]
-            public void GetFieldByNameIsCaseSensitive()
-            {
-                var f0 = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-                var f0Uppercase = new Field.Builder().Name("F0").DataType(Int8Type.Default).Build();
-
-                var schema = new Schema.Builder()
-                    .Field(f0)
-                    .Field(f0Uppercase)
-                    .Build();
-
-                Assert.Equal(f0, schema.GetFieldByName("f0"));
-                Assert.Equal(f0Uppercase, schema.GetFieldByName("F0"));
-            }
-
-            [Fact]
-            public void GetFieldByNameGetsFirstMatch()
-            {
-                var f0First = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-                var f0Second = new Field.Builder().Name("f0").DataType(Int8Type.Default).Build();
-                var f1First = new Field.Builder().Name("f1").DataType(Int32Type.Default).Build();
-                var f1Second = new Field.Builder().Name("f1").DataType(Int8Type.Default).Build();
-
-                var schema = new Schema.Builder()
-                    .Field(f0First)
-                    .Field(f0Second)
-                    .Field(f1First)
-                    .Field(f1Second)
-                    .Build();
-
-                Assert.Equal(f0First, schema.GetFieldByName("f0"));
-                Assert.Equal(f1First, schema.GetFieldByName("f1"));
-            }
-
-            [Fact]
-            public void GetFieldByNameReturnsNullWhenSchemaIsEmpty()
-            {
-                var schema = new Schema.Builder()
-                    .Build();
-
-                Assert.Null(schema.GetFieldByName("f0"));
-            }
-
-            [Fact]
-            public void GetFieldByNameReturnsNullWhenFieldDoesNotExist()
-            {
-                var schema = new Schema.Builder()
-                    .Field(f => f.Name("f0").DataType(Int32Type.Default))
-                    .Build();
-
-                Assert.Null(schema.GetFieldByName("f1"));
-            }
-
-            [Fact]
-            public void SquareBracketOperatorWithStringReturnsGetFieldByName()
-            {
-                Field f0 = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-                Field f1 = new Field.Builder().Name("f1").DataType(Int8Type.Default).Build();
-
-                var schema = new Schema.Builder()
-                    .Field(f0)
-                    .Field(f1)
-                    .Build();
-
-                Assert.Equal(schema.GetFieldByName("f0"), schema["f0"]);
-                Assert.Equal(schema.GetFieldByName("f1"), schema["f1"]);
-            }
-
-            [Fact]
-            public void SquareBracketOperatorWithIntReturnsGetFieldByIndex()
-            {
-                Field f0 = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-                Field f1 = new Field.Builder().Name("f1").DataType(Int8Type.Default).Build();
-
-                var schema = new Schema.Builder()
-                    .Field(f0)
-                    .Field(f1)
-                    .Build();
-
-                Assert.Equal(schema.GetFieldByIndex(0), schema[0]);
-                Assert.Equal(schema.GetFieldByIndex(1), schema[1]);
-            }
-
-            [Fact]
-            public void MetadataConstruction()
-            {
-
-                var metadata0 = new Dictionary<string, string> { { "foo", "bar" }, { "bizz", "buzz" } };
-                var metadata1 = new Dictionary<string, string> { { "foo", "bar" } };
-                var metadata0Copy = new Dictionary<string, string>(metadata0);
-                var metadata1Copy = new Dictionary<string, string>(metadata1);
-                Field f0 = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-                Field f1 = new Field.Builder().Name("f1").DataType(UInt8Type.Default).Nullable(false).Build();
-                Field f2 = new Field.Builder().Name("f2").DataType(StringType.Default).Build();
-                Field f3 = new Field.Builder().Name("f2").DataType(StringType.Default).Metadata(metadata1Copy).Build();
-
-                var schema0 = new Schema.Builder()
-                    .Field(f0)
-                    .Field(f1)
-                    .Field(f2)
-                    .Metadata(metadata0)
-                    .Build();
-                var schema1 = new Schema.Builder()
-                    .Field(f0)
-                    .Field(f1)
-                    .Field(f2)
-                    .Metadata(metadata1)
-                    .Build();
-                var schema2 = new Schema.Builder()
-                    .Field(f0)
-                    .Field(f1)
-                    .Field(f2)
-                    .Metadata(metadata0Copy)
-                    .Build();
-                var schema3 = new Schema.Builder()
-                    .Field(f0)
-                    .Field(f1)
-                    .Field(f3)
-                    .Metadata(metadata0Copy)
-                    .Build();
-
-                Assert.True(metadata0.Keys.SequenceEqual(schema0.Metadata.Keys) && metadata0.Values.SequenceEqual(schema0.Metadata.Values));
-                Assert.True(metadata1.Keys.SequenceEqual(schema1.Metadata.Keys) && metadata1.Values.SequenceEqual(schema1.Metadata.Values));
-                Assert.True(metadata0.Keys.SequenceEqual(schema2.Metadata.Keys) && metadata0.Values.SequenceEqual(schema2.Metadata.Values));
-                SchemaComparer.Compare(schema0, schema2);
-                Assert.Throws<EqualException>(() => SchemaComparer.Compare(schema0, schema1));
-                Assert.Throws<EqualException>(() => SchemaComparer.Compare(schema2, schema1));
-                Assert.Throws<EqualException>(() => SchemaComparer.Compare(schema2, schema3));
-            }
-
-            [Theory]
-            [MemberData(nameof(SampleSchema1))]
-            public void FieldsHaveExpectedValues(string name, IArrowType type, bool nullable)
-            {
-                var schema = new Schema.Builder()
-                    .Field(f => f.Name(name).DataType(type).Nullable(nullable))
-                    .Build();
-
-                var field = schema.FieldsList[0];
-
-                Assert.Equal(name, field.Name);
-                Assert.Equal(type.Name, field.DataType.Name);
-                Assert.Equal(nullable, field.IsNullable);
-            }
-
-            public static IEnumerable<object[]> SampleSchema1()
-            {
-                yield return new object[] {"f0", Int32Type.Default, true};
-                yield return new object[] {"f1", DoubleType.Default, true};
-                yield return new object[] {"f2", Int64Type.Default, false};
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/SchemaComparer.cs b/csharp/test/Apache.Arrow.Tests/SchemaComparer.cs
deleted file mode 100644
index de860ff..0000000
--- a/csharp/test/Apache.Arrow.Tests/SchemaComparer.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System.Linq;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public static class SchemaComparer
-    {
-        public static void Compare(Schema expected, Schema actual)
-        {
-            if (ReferenceEquals(expected, actual))
-            {
-                return;
-            }
-
-            Assert.Equal(expected.HasMetadata, actual.HasMetadata);
-            if (expected.HasMetadata)
-            {
-                Assert.Equal(expected.Metadata.Keys.Count(), actual.Metadata.Keys.Count());
-                Assert.True(expected.Metadata.Keys.All(k => actual.Metadata.ContainsKey(k) && expected.Metadata[k] == actual.Metadata[k]));
-                Assert.True(actual.Metadata.Keys.All(k => expected.Metadata.ContainsKey(k) && actual.Metadata[k] == expected.Metadata[k]));
-            }
-
-            Assert.Equal(expected.FieldsList.Count, actual.FieldsList.Count);
-            Assert.True(expected.FieldsList.All(f1 => actual.FieldsList.Any(f2 => f2.Name == f1.Name)));
-            foreach (string name in expected.FieldsList.Select(f => f.Name))
-            {
-                FieldComparer.Compare(expected.GetFieldByName(name), actual.GetFieldByName(name));
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/StringArrayTests.cs b/csharp/test/Apache.Arrow.Tests/StringArrayTests.cs
deleted file mode 100644
index b197315..0000000
--- a/csharp/test/Apache.Arrow.Tests/StringArrayTests.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class StringArrayTests
-    {
-        public class GetString
-        {
-            [Theory]
-            [InlineData(null, null)]
-            [InlineData(null, "")]
-            [InlineData(null, "value")]
-            [InlineData("", null)]
-            [InlineData("", "")]
-            [InlineData("", "value")]
-            [InlineData("value", null)]
-            [InlineData("value", "")]
-            [InlineData("value", "value")]
-            public void ReturnsAppendedValue(string firstValue, string secondValue)
-            {
-                // Arrange
-                // Create an array with two elements. The second element being null,
-                // empty, or non-empty may influence the underlying BinaryArray
-                // storage such that retrieving an empty first element could result
-                // in an empty span or a 0-length span backed by storage.
-                var array = new StringArray.Builder()
-                    .Append(firstValue)
-                    .Append(secondValue)
-                    .Build();
-
-                // Act
-                var retrievedValue = array.GetString(0);
-
-                // Assert
-                Assert.Equal(firstValue, retrievedValue);
-            }
-
-            [Theory]
-            [InlineData(null, null)]
-            [InlineData(null, "")]
-            [InlineData(null, "value")]
-            [InlineData("", null)]
-            [InlineData("", "")]
-            [InlineData("", "value")]
-            [InlineData("value", null)]
-            [InlineData("value", "")]
-            [InlineData("value", "value")]
-            public void ReturnsAppendedValueMaterialize(string firstValue, string secondValue)
-            {
-                // Arrange
-                // Create an array with two elements. The second element being null,
-                // empty, or non-empty may influence the underlying BinaryArray
-                // storage such that retrieving an empty first element could result
-                // in an empty span or a 0-length span backed by storage.
-                var array = new StringArray.Builder()
-                    .Append(firstValue)
-                    .Append(secondValue)
-                    .Build();
-
-                // Act
-                array.Materialize();
-                var retrievedValue = array.GetString(0);
-
-                // Assert
-                Assert.True(array.IsMaterialized());
-                Assert.Equal(firstValue, retrievedValue);
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/StructArrayTests.cs b/csharp/test/Apache.Arrow.Tests/StructArrayTests.cs
deleted file mode 100644
index ff5e8d2..0000000
--- a/csharp/test/Apache.Arrow.Tests/StructArrayTests.cs
+++ /dev/null
@@ -1,224 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Ipc;
-using Apache.Arrow.Types;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class StructArrayTests
-    {
-        [Fact]
-        public void TestStructArray()
-        {
-            // The following can be improved with a Builder class for StructArray.
-            List<Field> fields = new List<Field>();
-            Field.Builder fieldBuilder = new Field.Builder();
-            fields.Add(fieldBuilder.Name("Strings").DataType(StringType.Default).Nullable(true).Build());
-            fieldBuilder = new Field.Builder();
-            fields.Add(fieldBuilder.Name("Ints").DataType(Int32Type.Default).Nullable(true).Build());
-            StructType structType = new StructType(fields);
-
-            StringArray.Builder stringBuilder = new StringArray.Builder();
-            StringArray stringArray = stringBuilder.Append("joe").AppendNull().AppendNull().Append("mark").Build();
-            Int32Array.Builder intBuilder = new Int32Array.Builder();
-            Int32Array intArray = intBuilder.Append(1).Append(2).AppendNull().Append(4).Build();
-            List<Array> arrays = new List<Array>();
-            arrays.Add(stringArray);
-            arrays.Add(intArray);
-
-            ArrowBuffer.BitmapBuilder nullBitmap = new ArrowBuffer.BitmapBuilder();
-            var nullBitmapBuffer = nullBitmap.Append(true).Append(true).Append(false).Append(true).Build();
-            StructArray structs = new StructArray(structType, 4, arrays, nullBitmapBuffer, 1);
-
-            Assert.Equal(4, structs.Length);
-            Assert.Equal(1, structs.NullCount);
-            ArrayData[] childArrays = structs.Data.Children; // Data for StringArray and Int32Array
-            Assert.Equal(2, childArrays.Length);
-            for (int i = 0; i < childArrays.Length; i++)
-            {
-                ArrayData arrayData = childArrays[i];
-                Assert.Null(arrayData.Children);
-                if (i == 0)
-                {
-                    Assert.Equal(ArrowTypeId.String, arrayData.DataType.TypeId);
-                    Array array = new StringArray(arrayData);
-                    StringArray structStringArray = array as StringArray;
-                    Assert.NotNull(structStringArray);
-                    Assert.Equal(structs.Length, structStringArray.Length);
-                    Assert.Equal(stringArray.Length, structStringArray.Length);
-                    Assert.Equal(stringArray.NullCount, structStringArray.NullCount);
-                    for (int j = 0; j < stringArray.Length; j++)
-                    {
-                        Assert.Equal(stringArray.GetString(j), structStringArray.GetString(j));
-                    }
-                }
-                if (i == 1)
-                {
-                    Assert.Equal(ArrowTypeId.Int32, arrayData.DataType.TypeId);
-                    Array array = new Int32Array(arrayData);
-                    Int32Array structIntArray = array as Int32Array;
-                    Assert.NotNull(structIntArray);
-                    Assert.Equal(structs.Length, structIntArray.Length);
-                    Assert.Equal(intArray.Length, structIntArray.Length);
-                    Assert.Equal(intArray.NullCount, structIntArray.NullCount);
-                    for (int j = 0; j < intArray.Length; j++)
-                    {
-                        Assert.Equal(intArray.GetValue(j), structIntArray.GetValue(j));
-                    }
-                }
-            }
-        }
-
-        [Fact]
-        public void TestListOfStructArray()
-        {
-            Schema.Builder builder = new Schema.Builder();
-            Field structField = new Field(
-                "struct",
-                new StructType(
-                    new[]
-                    {
-                        new Field("name", StringType.Default, nullable: false),
-                        new Field("age", Int64Type.Default, nullable: false),
-                    }),
-                nullable: false);
-
-            Field listField = new Field("listOfStructs", new ListType(structField), nullable: false);
-            builder.Field(listField);
-            Schema schema = builder.Build();
-
-            StringArray stringArray = new StringArray.Builder()
-                .Append("joe").AppendNull().AppendNull().Append("mark").Append("abe").Append("phil").Build();
-            Int64Array intArray = new Int64Array.Builder()
-                .Append(1).Append(2).AppendNull().Append(4).Append(10).Append(55).Build();
-
-            ArrowBuffer nullBitmapBuffer = new ArrowBuffer.BitmapBuilder()
-                .Append(true).Append(true).Append(false).Append(true).Append(true).Append(true).Build();
-
-            StructArray structs = new StructArray(structField.DataType, 6, new IArrowArray[] { stringArray, intArray }, nullBitmapBuffer, nullCount: 1);
-
-            ArrowBuffer offsetsBuffer = new ArrowBuffer.Builder<int>()
-                .Append(0).Append(2).Append(5).Append(6).Build();
-            ListArray listArray = new ListArray(listField.DataType, 3, offsetsBuffer, structs, ArrowBuffer.Empty);
-
-            RecordBatch batch = new RecordBatch(schema, new[] { listArray }, 3);
-            TestRoundTripRecordBatch(batch);
-        }
-
-        [Fact]
-        public void TestSliceStructArray()
-        {
-            const int numRows = 10;
-            var fields = new List<Field>
-            {
-                new Field.Builder().Name("ints").DataType(new Int32Type()).Nullable(true).Build(),
-                new Field.Builder().Name("doubles").DataType(new DoubleType()).Nullable(true).Build(),
-            };
-            var arrays = new List<IArrowArray>
-            {
-                new Int32Array.Builder().AppendRange(Enumerable.Range(0, numRows)).Build(),
-                new DoubleArray.Builder().AppendRange(Enumerable.Range(0, numRows).Select(i => i * 0.1)).Build(),
-            };
-
-            var nullBitmap = new ArrowBuffer.BitmapBuilder().AppendRange(true, numRows).Build();
-            var array = new StructArray(new StructType(fields), numRows, arrays, nullBitmap, nullCount: 0);
-
-            var slicedArray = (StructArray) array.Slice(3, 4);
-
-            Assert.Equal(4, slicedArray.Length);
-            Assert.Equal(2, slicedArray.Fields.Count);
-
-            var slicedInts = slicedArray.Fields[0];
-            var expectedInts = Enumerable.Range(3, 4).Select(val => (int?) val).ToArray();
-            Assert.Equal(expectedInts, (IReadOnlyList<int?>) slicedInts);
-
-            var slicedDoubles = slicedArray.Fields[1];
-            var expectedDoubles = Enumerable.Range(3, 4).Select(val => (double?) (val * 0.1)).ToArray();
-            Assert.Equal(expectedDoubles, (IReadOnlyList<double?>) slicedDoubles);
-        }
-
-        [Fact]
-        public void TestStructArrayConstructedWithOffset()
-        {
-            const int dataNumRows = 10;
-            const int arrayLength = 4;
-            const int arrayOffset = 3;
-
-            var fields = new List<Field>
-            {
-                new Field.Builder().Name("ints").DataType(new Int32Type()).Nullable(true).Build(),
-                new Field.Builder().Name("doubles").DataType(new DoubleType()).Nullable(true).Build(),
-            };
-            var arrays = new List<IArrowArray>
-            {
-                new Int32Array.Builder().AppendRange(Enumerable.Range(0, dataNumRows)).Build(),
-                new DoubleArray.Builder().AppendRange(Enumerable.Range(0, dataNumRows).Select(i => i * 0.1)).Build(),
-            };
-
-            var nullBitmap = new ArrowBuffer.BitmapBuilder().AppendRange(true, dataNumRows).Build();
-            var array = new StructArray(
-                new StructType(fields), arrayLength, arrays, nullBitmap, nullCount: 0, offset: arrayOffset);
-
-            Assert.Equal(4, array.Length);
-            Assert.Equal(3, array.Offset);
-            Assert.Equal(2, array.Fields.Count);
-
-            var slicedInts = array.Fields[0];
-            var expectedInts = Enumerable.Range(3, 4).Select(val => (int?) val).ToArray();
-            Assert.Equal(expectedInts, (IReadOnlyList<int?>) slicedInts);
-
-            var slicedDoubles = array.Fields[1];
-            var expectedDoubles = Enumerable.Range(3, 4).Select(val => (double?) (val * 0.1)).ToArray();
-            Assert.Equal(expectedDoubles, (IReadOnlyList<double?>) slicedDoubles);
-
-            var subSlice = (StructArray) array.Slice(1, 2);
-            Assert.Equal(2, subSlice.Length);
-            Assert.Equal(2, subSlice.Fields.Count);
-
-            var subSlicedInts = subSlice.Fields[0];
-            var expectedSubSliceInts = Enumerable.Range(4, 2).Select(val => (int?) val).ToArray();
-            Assert.Equal(expectedSubSliceInts, (IReadOnlyList<int?>) subSlicedInts);
-
-            var subSlicedDoubles = subSlice.Fields[1];
-            var expectedSubSliceDoubles = Enumerable.Range(4, 2).Select(val => (double?) (val * 0.1)).ToArray();
-            Assert.Equal(expectedSubSliceDoubles, (IReadOnlyList<double?>) subSlicedDoubles);
-        }
-
-        private static void TestRoundTripRecordBatch(RecordBatch originalBatch)
-        {
-            using (MemoryStream stream = new MemoryStream())
-            {
-                using (var writer = new ArrowStreamWriter(stream, originalBatch.Schema, leaveOpen: true))
-                {
-                    writer.WriteRecordBatch(originalBatch);
-                    writer.WriteEnd();
-                }
-
-                stream.Position = 0;
-
-                using (var reader = new ArrowStreamReader(stream))
-                {
-                    RecordBatch newBatch = reader.ReadNextRecordBatch();
-                    ArrowReaderVerifier.CompareBatches(originalBatch, newBatch);
-                }
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/TableTests.cs b/csharp/test/Apache.Arrow.Tests/TableTests.cs
deleted file mode 100644
index a12e7b9..0000000
--- a/csharp/test/Apache.Arrow.Tests/TableTests.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class TableTests
-    {
-        public static Table MakeTableWithOneColumnOfTwoIntArrays(int lengthOfEachArray)
-        {
-            Array intArray = ColumnTests.MakeIntArray(lengthOfEachArray);
-            Array intArrayCopy = ColumnTests.MakeIntArray(lengthOfEachArray);
-
-            Field field = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-            Schema s0 = new Schema.Builder().Field(field).Build();
-
-            Column column = new Column(field, new List<IArrowArray> { intArray, intArrayCopy });
-            Table table = new Table(s0, new List<Column> { column });
-            return table;
-        }
-
-        [Fact]
-        public void TestEmptyTable()
-        {
-            Table table = new Table();
-            Assert.Equal(0, table.ColumnCount);
-            Assert.Equal(0, table.RowCount);
-        }
-
-        [Fact]
-        public void TestTableBasics()
-        {
-            Table table = MakeTableWithOneColumnOfTwoIntArrays(10);
-            Assert.Equal(20, table.RowCount);
-            Assert.Equal(1, table.ColumnCount);
-            Assert.Equal("Table: 1 columns by 20 rows", table.ToString());
-            Assert.Equal("ChunkedArray: Length=20, DataType=int32", table.Column(0).Data.ToString());
-        }
-
-        [Fact]
-        public void TestTableFromRecordBatches()
-        {
-            RecordBatch recordBatch1 = TestData.CreateSampleRecordBatch(length: 10, true);
-            RecordBatch recordBatch2 = TestData.CreateSampleRecordBatch(length: 10, true);
-            IList<RecordBatch> recordBatches = new List<RecordBatch>() { recordBatch1, recordBatch2 };
-
-            Table table1 = Table.TableFromRecordBatches(recordBatch1.Schema, recordBatches);
-            Assert.Equal(20, table1.RowCount);
-#if NET5_0_OR_GREATER
-            Assert.Equal(40, table1.ColumnCount);
-#else
-            Assert.Equal(39, table1.ColumnCount);
-#endif
-            Assert.Equal("ChunkedArray: Length=20, DataType=list", table1.Column(0).Data.ToString());
-
-            FixedSizeBinaryType type = new FixedSizeBinaryType(17);
-            Field newField1 = new Field(type.Name, type, false);
-            Schema newSchema1 = recordBatch1.Schema.SetField(20, newField1);
-            Assert.Throws<ArgumentException>(() => Table.TableFromRecordBatches(newSchema1, recordBatches));
-
-            List<Field> fields = new List<Field>();
-            Field.Builder fieldBuilder = new Field.Builder();
-            fields.Add(fieldBuilder.Name("Ints").DataType(Int32Type.Default).Nullable(true).Build());
-            fieldBuilder = new Field.Builder();
-            fields.Add(fieldBuilder.Name("Strings").DataType(StringType.Default).Nullable(true).Build());
-            StructType structType = new StructType(fields);
-
-            Field newField2 = new Field(structType.Name, structType, false);
-            Schema newSchema2 = recordBatch1.Schema.SetField(16, newField2);
-            Assert.Throws<ArgumentException>(() => Table.TableFromRecordBatches(newSchema2, recordBatches));
-        }
-
-        [Fact]
-        public void TestTableAddRemoveAndSetColumn()
-        {
-            Table table = MakeTableWithOneColumnOfTwoIntArrays(10);
-            Assert.Equal("Table: 1 columns by 20 rows", table.ToString());
-            Assert.Equal("Field: Name=f0, DataType=int32, IsNullable=True, Metadata count=0", table.Column(0).Field.ToString());
-            Assert.Equal("ChunkedArray: Length=20, DataType=int32", table.Column(0).Data.ToString());
-
-            Array nonEqualLengthIntArray = ColumnTests.MakeIntArray(10);
-            Field field1 = new Field.Builder().Name("f1").DataType(Int32Type.Default).Build();
-            Column nonEqualLengthColumn = new Column(field1, new IArrowArray[] { nonEqualLengthIntArray });
-            Assert.Throws<ArgumentException>(() => table.InsertColumn(-1, nonEqualLengthColumn));
-            Assert.Throws<ArgumentException>(() => table.InsertColumn(1, nonEqualLengthColumn));
-
-            Array equalLengthIntArray = ColumnTests.MakeIntArray(20);
-            Field field2 = new Field.Builder().Name("f2").DataType(Int32Type.Default).Build();
-            Column equalLengthColumn = new Column(field2, new IArrowArray[] { equalLengthIntArray });
-            Column existingColumn = table.Column(0);
-
-            Table newTable = table.InsertColumn(0, equalLengthColumn);
-            Assert.Equal(2, newTable.ColumnCount);
-            Assert.True(newTable.Column(0) == equalLengthColumn);
-            Assert.True(newTable.Column(1) == existingColumn);
-
-            newTable = newTable.RemoveColumn(1);
-            Assert.Equal(1, newTable.ColumnCount);
-            Assert.True(newTable.Column(0) == equalLengthColumn);
-
-            newTable = table.SetColumn(0, existingColumn);
-            Assert.True(newTable.Column(0) == existingColumn);
-        }
-
-        [Fact]
-        public void TestBuildFromRecordBatch()
-        {
-            Schema.Builder builder = new Schema.Builder();
-            builder.Field(new Field("A", Int64Type.Default, nullable: false));
-            Schema schema = builder.Build();
-
-            RecordBatch batch = TestData.CreateSampleRecordBatch(schema, 10);
-            Table table = Table.TableFromRecordBatches(schema, new[] { batch });
-
-            Assert.NotNull(table.Column(0).Data.ArrowArray(0) as Int64Array);
-        }
-    }
-
-}
diff --git a/csharp/test/Apache.Arrow.Tests/TestData.cs b/csharp/test/Apache.Arrow.Tests/TestData.cs
deleted file mode 100644
index 08ada33..0000000
--- a/csharp/test/Apache.Arrow.Tests/TestData.cs
+++ /dev/null
@@ -1,809 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Arrays;
-using Apache.Arrow.Scalars;
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Apache.Arrow.Tests
-{
-    public static class TestData
-    {
-        public static RecordBatch CreateSampleRecordBatch(int length, bool createDictionaryArray)
-        {
-            HashSet<ArrowTypeId> excluded = createDictionaryArray ? null : new HashSet<ArrowTypeId> { ArrowTypeId.Dictionary };
-            return CreateSampleRecordBatch(length, columnSetCount: 1, excluded);
-        }
-
-        public static RecordBatch CreateSampleRecordBatch(
-            int length,
-            int columnSetCount = 1,
-            HashSet<ArrowTypeId> excludedTypes = null)
-        {
-            Schema.Builder builder = new Schema.Builder();
-
-            void AddField(Field field)
-            {
-                if (excludedTypes == null || !excludedTypes.Contains(field.DataType.TypeId))
-                {
-                    builder.Field(field);
-                }
-            }
-
-            for (int i = 0; i < columnSetCount; i++)
-            {
-                AddField(CreateField(new ListType(Int64Type.Default), i));
-                AddField(CreateField(new ListViewType(Int64Type.Default), i));
-                AddField(CreateField(new LargeListType(Int64Type.Default), i));
-                AddField(CreateField(BooleanType.Default, i));
-                AddField(CreateField(UInt8Type.Default, i));
-                AddField(CreateField(Int8Type.Default, i));
-                AddField(CreateField(UInt16Type.Default, i));
-                AddField(CreateField(Int16Type.Default, i));
-                AddField(CreateField(UInt32Type.Default, i));
-                AddField(CreateField(Int32Type.Default, i));
-                AddField(CreateField(UInt64Type.Default, i));
-                AddField(CreateField(Int64Type.Default, i));
-#if NET5_0_OR_GREATER
-                AddField(CreateField(HalfFloatType.Default, i));
-#endif
-                AddField(CreateField(FloatType.Default, i));
-                AddField(CreateField(DoubleType.Default, i));
-                AddField(CreateField(Date32Type.Default, i));
-                AddField(CreateField(Date64Type.Default, i));
-                AddField(CreateField(Time32Type.Default, i));
-                AddField(CreateField(Time64Type.Default, i));
-                AddField(CreateField(TimestampType.Default, i));
-                AddField(CreateField(StringType.Default, i));
-                AddField(CreateField(StringViewType.Default, i));
-                AddField(CreateField(new StructType(new List<Field> { CreateField(StringType.Default, i), CreateField(Int32Type.Default, i) }), i));
-                AddField(CreateField(new Decimal32Type(9, 2), i));
-                AddField(CreateField(new Decimal64Type(10, 4), i));
-                AddField(CreateField(new Decimal128Type(10, 6), i));
-                AddField(CreateField(new Decimal256Type(16, 8), i));
-                AddField(CreateField(new MapType(StringType.Default, Int32Type.Default), i));
-                AddField(CreateField(IntervalType.YearMonth, i));
-                AddField(CreateField(IntervalType.DayTime, i));
-                AddField(CreateField(IntervalType.MonthDayNanosecond, i));
-                AddField(CreateField(BinaryType.Default, i));
-                AddField(CreateField(BinaryViewType.Default, i));
-                AddField(CreateField(new FixedSizeBinaryType(16), i));
-                AddField(CreateField(new FixedSizeListType(Int32Type.Default, 3), i));
-                AddField(CreateField(new UnionType(new[] { CreateField(StringType.Default, i), CreateField(Int32Type.Default, i) }, new[] { 0, 1 }, UnionMode.Sparse), i));
-                AddField(CreateField(new UnionType(new[] { CreateField(StringType.Default, i), CreateField(Int32Type.Default, i) }, new[] { 0, 1 }, UnionMode.Dense), -i));
-                AddField(CreateField(new DictionaryType(Int32Type.Default, StringType.Default, false), i));
-                AddField(CreateField(new LargeBinaryType(), i));
-                AddField(CreateField(new LargeStringType(), i));
-            }
-
-            Schema schema = builder.Build();
-
-            return CreateSampleRecordBatch(schema, length);
-        }
-
-        public static RecordBatch CreateSampleRecordBatch(Schema schema, int length)
-        {
-            IEnumerable<IArrowArray> arrays = CreateArrays(schema, length);
-
-            return new RecordBatch(schema, arrays, length);
-        }
-
-        private static Field CreateField(ArrowType type, int iteration)
-        {
-            return new Field(type.Name + iteration, type, nullable: false);
-        }
-
-        public static IEnumerable<IArrowArray> CreateArrays(Schema schema, int length)
-        {
-            int fieldCount = schema.FieldsList.Count;
-            List<IArrowArray> arrays = new List<IArrowArray>(fieldCount);
-            for (int i = 0; i < fieldCount; i++)
-            {
-                Field field = schema.GetFieldByIndex(i);
-                arrays.Add(CreateArray(field, length));
-            }
-            return arrays;
-        }
-
-        private static IArrowArray CreateArray(Field field, int length)
-        {
-            var creator = new ArrayCreator(length);
-
-            field.DataType.Accept(creator);
-
-            return creator.Array;
-        }
-
-        private class ArrayCreator :
-            IArrowTypeVisitor<BooleanType>,
-            IArrowTypeVisitor<Date32Type>,
-            IArrowTypeVisitor<Date64Type>,
-            IArrowTypeVisitor<Time32Type>,
-            IArrowTypeVisitor<Time64Type>,
-            IArrowTypeVisitor<DurationType>,
-            IArrowTypeVisitor<Int8Type>,
-            IArrowTypeVisitor<Int16Type>,
-            IArrowTypeVisitor<Int32Type>,
-            IArrowTypeVisitor<Int64Type>,
-            IArrowTypeVisitor<UInt8Type>,
-            IArrowTypeVisitor<UInt16Type>,
-            IArrowTypeVisitor<UInt32Type>,
-            IArrowTypeVisitor<UInt64Type>,
-            IArrowTypeVisitor<FloatType>,
-            IArrowTypeVisitor<DoubleType>,
-            IArrowTypeVisitor<TimestampType>,
-            IArrowTypeVisitor<StringType>,
-            IArrowTypeVisitor<StringViewType>,
-            IArrowTypeVisitor<LargeStringType>,
-            IArrowTypeVisitor<ListType>,
-            IArrowTypeVisitor<ListViewType>,
-            IArrowTypeVisitor<LargeListType>,
-            IArrowTypeVisitor<FixedSizeListType>,
-            IArrowTypeVisitor<StructType>,
-            IArrowTypeVisitor<UnionType>,
-            IArrowTypeVisitor<Decimal32Type>,
-            IArrowTypeVisitor<Decimal64Type>,
-            IArrowTypeVisitor<Decimal128Type>,
-            IArrowTypeVisitor<Decimal256Type>,
-            IArrowTypeVisitor<DictionaryType>,
-            IArrowTypeVisitor<BinaryType>,
-            IArrowTypeVisitor<BinaryViewType>,
-            IArrowTypeVisitor<LargeBinaryType>,
-            IArrowTypeVisitor<FixedSizeBinaryType>,
-            IArrowTypeVisitor<MapType>,
-            IArrowTypeVisitor<IntervalType>,
-#if NET5_0_OR_GREATER
-            IArrowTypeVisitor<HalfFloatType>,
-#endif
-            IArrowTypeVisitor<NullType>
-        {
-            private int Length { get; }
-            public IArrowArray Array { get; private set; }
-
-            public ArrayCreator(int length)
-            {
-                Length = length;
-            }
-
-            public void Visit(BooleanType type) => GenerateArray(new BooleanArray.Builder(), x => x % 2 == 0);
-            public void Visit(Int8Type type) => GenerateArray(new Int8Array.Builder(), x => (sbyte)x);
-            public void Visit(Int16Type type) => GenerateArray(new Int16Array.Builder(), x => (short)x);
-            public void Visit(Int32Type type) => GenerateArray(new Int32Array.Builder(), x => x);
-            public void Visit(Int64Type type) => GenerateArray(new Int64Array.Builder(), x => x);
-            public void Visit(UInt8Type type) => GenerateArray(new UInt8Array.Builder(), x => (byte)x);
-            public void Visit(UInt16Type type) => GenerateArray(new UInt16Array.Builder(), x => (ushort)x);
-            public void Visit(UInt32Type type) => GenerateArray(new UInt32Array.Builder(), x => (uint)x);
-            public void Visit(UInt64Type type) => GenerateArray(new UInt64Array.Builder(), x => (ulong)x);
-            public void Visit(FloatType type) => GenerateArray(new FloatArray.Builder(), x => ((float)x / Length));
-#if NET5_0_OR_GREATER
-            public void Visit(HalfFloatType type) => GenerateArray(new HalfFloatArray.Builder(), x => ((Half)x / (Half)Length));
-#endif
-            public void Visit(DoubleType type) => GenerateArray(new DoubleArray.Builder(), x => ((double)x / Length));
-
-            public void Visit(Decimal32Type type)
-            {
-                var builder = new Decimal32Array.Builder(type).Reserve(Length);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append((decimal)i / Length);
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(Decimal64Type type)
-            {
-                var builder = new Decimal64Array.Builder(type).Reserve(Length);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append((decimal)i / Length);
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(Decimal128Type type)
-            {
-                var builder = new Decimal128Array.Builder(type).Reserve(Length);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append((decimal)i / Length);
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(Decimal256Type type)
-            {
-                var builder = new Decimal256Array.Builder(type).Reserve(Length);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append((decimal)i / Length);
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(Date32Type type)
-            {
-                var builder = new Date32Array.Builder().Reserve(Length);
-
-                // Length can be greater than the number of days since DateTime.MinValue.
-                // Set a cap for how many days can be subtracted from now.
-                int maxDays = Math.Min(Length, 100_000);
-                var basis = DateTimeOffset.UtcNow.AddDays(-maxDays);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append(basis.AddDays(i % maxDays));
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(Date64Type type)
-            {
-                var builder = new Date64Array.Builder().Reserve(Length);
-                var basis = DateTimeOffset.UtcNow.AddSeconds(-Length);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append(basis.AddSeconds(i));
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(Time32Type type)
-            {
-                var builder = new Time32Array.Builder(type).Reserve(Length);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append(i);
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(Time64Type type)
-            {
-                var builder = new Time64Array.Builder(type).Reserve(Length);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append(i);
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(DurationType type)
-            {
-                var builder = new DurationArray.Builder(type).Reserve(Length);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append(i);
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(TimestampType type)
-            {
-                var builder = new TimestampArray.Builder().Reserve(Length);
-                var basis = DateTimeOffset.UtcNow.AddMilliseconds(-Length);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append(basis.AddMilliseconds(i));
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(StringType type)
-            {
-                var str = "hello";
-                var builder = new StringArray.Builder();
-
-                for (var i = 0; i < Length; i++)
-                {
-                    switch (i % 3)
-                    {
-                        case 0:
-                            builder.AppendNull();
-                            break;
-                        case 1:
-                            builder.Append(str);
-                            break;
-                        case 2:
-                            builder.Append(str + str);
-                            break;
-                    }
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(StringViewType type)
-            {
-                var str = "length=ten";
-                var builder = new StringViewArray.Builder();
-
-                for (var i = 0; i < Length; i++)
-                {
-                    switch (i % 3)
-                    {
-                        case 0:
-                            builder.AppendNull();
-                            break;
-                        case 1:
-                            builder.Append(str);
-                            break;
-                        case 2:
-                            builder.Append(str + str);
-                            break;
-                    }
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(LargeStringType type)
-            {
-                var str = "hello";
-                var valueBuffer = new ArrowBuffer.Builder<byte>();
-                var offsetBuffer = new ArrowBuffer.Builder<long>();
-                var validityBuffer = new ArrowBuffer.BitmapBuilder();
-
-                long offset = 0;
-                offsetBuffer.Append(offset);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    switch (i % 3)
-                    {
-                        case 0:
-                            offsetBuffer.Append(offset);
-                            validityBuffer.Append(false);
-                            break;
-                        case 1:
-                            valueBuffer.Append(LargeStringArray.DefaultEncoding.GetBytes(str));
-                            offset += str.Length;
-                            offsetBuffer.Append(offset);
-                            validityBuffer.Append(true);
-                            break;
-                        case 2:
-                            valueBuffer.Append(LargeStringArray.DefaultEncoding.GetBytes(str + str));
-                            offset += str.Length * 2;
-                            offsetBuffer.Append(offset);
-                            validityBuffer.Append(true);
-                            break;
-                    }
-                }
-
-                var validity = validityBuffer.UnsetBitCount > 0 ? validityBuffer.Build() : ArrowBuffer.Empty;
-                Array = new LargeStringArray(
-                    Length, offsetBuffer.Build(), valueBuffer.Build(), validity,
-                    validityBuffer.UnsetBitCount);
-            }
-
-            public void Visit(ListType type)
-            {
-                var builder = new ListArray.Builder(type.ValueField).Reserve(Length);
-
-                var valueBuilder = (Int64Array.Builder)builder.ValueBuilder.Reserve(Length * 3 / 2);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    if (i % 10 == 2)
-                    {
-                        builder.AppendNull();
-                    }
-                    else
-                    {
-                        builder.Append();
-                        var listLength = i % 4;
-                        valueBuilder.AppendRange(Enumerable.Range(i, listLength).Select(x => (long)x));
-                    }
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(ListViewType type)
-            {
-                var builder = new ListViewArray.Builder(type.ValueField).Reserve(Length);
-
-                var valueBuilder = (Int64Array.Builder)builder.ValueBuilder.Reserve(Length + 1);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append();
-                    valueBuilder.Append(i);
-                }
-
-                if (Length > 0)
-                {
-                    // Add a value to check if Values.Length can exceed ListArray.Length
-                    valueBuilder.Append(0);
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(LargeListType type)
-            {
-                var valueBuilder = new Int64Array.Builder().Reserve(Length * 3 / 2);
-                var offsetBuffer = new ArrowBuffer.Builder<long>();
-                var validityBuffer = new ArrowBuffer.BitmapBuilder();
-
-                offsetBuffer.Append(0);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    if (i % 10 == 2)
-                    {
-                        offsetBuffer.Append(valueBuilder.Length);
-                        validityBuffer.Append(false);
-                    }
-                    else
-                    {
-                        var listLength = i % 4;
-                        valueBuilder.AppendRange(Enumerable.Range(i, listLength).Select(x => (long)x));
-                        offsetBuffer.Append(valueBuilder.Length);
-                        validityBuffer.Append(true);
-                    }
-                }
-
-                var validity = validityBuffer.UnsetBitCount > 0 ? validityBuffer.Build() : ArrowBuffer.Empty;
-                Array = new LargeListArray(
-                    new LargeListType(new Int64Type()), Length,
-                    offsetBuffer.Build(), valueBuilder.Build(), validity,
-                    validityBuffer.UnsetBitCount);
-            }
-
-            public void Visit(FixedSizeListType type)
-            {
-                var builder = new FixedSizeListArray.Builder(type.ValueField, type.ListSize).Reserve(Length);
-
-                var valueBuilder = (Int32Array.Builder)builder.ValueBuilder;
-
-                for (var i = 0; i < Length; i++)
-                {
-                    if (type.Fields[0].IsNullable && (i % 3) == 0)
-                    {
-                        builder.AppendNull();
-                    }
-                    else
-                    {
-                        builder.Append();
-                        for (var j = 0; j < type.ListSize; j++)
-                        {
-                            valueBuilder.Append(i * type.ListSize + j);
-                        }
-                    }
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(StructType type)
-            {
-                IArrowArray[] childArrays = new IArrowArray[type.Fields.Count];
-                for (int i = 0; i < childArrays.Length; i++)
-                {
-                    childArrays[i] = CreateArray(type.Fields[i], Length);
-                }
-
-                ArrowBuffer.BitmapBuilder nullBitmap = new ArrowBuffer.BitmapBuilder();
-                for (int i = 0; i < Length; i++)
-                {
-                    nullBitmap.Append(true);
-                }
-
-                Array = new StructArray(type, Length, childArrays, nullBitmap.Build());
-            }
-
-            public void Visit(UnionType type)
-            {
-                int[] lengths = new int[type.Fields.Count];
-                if (type.Mode == UnionMode.Sparse)
-                {
-                    for (int i = 0; i < lengths.Length; i++)
-                    {
-                        lengths[i] = Length;
-                    }
-                }
-                else
-                {
-                    int totalLength = Length;
-                    int oneLength = Length / lengths.Length;
-                    for (int i = 1; i < lengths.Length; i++)
-                    {
-                        lengths[i] = oneLength;
-                        totalLength -= oneLength;
-                    }
-                    lengths[0] = totalLength;
-                }
-
-                ArrayData[] childArrays = new ArrayData[type.Fields.Count];
-                for (int i = 0; i < childArrays.Length; i++)
-                {
-                    childArrays[i] = CreateArray(type.Fields[i], lengths[i]).Data;
-                }
-
-                ArrowBuffer.Builder<byte> typeIdBuilder = new ArrowBuffer.Builder<byte>(Length);
-                byte index = 0;
-                for (int i = 0; i < Length; i++)
-                {
-                    typeIdBuilder.Append(index);
-                    index++;
-                    if (index == lengths.Length)
-                    {
-                        index = 0;
-                    }
-                }
-
-                ArrowBuffer[] buffers;
-                if (type.Mode == UnionMode.Sparse)
-                {
-                    buffers = new ArrowBuffer[1];
-                }
-                else
-                {
-                    ArrowBuffer.Builder<int> offsetBuilder = new ArrowBuffer.Builder<int>(Length);
-                    for (int i = 0; i < Length; i++)
-                    {
-                        offsetBuilder.Append(i / lengths.Length);
-                    }
-
-                    buffers = new ArrowBuffer[2];
-                    buffers[1] = offsetBuilder.Build();
-                }
-                buffers[0] = typeIdBuilder.Build();
-
-                Array = UnionArray.Create(new ArrayData(type, Length, 0, 0, buffers, childArrays));
-            }
-
-            public void Visit(DictionaryType type)
-            {
-                Int32Array.Builder indicesBuilder = new Int32Array.Builder().Reserve(Length);
-                StringArray.Builder valueBuilder = new StringArray.Builder().Reserve(Length);
-
-                for (int i = 0; i < Length; i++)
-                {
-                    indicesBuilder.Append(i);
-                    valueBuilder.Append($"{i}");
-                }
-
-                Array = new DictionaryArray(type, indicesBuilder.Build(), valueBuilder.Build());
-            }
-
-            public void Visit(BinaryType type)
-            {
-                ReadOnlySpan<byte> shortData = new[] { (byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7, (byte)8, (byte)9 };
-                ReadOnlySpan<byte> longData = new[]
-                {
-                    (byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7, (byte)8, (byte)9,
-                    (byte)10, (byte)11, (byte)12, (byte)13, (byte)14, (byte)15, (byte)16, (byte)17, (byte)18, (byte)19
-                };
-                var builder = new BinaryArray.Builder();
-
-                for (var i = 0; i < Length; i++)
-                {
-                    switch (i % 3)
-                    {
-                        case 0:
-                            builder.AppendNull();
-                            break;
-                        case 1:
-                            builder.Append(shortData);
-                            break;
-                        case 2:
-                            builder.Append(longData);
-                            break;
-                    }
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(BinaryViewType type)
-            {
-                ReadOnlySpan<byte> shortData = new[] { (byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7, (byte)8, (byte)9 };
-                ReadOnlySpan<byte> longData = new[]
-                {
-                    (byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7, (byte)8, (byte)9,
-                    (byte)10, (byte)11, (byte)12, (byte)13, (byte)14, (byte)15, (byte)16, (byte)17, (byte)18, (byte)19
-                };
-                var builder = new BinaryViewArray.Builder();
-
-                for (var i = 0; i < Length; i++)
-                {
-                    switch (i % 3)
-                    {
-                        case 0:
-                            builder.AppendNull();
-                            break;
-                        case 1:
-                            builder.Append(shortData);
-                            break;
-                        case 2:
-                            builder.Append(longData);
-                            break;
-                    }
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(LargeBinaryType type)
-            {
-                ReadOnlySpan<byte> shortData = new[] { (byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7, (byte)8, (byte)9 };
-                ReadOnlySpan<byte> longData = new[]
-                {
-                    (byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7, (byte)8, (byte)9,
-                    (byte)10, (byte)11, (byte)12, (byte)13, (byte)14, (byte)15, (byte)16, (byte)17, (byte)18, (byte)19
-                };
-                var valueBuffer = new ArrowBuffer.Builder<byte>();
-                var offsetBuffer = new ArrowBuffer.Builder<long>();
-                var validityBuffer = new ArrowBuffer.BitmapBuilder();
-
-                offsetBuffer.Append(0L);
-
-                for (var i = 0; i < Length; i++)
-                {
-                    switch (i % 3)
-                    {
-                        case 0:
-                            offsetBuffer.Append(valueBuffer.Length);
-                            validityBuffer.Append(false);
-                            break;
-                        case 1:
-                            valueBuffer.Append(shortData);
-                            offsetBuffer.Append(valueBuffer.Length);
-                            validityBuffer.Append(true);
-                            break;
-                        case 2:
-                            valueBuffer.Append(longData);
-                            offsetBuffer.Append(valueBuffer.Length);
-                            validityBuffer.Append(true);
-                            break;
-                    }
-                }
-
-                var validity = validityBuffer.UnsetBitCount > 0 ? validityBuffer.Build() : ArrowBuffer.Empty;
-                Array = new LargeBinaryArray(
-                    LargeBinaryType.Default, Length,
-                    offsetBuffer.Build(), valueBuffer.Build(), validity,
-                    validityBuffer.UnsetBitCount);
-            }
-
-            public void Visit(FixedSizeBinaryType type)
-            {
-                ArrowBuffer.Builder<byte> valueBuilder = new ArrowBuffer.Builder<byte>();
-
-                int valueSize = type.BitWidth;
-                for (int i = 0; i < Length; i++)
-                {
-                    valueBuilder.Append(Enumerable.Repeat((byte)i, valueSize).ToArray());
-                }
-
-                ArrowBuffer validityBuffer = ArrowBuffer.Empty;
-                ArrowBuffer valueBuffer = valueBuilder.Build(default);
-
-                ArrayData arrayData = new ArrayData(type, Length, 0, 0, new[] { validityBuffer, valueBuffer });
-                Array = new FixedSizeBinaryArray(arrayData);
-            }
-
-            public void Visit(MapType type)
-            {
-                MapArray.Builder builder = new MapArray.Builder(type).Reserve(Length);
-                var keyBuilder = builder.KeyBuilder.Reserve(Length + 1) as StringArray.Builder;
-                var valueBuilder = builder.ValueBuilder.Reserve(Length + 1) as Int32Array.Builder;
-
-                for (var i = 0; i < Length; i++)
-                {
-                    builder.Append();
-                    keyBuilder.Append(i.ToString());
-                    valueBuilder.Append(i);
-                }
-
-                if (Length > 0)
-                {
-                    // Add a value to check if Values.Length can exceed MapArray.Length
-                    keyBuilder.Append("0");
-                    valueBuilder.Append(0);
-                }
-
-                Array = builder.Build();
-            }
-
-            public void Visit(IntervalType type)
-            {
-                switch (type.Unit)
-                {
-                    case IntervalUnit.YearMonth:
-                        var yearMonthBuilder = new YearMonthIntervalArray.Builder().Reserve(Length);
-                        for (var i = 0; i < Length; i++)
-                        {
-                            yearMonthBuilder.Append(new YearMonthInterval(i));
-                        }
-                        Array = yearMonthBuilder.Build();
-                        break;
-                    case IntervalUnit.DayTime:
-                        var dayTimeBuilder = new DayTimeIntervalArray.Builder().Reserve(Length);
-                        for (var i = 0; i < Length; i++)
-                        {
-                            dayTimeBuilder.Append(new DayTimeInterval(100 - 50*i, 100 * i));
-                        }
-                        Array = dayTimeBuilder.Build();
-                        break;
-                    case IntervalUnit.MonthDayNanosecond:
-                        var monthDayNanoBuilder = new MonthDayNanosecondIntervalArray.Builder().Reserve(Length);
-                        for (var i = 0; i < Length; i++)
-                        {
-                            monthDayNanoBuilder.Append(new MonthDayNanosecondInterval(i, 5-i, 100*i));
-                        }
-                        Array = monthDayNanoBuilder.Build();
-                        break;
-                    default:
-                        throw new InvalidOperationException($"unsupported interval unit <{type.Unit}>");
-                }
-            }
-
-            public void Visit(NullType type)
-            {
-                Array = new NullArray(Length);
-            }
-
-            private void GenerateArray<T, TArray, TArrayBuilder>(IArrowArrayBuilder<T, TArray, TArrayBuilder> builder, Func<int, T> generator)
-                where TArrayBuilder : IArrowArrayBuilder<T, TArray, TArrayBuilder>
-                where TArray : IArrowArray
-                where T : struct
-            {
-                for (var i = 0; i < Length; i++)
-                {
-                    if (i == Length - 2)
-                    {
-                        builder.AppendNull();
-                    }
-                    else
-                    {
-                        var value = generator(i);
-                        builder.Append(value);
-                    }
-                }
-
-                Array = builder.Build(default);
-            }
-
-            public void Visit(IArrowType type)
-            {
-                throw new NotImplementedException();
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/TestDateAndTimeData.cs b/csharp/test/Apache.Arrow.Tests/TestDateAndTimeData.cs
deleted file mode 100644
index 8a8f76b..0000000
--- a/csharp/test/Apache.Arrow.Tests/TestDateAndTimeData.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Apache.Arrow.Tests
-{
-    /// <summary>
-    /// The <see cref="TestDateAndTimeData"/> class holds example dates and times useful for testing.
-    /// </summary>
-    internal static class TestDateAndTimeData
-    {
-        private static readonly DateTime _earliestDate = new DateTime(1, 1, 1);
-        private static readonly DateTime _latestDate = new DateTime(9999, 12, 31);
-
-        private static readonly DateTime[] _exampleDates =
-        {
-            _earliestDate, new DateTime(1969, 12, 31), new DateTime(1970, 1, 1), new DateTime(1970, 1, 2),
-            new DateTime(1972, 6, 30), new DateTime(2015, 6, 30), new DateTime(2016, 12, 31), new DateTime(2020, 2, 29),
-            new DateTime(2020, 7, 1), _latestDate,
-        };
-
-        private static readonly TimeSpan[] _exampleTimes =
-        {
-            new TimeSpan(0, 0, 0), new TimeSpan(0, 0, 1), new TimeSpan(12, 0, 0), new TimeSpan(23, 59, 59),
-        };
-
-        private static readonly DateTimeKind[] _exampleKinds =
-        {
-            DateTimeKind.Local, DateTimeKind.Unspecified, DateTimeKind.Utc,
-        };
-
-        private static readonly TimeSpan[] _exampleOffsets =
-        {
-            TimeSpan.FromHours(-2),
-            TimeSpan.Zero,
-            TimeSpan.FromHours(2),
-        };
-
-        /// <summary>
-        /// Gets a collection of example dates (i.e. with a zero time component), of all different kinds.
-        /// </summary>
-        public static IEnumerable<DateTime> ExampleDates =>
-            from date in _exampleDates
-            from kind in _exampleKinds
-            select DateTime.SpecifyKind(date, kind);
-
-        /// <summary>
-        /// Gets a collection of example times
-        /// </summary>
-        public static IEnumerable<TimeSpan> ExampleTimes => _exampleTimes;
-
-        /// <summary>
-        /// Gets a collection of example date/times, of all different kinds.
-        /// </summary>
-        public static IEnumerable<DateTime> ExampleDateTimes =>
-            from date in _exampleDates
-            from time in _exampleTimes
-            from kind in _exampleKinds
-            select DateTime.SpecifyKind(date.Add(time), kind);
-
-        /// <summary>
-        /// Gets a collection of example date time offsets.
-        /// </summary>
-        /// <returns></returns>
-        public static IEnumerable<DateTimeOffset> ExampleDateTimeOffsets =>
-            from date in _exampleDates
-            from time in _exampleTimes
-            from offset in _exampleOffsets
-            where !(date == _earliestDate && offset.Ticks > 0)
-            where !(date == _latestDate && offset.Ticks < 0)
-            select new DateTimeOffset(date.Add(time), offset);
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/TestMemoryAllocator.cs b/csharp/test/Apache.Arrow.Tests/TestMemoryAllocator.cs
deleted file mode 100644
index 0243c39..0000000
--- a/csharp/test/Apache.Arrow.Tests/TestMemoryAllocator.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using Apache.Arrow.Memory;
-using System.Buffers;
-using System.Threading;
-
-namespace Apache.Arrow.Tests
-{
-    public class TestMemoryAllocator : MemoryAllocator
-    {
-        private int _rented = 0;
-        public int Rented => _rented;
-
-        protected override IMemoryOwner<byte> AllocateInternal(int length, out int bytesAllocated)
-        {
-            var mem = MemoryPool<byte>.Shared.Rent(length);
-            bytesAllocated = mem.Memory.Length;
-            Interlocked.Increment(ref _rented);
-            return new TestMemoryOwner(mem, this);
-        }
-
-        private class TestMemoryOwner : IMemoryOwner<byte>
-        {
-            private readonly IMemoryOwner<byte> _inner;
-            private readonly TestMemoryAllocator _allocator;
-            private bool _disposed;
-
-            public TestMemoryOwner(IMemoryOwner<byte> inner, TestMemoryAllocator allocator)
-            {
-                _inner = inner;
-                _allocator = allocator;
-            }
-
-            public Memory<byte> Memory
-            {
-                get
-                {
-                    if (_disposed)
-                        throw new ObjectDisposedException(nameof(TestMemoryOwner));
-                    return _inner.Memory;
-                }
-            }
-
-            public void Dispose()
-            {
-                if (_disposed)
-                    return;
-                _disposed = true;
-                Interlocked.Decrement(ref _allocator._rented);
-                _inner?.Dispose();
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/TimeOnlyTests.cs b/csharp/test/Apache.Arrow.Tests/TimeOnlyTests.cs
deleted file mode 100644
index cd66530..0000000
--- a/csharp/test/Apache.Arrow.Tests/TimeOnlyTests.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests
-{
-    public class TimeOnlyTests
-    {
-        private static IEnumerable<object[]> GetTimeOnlyData(params TimeUnit[] units) =>
-            from time in TestDateAndTimeData.ExampleTimes
-            from unit in units
-            select new object[] { TimeOnly.FromTimeSpan(time), unit };
-
-        public class Time32
-        {
-            public static IEnumerable<object[]> GetTestData => GetTimeOnlyData(TimeUnit.Second, TimeUnit.Millisecond);
-
-            [Fact]
-            public void AppendThenGetGivesNull()
-            {
-                // Arrange
-                var builder = new Time32Array.Builder();
-
-                // Act
-                builder = builder.AppendNull();
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Null(array.GetTime(0));
-                Assert.Null(array.GetValue(0));
-            }
-
-            [Theory]
-            [MemberData(nameof(GetTestData))]
-            public void AppendTimeGivesSameTime(TimeOnly time, TimeUnit timeUnit)
-            {
-                // Arrange
-                var builder = new Time32Array.Builder(timeUnit);
-                var expectedTime = time;
-                int expectedMilliseconds = (int)(time.Ticks / TimeSpan.TicksPerMillisecond);
-
-                // Act
-                builder = builder.Append(time);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(expectedTime, array.GetTime(0));
-                Assert.Equal(expectedMilliseconds, array.GetMilliSeconds(0));
-            }
-        }
-
-        public class Time64
-        {
-            public static IEnumerable<object[]> GetTestData => GetTimeOnlyData(TimeUnit.Microsecond, TimeUnit.Nanosecond);
-
-            [Fact]
-            public void AppendThenGetGivesNull()
-            {
-                // Arrange
-                var builder = new Time64Array.Builder();
-
-                // Act
-                builder = builder.AppendNull();
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Null(array.GetTime(0));
-                Assert.Null(array.GetValue(0));
-            }
-
-            [Theory]
-            [MemberData(nameof(GetTestData))]
-            public void AppendTimeGivesSameTime(TimeOnly time, TimeUnit timeUnit)
-            {
-                // Arrange
-                var builder = new Time64Array.Builder(timeUnit);
-                var expectedTime = time;
-                long expectedNanoseconds = time.Ticks * TimeSpan.NanosecondsPerTick;
-
-                // Act
-                builder = builder.Append(time);
-
-                // Assert
-                var array = builder.Build();
-                Assert.Equal(1, array.Length);
-                Assert.Equal(expectedTime, array.GetTime(0));
-                Assert.Equal(expectedNanoseconds, array.GetNanoSeconds(0));
-            }
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/TypeTests.cs b/csharp/test/Apache.Arrow.Tests/TypeTests.cs
deleted file mode 100644
index c279d69..0000000
--- a/csharp/test/Apache.Arrow.Tests/TypeTests.cs
+++ /dev/null
@@ -1,131 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Xunit;
-using Xunit.Sdk;
-
-namespace Apache.Arrow.Tests
-{
-    public class TypeTests
-    {
-        [Fact]
-        public void Basics()
-        {
-            Field.Builder fb = new Field.Builder();
-            Field f0_nullable = fb.Name("f0").DataType(Int32Type.Default).Build();
-            Field f0_nonnullable = fb.Name("f0").DataType(Int32Type.Default).Nullable(false).Build();
-
-            Assert.True(f0_nullable.Name == "f0");
-            Assert.True(f0_nullable.DataType.Name == Int32Type.Default.Name);
-
-            Assert.True(f0_nullable.IsNullable);
-            Assert.False(f0_nonnullable.IsNullable);
-        }
-
-        [Fact]
-        public void Equality()
-        {
-            Field f0_nullable = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-            Field f0_nonnullable = new Field.Builder().Name("f0").DataType(Int32Type.Default).Nullable(false).Build();
-            Field f0_other = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-            Field f0_with_meta = new Field.Builder().Name("f0").DataType(Int32Type.Default).Nullable(true).Metadata("a", "1").Metadata("b", "2").Build();
-
-            FieldComparer.Compare(f0_nullable, f0_other);
-            Assert.Throws<EqualException>(() => FieldComparer.Compare(f0_nullable, f0_nonnullable));
-            Assert.Throws<EqualException>(() => FieldComparer.Compare(f0_nullable, f0_with_meta));
-        }
-
-        [Fact]
-        public void TestMetadataConstruction()
-        {
-            var metadata = new Dictionary<string, string> { { "foo", "bar" }, { "bizz", "buzz" } };
-            var metadata1 = new Dictionary<string, string>(metadata);
-            Field f0_nullable = new Field.Builder().Name("f0").DataType(Int32Type.Default).Metadata(metadata).Build();
-            Field f1_nullable = new Field.Builder().Name("f0").DataType(Int32Type.Default).Metadata(metadata1).Build();
-            Assert.True(metadata.Keys.SequenceEqual(f0_nullable.Metadata.Keys) && metadata.Values.SequenceEqual(f0_nullable.Metadata.Values));
-            FieldComparer.Compare(f0_nullable, f1_nullable);
-        }
-
-        [Fact]
-        public void TestStructBasics()
-        {
-
-            Field f0_nullable = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-            Field f1_nullable = new Field.Builder().Name("f1").DataType(StringType.Default).Build();
-            Field f2_nullable = new Field.Builder().Name("f2").DataType(UInt8Type.Default).Build();
-
-            List<Field> fields = new List<Field>() { f0_nullable, f1_nullable, f2_nullable };
-            StructType struct_type = new StructType(fields);
-
-            var structFields = struct_type.Fields;
-            FieldComparer.Compare(structFields.ElementAt(0), f0_nullable);
-            FieldComparer.Compare(structFields.ElementAt(1), f1_nullable);
-            FieldComparer.Compare(structFields.ElementAt(2), f2_nullable);
-        }
-
-        [Fact]
-        public void TestStructGetFieldByName()
-        {
-
-            Field f0_nullable = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-            Field f1_nullable = new Field.Builder().Name("f1").DataType(StringType.Default).Build();
-            Field f2_nullable = new Field.Builder().Name("f2").DataType(UInt8Type.Default).Build();
-
-            List<Field> fields = new List<Field>() { f0_nullable, f1_nullable, f2_nullable };
-            StructType struct_type = new StructType(fields);
-
-            FieldComparer.Compare(struct_type.GetFieldByName("f0"), f0_nullable);
-            FieldComparer.Compare(struct_type.GetFieldByName("f1"), f1_nullable);
-            FieldComparer.Compare(struct_type.GetFieldByName("f2"), f2_nullable);
-            Assert.True(struct_type.GetFieldByName("not_found") == null);
-        }
-
-        [Fact]
-        public void TestStructGetFieldIndex()
-        {
-            Field f0_nullable = new Field.Builder().Name("f0").DataType(Int32Type.Default).Build();
-            Field f1_nullable = new Field.Builder().Name("f1").DataType(StringType.Default).Build();
-            Field f2_nullable = new Field.Builder().Name("f2").DataType(UInt8Type.Default).Build();
-
-            StructType struct_type = new StructType(new[] { f0_nullable, f1_nullable, f2_nullable });
-
-            Assert.Equal(0, struct_type.GetFieldIndex("f0"));
-            Assert.Equal(1, struct_type.GetFieldIndex("f1"));
-            Assert.Equal(2, struct_type.GetFieldIndex("F2", StringComparer.OrdinalIgnoreCase));
-            Assert.Equal(-1, struct_type.GetFieldIndex("F2"));
-            Assert.Equal(-1, struct_type.GetFieldIndex("F2", StringComparer.Ordinal));
-            Assert.Equal(-1, struct_type.GetFieldIndex("not_found"));
-        }
-
-        [Fact]
-        public void TestListTypeConstructor()
-        {
-            var stringField = new Field.Builder().Name("item").DataType(StringType.Default).Build();
-            var stringType1 = new ListType(stringField);
-            var stringType2 = new ListType(StringType.Default);
-
-            FieldComparer.Compare(stringType1.ValueField, stringType2.ValueField);
-            Assert.Equal(stringType1.ValueDataType.TypeId, stringType2.ValueDataType.TypeId);
-        }
-
-        // Todo: StructType::GetFieldIndexDuplicate test
-
-
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/Types/MapTypeTests.cs b/csharp/test/Apache.Arrow.Tests/Types/MapTypeTests.cs
deleted file mode 100644
index ba306ec..0000000
--- a/csharp/test/Apache.Arrow.Tests/Types/MapTypeTests.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests.Types
-{
-    public class MapTypeTests
-    {
-        [Fact]
-        public void MapType_Should_HaveCorrectTypeId()
-        {
-            var type = new MapType(StringType.Default, Int32Type.Default);
-            Assert.Equal(ArrowTypeId.Map, type.TypeId);
-        }
-
-        [Fact]
-        public void MapType_Should_HaveCorrectStructType()
-        {
-            var type = new MapType(BooleanType.Default, Int32Type.Default, true);
-            Assert.IsType<StructType>(type.Fields[0].DataType);
-            Assert.Equal(2, type.KeyValueType.Fields.Count);
-
-            Assert.Equal("entries", type.Fields[0].Name);
-            Assert.Equal("key", type.KeyField.Name);
-            Assert.Equal("value", type.ValueField.Name);
-
-            Assert.False(type.Fields[0].IsNullable);
-            Assert.False(type.KeyField.IsNullable);
-            Assert.True(type.ValueField.IsNullable);
-            Assert.False(new MapType(BooleanType.Default, Int32Type.Default, false).ValueField.IsNullable);
-
-            Assert.IsType<BooleanType>(type.KeyField.DataType);
-            Assert.IsType<Int32Type>(type.ValueField.DataType);
-        }
-
-        [Fact]
-        public void MapType_Should_SetKeySorted()
-        {
-            Assert.False(new MapType(BooleanType.Default, Int32Type.Default).KeySorted);
-            Assert.True(new MapType(StringType.Default, Int32Type.Default, true, true).KeySorted);
-        }
-    }
-}
diff --git a/csharp/test/Apache.Arrow.Tests/UnionArrayTests.cs b/csharp/test/Apache.Arrow.Tests/UnionArrayTests.cs
deleted file mode 100644
index c603ef6..0000000
--- a/csharp/test/Apache.Arrow.Tests/UnionArrayTests.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Linq;
-using Apache.Arrow.Types;
-using Xunit;
-
-namespace Apache.Arrow.Tests;
-
-public class UnionArrayTests
-{
-    [Theory]
-    [InlineData(UnionMode.Sparse)]
-    [InlineData(UnionMode.Dense)]
-    public void UnionArrayIsNull(UnionMode mode)
-    {
-        var (array, expectedNull) = BuildUnionArray(mode, 100);
-
-        for (var i = 0; i < array.Length; ++i)
-        {
-            Assert.Equal(expectedNull[i], array.IsNull(i));
-            Assert.Equal(!expectedNull[i], array.IsValid(i));
-        }
-    }
-
-    [Theory]
-    [InlineData(UnionMode.Sparse)]
-    [InlineData(UnionMode.Dense)]
-    public void UnionArraySlice(UnionMode mode)
-    {
-        var (array, expectedNull) = BuildUnionArray(mode, 10);
-
-        for (var offset = 0; offset < array.Length; ++offset)
-        {
-            for (var length = 0; length < array.Length - offset; ++length)
-            {
-                var slicedArray = (UnionArray)ArrowArrayFactory.Slice(array, offset, length);
-
-                var nullCount = 0;
-                for (var i = 0; i < slicedArray.Length; ++i)
-                {
-                    Assert.Equal(expectedNull[offset + i], slicedArray.IsNull(i));
-                    Assert.Equal(!expectedNull[offset + i], slicedArray.IsValid(i));
-                    nullCount += expectedNull[offset + i] ? 1 : 0;
-
-                    CompareValue(array, offset + i, slicedArray, i);
-                }
-
-                Assert.Equal(nullCount, slicedArray.NullCount);
-            }
-        }
-    }
-
-    [Theory]
-    [InlineData(UnionMode.Sparse)]
-    [InlineData(UnionMode.Dense)]
-    public void UnionArrayConstructedWithOffset(UnionMode mode)
-    {
-        const int length = 10;
-        var (array, expectedNull) = BuildUnionArray(mode, length);
-
-        for (var offset = 0; offset < array.Length; ++offset)
-        {
-            var (slicedArray, _) = BuildUnionArray(mode, length, offset);
-
-            var nullCount = 0;
-            for (var i = 0; i < slicedArray.Length; ++i)
-            {
-                Assert.Equal(expectedNull[offset + i], slicedArray.IsNull(i));
-                Assert.Equal(!expectedNull[offset + i], slicedArray.IsValid(i));
-                nullCount += expectedNull[offset + i] ? 1 : 0;
-
-                CompareValue(array, offset + i, slicedArray, i);
-            }
-
-            Assert.Equal(nullCount, slicedArray.NullCount);
-        }
-    }
-
-    private static void CompareValue(UnionArray originalArray, int originalIndex, UnionArray slicedArray, int sliceIndex)
-    {
-        var typeId = originalArray.TypeIds[originalIndex];
-        var sliceTypeId = slicedArray.TypeIds[sliceIndex];
-        Assert.Equal(typeId, sliceTypeId);
-
-        switch (typeId)
-        {
-            case 0:
-                CompareFieldValue<int, Int32Array>(typeId, originalArray, originalIndex, slicedArray, sliceIndex);
-                break;
-            case 1:
-                CompareFieldValue<float, FloatArray>(typeId, originalArray, originalIndex, slicedArray, sliceIndex);
-                break;
-            default:
-                throw new Exception($"Unexpected type id {typeId}");
-        }
-    }
-
-    private static void CompareFieldValue<T, TArray>(byte typeId, UnionArray originalArray, int originalIndex, UnionArray slicedArray, int sliceIndex)
-        where T : struct, IEquatable<T>
-        where TArray : PrimitiveArray<T>
-    {
-        if (originalArray is DenseUnionArray denseOriginalArray)
-        {
-            Assert.IsType<DenseUnionArray>(slicedArray);
-
-            originalIndex = denseOriginalArray.ValueOffsets[originalIndex];
-            sliceIndex = ((DenseUnionArray)slicedArray).ValueOffsets[sliceIndex];
-        }
-        var originalValue = ((TArray)originalArray.Fields[typeId]).GetValue(originalIndex);
-        var sliceValue = ((TArray)slicedArray.Fields[typeId]).GetValue(sliceIndex);
-        Assert.Equal(originalValue, sliceValue);
-    }
-
-    private static (UnionArray array, bool[] isNull) BuildUnionArray(UnionMode mode, int length, int offset=0)
-    {
-        var fields = new Field[]
-        {
-            new Field("field0", new Int32Type(), true),
-            new Field("field1", new FloatType(), true),
-        };
-        var typeIds = new[] { 0, 1 };
-        var type = new UnionType(fields, typeIds, mode);
-
-        var nullCount = 0;
-        var field0Builder = new Int32Array.Builder();
-        var field1Builder = new FloatArray.Builder();
-        var typeIdsBuilder = new ArrowBuffer.Builder<byte>();
-        var valuesOffsetBuilder = new ArrowBuffer.Builder<int>();
-        var expectedNull = new bool[length];
-
-        for (var i = 0; i < length; ++i)
-        {
-            var isNull = i % 3 == 0;
-            expectedNull[i] = isNull;
-            nullCount += (isNull && i >= offset) ? 1 : 0;
-
-            if (i % 2 == 0)
-            {
-                typeIdsBuilder.Append(0);
-                if (mode == UnionMode.Sparse)
-                {
-                    field1Builder.Append(0.0f);
-                }
-                else
-                {
-                    valuesOffsetBuilder.Append(field0Builder.Length);
-                }
-
-                if (isNull)
-                {
-                    field0Builder.AppendNull();
-                }
-                else
-                {
-                    field0Builder.Append(i);
-                }
-            }
-            else
-            {
-                typeIdsBuilder.Append(1);
-                if (mode == UnionMode.Sparse)
-                {
-                    field0Builder.Append(0);
-                }
-                else
-                {
-                    valuesOffsetBuilder.Append(field1Builder.Length);
-                }
-
-                if (isNull)
-                {
-                    field1Builder.AppendNull();
-                }
-                else
-                {
-                    field1Builder.Append(i * 0.1f);
-                }
-            }
-        }
-
-        var typeIdsBuffer = typeIdsBuilder.Build();
-        var valuesOffsetBuffer = valuesOffsetBuilder.Build();
-        var children = new IArrowArray[]
-        {
-            field0Builder.Build(),
-            field1Builder.Build()
-        };
-
-        UnionArray array = mode == UnionMode.Dense
-            ? new DenseUnionArray(type, length - offset, children, typeIdsBuffer, valuesOffsetBuffer, nullCount, offset)
-            : new SparseUnionArray(type, length - offset, children, typeIdsBuffer, nullCount, offset);
-
-        return (array, expectedNull);
-    }
-}
diff --git a/csharp/test/Directory.Build.props b/csharp/test/Directory.Build.props
deleted file mode 100644
index 4f17847..0000000
--- a/csharp/test/Directory.Build.props
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements. See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-
-<Project>
-
-  <Import Project="..\Directory.Build.props" />
-
-  <PropertyGroup>
-    <IsPackable>false</IsPackable>
-  </PropertyGroup>
-
-</Project>
diff --git a/dev/release/01-prepare-test.rb b/dev/release/01-prepare-test.rb
index 4dd4167..1d758f5 100644
--- a/dev/release/01-prepare-test.rb
+++ b/dev/release/01-prepare-test.rb
@@ -178,13 +178,6 @@
         ],
       },
       {
-        path: "csharp/Directory.Build.props",
-        hunks: [
-          ["-    <Version>#{@snapshot_version}</Version>",
-           "+    <Version>#{@release_version}</Version>"],
-        ],
-      },
-      {
         path: "dev/tasks/homebrew-formulae/apache-arrow-glib.rb",
         hunks: [
           ["-  url \"https://www.apache.org/dyn/closer.lua?path=arrow/arrow-#{@snapshot_version}/apache-arrow-#{@snapshot_version}.tar.gz\"",
diff --git a/dev/release/02-source-test.rb b/dev/release/02-source-test.rb
index 1b0bc2a..fe2c7b7 100644
--- a/dev/release/02-source-test.rb
+++ b/dev/release/02-source-test.rb
@@ -57,31 +57,6 @@
     end
   end
 
-  def test_csharp_git_commit_information
-    source
-    Dir.chdir("#{@tag_name_no_rc}/csharp") do
-      FileUtils.mv("dummy.git", "../.git")
-      sh("dotnet", "pack", "-c", "Release")
-      FileUtils.mv("../.git", "dummy.git")
-      Dir.chdir("artifacts/Apache.Arrow/Release") do
-        sh("unzip", "Apache.Arrow.#{@snapshot_version}.nupkg")
-        FileUtils.chmod(0400, "Apache.Arrow.nuspec")
-        nuspec = REXML::Document.new(File.read("Apache.Arrow.nuspec"))
-        nuspec_repository = nuspec.elements["package/metadata/repository"]
-        attributes = {}
-        nuspec_repository.attributes.each do |key, value|
-          attributes[key] = value
-        end
-        assert_equal({
-                       "type" => "git",
-                       "url" => "https://github.com/apache/arrow",
-                       "commit" => @current_commit,
-                     },
-                     attributes)
-      end
-    end
-  end
-
   def test_python_version
     source
     Dir.chdir("#{@tag_name_no_rc}/python") do
diff --git a/dev/release/02-source.sh b/dev/release/02-source.sh
index 099a899..5f813eb 100755
--- a/dev/release/02-source.sh
+++ b/dev/release/02-source.sh
@@ -65,7 +65,6 @@
   # Wait for the release candidate workflow to finish before attempting
   # to download the tarball from the GitHub Release.
   . $SOURCE_DIR/utils-watch-gh-workflow.sh ${tag} "release_candidate.yml"
-  . $SOURCE_DIR/utils-watch-gh-workflow.sh ${tag} "csharp.yml"
   rm -rf artifacts
   gh release download ${tag} \
     --dir artifacts \
diff --git a/dev/release/post-10-bump-versions-test.rb b/dev/release/post-10-bump-versions-test.rb
index 8eb0d1b..3818339 100644
--- a/dev/release/post-10-bump-versions-test.rb
+++ b/dev/release/post-10-bump-versions-test.rb
@@ -208,13 +208,6 @@
           ],
         },
         {
-          path: "csharp/Directory.Build.props",
-          hunks: [
-            ["-    <Version>#{@snapshot_version}</Version>",
-             "+    <Version>#{@next_snapshot_version}</Version>"],
-          ],
-        },
-        {
           path: "dev/tasks/homebrew-formulae/apache-arrow-glib.rb",
           hunks: [
             ["-  url \"https://www.apache.org/dyn/closer.lua?path=arrow/arrow-#{@snapshot_version}/apache-arrow-#{@snapshot_version}.tar.gz\"",
diff --git a/dev/release/rat_exclude_files.txt b/dev/release/rat_exclude_files.txt
index 51c0151..5212dc4 100644
--- a/dev/release/rat_exclude_files.txt
+++ b/dev/release/rat_exclude_files.txt
@@ -57,35 +57,6 @@
 dev/tasks/requirements*.txt
 dev/tasks/conda-recipes/*
 docs/requirements.txt
-go.work.sum
-go/go.sum
-go/arrow/Gopkg.lock
-go/arrow/flight/gen/flight/*.pb.go
-go/arrow/util/util_message/*.pb.go
-go/arrow/internal/cpu/*
-go/arrow/type_string.go
-go/arrow/cdata/test/go.sum
-go/arrow/unionmode_string.go
-go/arrow/compute/go.sum
-go/arrow/compute/datumkind_string.go
-go/arrow/compute/funckind_string.go
-go/arrow/compute/internal/kernels/compareoperator_string.go
-go/arrow/compute/internal/kernels/roundmode_string.go
-go/arrow/compute/internal/kernels/_lib/vendored/*
-go/*.tmpldata
-go/*.s
-go/parquet/internal/encoding/testdata/timestamp.data
-go/parquet/internal/gen-go/parquet/GoUnusedProtection__.go
-go/parquet/internal/gen-go/parquet/parquet-consts.go
-go/parquet/internal/gen-go/parquet/parquet.go
-go/parquet/version_string.go
-java/vector/src/main/java/org/apache/arrow/vector/util/IntObjectMap.java
-java/vector/src/main/java/org/apache/arrow/vector/util/IntObjectHashMap.java
-js/.npmignore
-js/closure-compiler-scripts/*
-js/src/fb/*.ts
-js/yarn.lock
-js/.eslintignore
 python/cmake_modules
 python/cmake_modules/FindPythonLibsNew.cmake
 python/MANIFEST.in
@@ -100,28 +71,6 @@
 __init__.pxd
 __init__.py
 requirements.txt
-csharp/.gitattributes
-csharp/dummy.git/*
-csharp/src/Apache.Arrow/Flatbuf/*
-csharp/Apache.Arrow.sln
-csharp/examples/FluentBuilderExample/FluentBuilderExample.csproj
-csharp/examples/Examples.sln
-csharp/src/Apache.Arrow/Apache.Arrow.csproj
-csharp/src/Apache.Arrow/Properties/Resources.Designer.cs
-csharp/src/Apache.Arrow/Properties/Resources.resx
-csharp/src/Apache.Arrow.Flight/Apache.Arrow.Flight.csproj
-csharp/src/Apache.Arrow.Flight.AspNetCore/Apache.Arrow.Flight.AspNetCore.csproj
-csharp/src/Apache.Arrow.Compression/Apache.Arrow.Compression.csproj
-csharp/src/Apache.Arrow.Flight.Sql/Apache.Arrow.Flight.Sql.csproj
-csharp/test/Apache.Arrow.Benchmarks/Apache.Arrow.Benchmarks.csproj
-csharp/test/Apache.Arrow.Flight.IntegrationTest/Apache.Arrow.Flight.IntegrationTest.csproj
-csharp/test/Apache.Arrow.Flight.Tests/Apache.Arrow.Flight.Tests.csproj
-csharp/test/Apache.Arrow.Flight.Sql.Tests/Apache.Arrow.Flight.Sql.Tests.csproj
-csharp/test/Apache.Arrow.Flight.TestWeb/Apache.Arrow.Flight.TestWeb.csproj
-csharp/test/Apache.Arrow.IntegrationTest/Apache.Arrow.IntegrationTest.csproj
-csharp/test/Apache.Arrow.Tests/Apache.Arrow.Tests.csproj
-csharp/test/Apache.Arrow.Compression.Tests/Apache.Arrow.Compression.Tests.csproj
-csharp/test/Apache.Arrow.Tests/app.config
 *.html
 *.sgml
 *.css
diff --git a/dev/release/utils-create-release-tarball.sh b/dev/release/utils-create-release-tarball.sh
index 89f0a30..8f91f5a 100755
--- a/dev/release/utils-create-release-tarball.sh
+++ b/dev/release/utils-create-release-tarball.sh
@@ -55,34 +55,6 @@
 cp -a -L ${root_folder}.tmp ${root_folder}
 rm -rf ${root_folder}.tmp
 
-# Create a dummy .git/ directory to download the source files from
-# GitHub with Source Link in C#. See the followings for more Source
-# Link support and why we need a dummy .git directory:
-# * https://github.com/apache/arrow/issues/21580
-# * https://github.com/apache/arrow/pull/4488
-#
-# We need to set constant timestamp for a dummy .git/ directory for
-# Reproducible Builds. We use committer date of the target commit hash
-# for it. If SOURCE_DATE_EPOCH is defined, this mtime is overwritten
-# when tar file is created.
-csharp_mtime=$(TZ=UTC \
-                 git \
-                 -C "${SOURCE_TOP_DIR}" \
-                 log \
-                 --format=%cd \
-                 --date=format:%Y%m%d%H%M.%S \
-                 -n1 \
-                 "${release_hash}")
-dummy_git=${root_folder}/csharp/dummy.git
-mkdir ${dummy_git}
-pushd ${dummy_git}
-echo ${release_hash} > HEAD
-echo "[remote \"origin\"] url = https://github.com/${GITHUB_REPOSITORY:-apache/arrow}.git" >> config
-mkdir objects refs
-TZ=UTC find . -exec touch -t "${csharp_mtime}" '{}' ';'
-popd
-TZ=UTC touch -t "${csharp_mtime}" ${root_folder}/csharp
-
 # Create new tarball from modified source directory.
 #
 # We need to strip unreproducible information. See also:
diff --git a/dev/release/utils-prepare.sh b/dev/release/utils-prepare.sh
index 37294c3..27e7e12 100644
--- a/dev/release/utils-prepare.sh
+++ b/dev/release/utils-prepare.sh
@@ -90,14 +90,6 @@
   git add vcpkg.json
   popd
 
-  pushd "${ARROW_DIR}/csharp"
-  sed -i.bak -E -e \
-    "s/^    <Version>.+<\/Version>/    <Version>${version}<\/Version>/" \
-    Directory.Build.props
-  rm -f Directory.Build.props.bak
-  git add Directory.Build.props
-  popd
-
   pushd "${ARROW_DIR}/dev/tasks/homebrew-formulae"
   sed -i.bak -E -e \
     "s/arrow-[0-9.\-]+[0-9SNAPHOT]+/arrow-${version}/g" \
diff --git a/dev/release/verify-release-candidate.sh b/dev/release/verify-release-candidate.sh
index 5768106..e202c7b 100755
--- a/dev/release/verify-release-candidate.sh
+++ b/dev/release/verify-release-candidate.sh
@@ -332,49 +332,6 @@
   echo "Working in sandbox ${ARROW_TMPDIR}"
 }
 
-install_csharp() {
-  # Install C# if doesn't already exist
-  if [ "${CSHARP_ALREADY_INSTALLED:-0}" -gt 0 ]; then
-    show_info "C# already installed $(which csharp) (.NET $(dotnet --version))"
-    return 0
-  fi
-
-  show_info "Ensuring that C# is installed..."
-
-  if dotnet --version | grep 8\.0 > /dev/null 2>&1; then
-    local csharp_bin=$(dirname $(which dotnet))
-    show_info "Found C# at $(which csharp) (.NET $(dotnet --version))"
-  else
-    if which dotnet > /dev/null 2>&1; then
-      show_info "dotnet found but it is the wrong version and will be ignored."
-    fi
-    local csharp_bin=${ARROW_TMPDIR}/csharp/bin
-    local dotnet_version=8.0.204
-    local dotnet_platform=
-    case "$(uname)" in
-      Linux)
-        dotnet_platform=linux
-        ;;
-      Darwin)
-        dotnet_platform=macos
-        ;;
-    esac
-    local dotnet_download_thank_you_url=https://dotnet.microsoft.com/download/thank-you/dotnet-sdk-${dotnet_version}-${dotnet_platform}-x64-binaries
-    local dotnet_download_url=$( \
-      curl -sL ${dotnet_download_thank_you_url} | \
-        grep 'directLink' | \
-        grep -E -o 'https://builds.dotnet[^"]+' | \
-        sed -n 2p)
-    mkdir -p ${csharp_bin}
-    curl -sL ${dotnet_download_url} | \
-      tar xzf - -C ${csharp_bin}
-    PATH=${csharp_bin}:${PATH}
-    show_info "Installed C# at $(which csharp) (.NET $(dotnet --version))"
-  fi
-
-  CSHARP_ALREADY_INSTALLED=1
-}
-
 install_conda() {
   # Setup short-lived miniconda for Python and integration tests
   show_info "Ensuring that Conda is installed..."
@@ -723,26 +680,6 @@
   popd
 }
 
-test_csharp() {
-  show_header "Build and test C# libraries"
-
-  install_csharp
-
-  pushd csharp
-
-  dotnet test
-
-  if [ "${SOURCE_KIND}" = "local" -o "${SOURCE_KIND}" = "git" ]; then
-    dotnet pack -c Release
-  else
-    mv dummy.git ../.git
-    dotnet pack -c Release
-    mv ../.git dummy.git
-  fi
-
-  popd
-}
-
 # Run integration tests
 test_integration() {
   show_header "Build and execute integration tests"
@@ -872,9 +809,6 @@
     popd
   fi
 
-  if [ ${TEST_CSHARP} -gt 0 ]; then
-    test_csharp
-  fi
   if [ ${BUILD_CPP} -gt 0 ]; then
     test_and_install_cpp
   fi
@@ -1062,7 +996,6 @@
 # Source verification tasks
 : ${TEST_SOURCE_REPRODUCIBLE:=0}
 : ${TEST_CPP:=${TEST_SOURCE}}
-: ${TEST_CSHARP:=${TEST_SOURCE}}
 : ${TEST_GLIB:=${TEST_SOURCE}}
 : ${TEST_RUBY:=${TEST_SOURCE}}
 : ${TEST_PYTHON:=${TEST_SOURCE}}
diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml
index d634719..caad319 100644
--- a/dev/tasks/tasks.yml
+++ b/dev/tasks/tasks.yml
@@ -571,7 +571,6 @@
                                  ("ubuntu", "22.04"),
                                  ("ubuntu", "24.04")] %}
   {% for target in ["cpp",
-                    "csharp",
                     "integration",
                     "python",
                     "ruby"] %}
@@ -600,7 +599,6 @@
   {% endfor %}
 
   {% for target in ["cpp",
-                    "csharp",
                     "integration",
                     "python",
                     "ruby"] %}
@@ -613,7 +611,6 @@
   {% endfor %}
 
   {% for target in ["cpp",
-                    "csharp",
                     "integration",
                     "python",
                     "ruby"] %}
diff --git a/docker-compose.yml b/docker-compose.yml
index cd94c8b..6d3babd 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -152,7 +152,6 @@
   - ubuntu-cpp-minimal
   - ubuntu-cuda-cpp:
     - ubuntu-cuda-python
-  - ubuntu-csharp
   - ubuntu-cpp-sanitizer
   - ubuntu-cpp-thread-sanitizer
   - ubuntu-cpp-emscripten
@@ -1727,30 +1726,6 @@
     command: >
       /bin/bash -c "/arrow/ci/scripts/r_revdepcheck.sh /arrow"
 
-  #################################### C# #####################################
-
-  ubuntu-csharp:
-    # Usage:
-    #   docker compose build ubuntu-csharp
-    #   docker compose run ubuntu-csharp
-    image: ${REPO}:${ARCH}-ubuntu-22.04-csharp-${DOTNET}
-    build:
-      context: .
-      dockerfile: ci/docker/ubuntu-22.04-csharp.dockerfile
-      cache_from:
-        - ${REPO}:${ARCH}-ubuntu-22.04-csharp-${DOTNET}
-      args:
-        arch: ${ARCH}
-        dotnet: ${DOTNET}
-        platform: jammy
-    shm_size: *shm-size
-    volumes: *ubuntu-volumes
-    command: &csharp-command >
-      /bin/bash -c "
-        /arrow/ci/scripts/csharp_build.sh /arrow &&
-        /arrow/ci/scripts/csharp_test.sh /arrow &&
-        /arrow/ci/scripts/csharp_pack.sh /arrow"
-
   ############################## Integration ##################################
 
   conda-integration:
diff --git a/docs/source/developers/guide/step_by_step/arrow_codebase.rst b/docs/source/developers/guide/step_by_step/arrow_codebase.rst
index 0c24cac..c464b68 100644
--- a/docs/source/developers/guide/step_by_step/arrow_codebase.rst
+++ b/docs/source/developers/guide/step_by_step/arrow_codebase.rst
@@ -35,17 +35,19 @@
 The `Apache Arrow repository <https://github.com/apache/arrow>`_ includes
 implementations for most of the libraries for which Arrow is available.
 
-Languages like GLib (``c_glib/``), C++ (``cpp/``), C# (``csharp/``),
-MATLAB (``matlab/``), Python (``python/``), R (``r/``) and Ruby (``ruby/``)
+Languages like GLib (``c_glib/``), C++ (``cpp/``), MATLAB
+(``matlab/``), Python (``python/``), R (``r/``) and Ruby (``ruby/``)
 have their own subdirectories in the main folder as written here.
 
 The following language implementations have their own repositories:
 
-- `Rust <https://github.com/apache/arrow-rs>`_
+- `.NET <https://github.com/apache/arrow-dotnet>`_
 - `Go <https://github.com/apache/arrow-go>`_
 - `Java <https://github.com/apache/arrow-java>`_
 - `JavaScript <https://github.com/apache/arrow-js>`_
 - `Julia <https://github.com/apache/arrow-julia>`_
+- `Rust <https://github.com/apache/arrow-rs>`_
+- `Swift <https://github.com/apache/arrow-swift>`_
 
 In the **language-specific subdirectories** you can find the code
 connected to that language. For example:
diff --git a/docs/source/implementations.rst b/docs/source/implementations.rst
index 116e55a..7cc2447 100644
--- a/docs/source/implementations.rst
+++ b/docs/source/implementations.rst
@@ -34,23 +34,23 @@
    * - Language
      - Docs
      - Source
+   * - .NET
+     - `.NET Docs <https://arrow.apache.org/dotnet/>`_ :fa:`external-link-alt`
+     - `.NET Source <https://github.com/apache/arrow-dotnet>`_
    * - C++
      - :doc:`C++ Docs<cpp/index>`
      - `C++ Source <https://github.com/apache/arrow/tree/main/cpp>`_
    * - C GLib
      - :doc:`C GLib Docs<c_glib/index>`
      - `C GLib Source <https://github.com/apache/arrow/tree/main/c_glib>`_
-   * - C#
-     - `C# Docs <https://github.com/apache/arrow/blob/main/csharp/README.md>`_ :fa:`external-link-alt`
-     - `C# Source <https://github.com/apache/arrow/tree/main/csharp>`_
    * - Go
-     - `Go Docs <https://godoc.org/github.com/apache/arrow/go/arrow>`_ :fa:`external-link-alt`
+     - `Go Docs <https://arrow.apache.org/go/>`_ :fa:`external-link-alt`
      - `Go Source <https://github.com/apache/arrow-go>`_
    * - Java
      - :doc:`Java Docs<java/index>`
      - `Java Source <https://github.com/apache/arrow-java>`_
    * - JavaScript
-     - `JavaScript Docs <https://arrow.apache.org/docs/js>`_ :fa:`external-link-alt`
+     - `JavaScript Docs <https://arrow.apache.org/js/>`_ :fa:`external-link-alt`
      - `JavaScript Source <https://github.com/apache/arrow-js>`_
    * - Julia
      - `Julia Docs <https://arrow.apache.org/julia/>`_ :fa:`external-link-alt`
@@ -71,7 +71,7 @@
      - `Rust Docs <https://docs.rs/arrow/latest>`_ :fa:`external-link-alt`
      - `Rust Source <https://github.com/apache/arrow-rs>`_
    * - Swift
-     - `Swift Docs <https://github.com/apache/arrow-swift/blob/main/Arrow/README.md>`_ :fa:`external-link-alt`
+     - `Swift Docs <https://arrow.apache.org/swift/>`_ :fa:`external-link-alt`
      - `Swift Source <https://github.com/apache/arrow-swift>`_
 
 In addition to the libraries listed above, the Arrow project hosts the
@@ -109,9 +109,9 @@
    :maxdepth: 1
    :hidden:
 
+   .NET <https://arrow.apache.org/dotnet/>
    C++ <cpp/index>
    C GLib <c_glib/index>
-   C# <https://github.com/apache/arrow/blob/main/csharp/README.md>
    Go <https://arrow.apache.org/go/>
    Java <java/index>
    JavaScript <https://arrow.apache.org/js/current/>
diff --git a/r/_pkgdown.yml b/r/_pkgdown.yml
index 1a3665c..4946832 100644
--- a/r/_pkgdown.yml
+++ b/r/_pkgdown.yml
@@ -52,7 +52,7 @@
           data-project-color="#000000"
           data-project-logo="https://arrow.apache.org/img/arrow-logo_chevrons_white-txt_black-bg.png"
           data-modal-disclaimer="This is a custom LLM with access to all of [Arrow documentation](https://arrow.apache.org/docs/).  If you want an R-specific answer, please mention this in your question."
-          data-consent-required="true" 
+          data-consent-required="true"
           data-user-analytics-cookie-enabled="false"
           data-consent-screen-disclaimer="By clicking &quot;I agree, let's chat&quot;, you consent to the use of the AI assistant in accordance with kapa.ai's [Privacy Policy](https://www.kapa.ai/content/privacy-policy). This service uses reCAPTCHA, which requires your consent to Google's [Privacy Policy](https://policies.google.com/privacy) and [Terms of Service](https://policies.google.com/terms). By proceeding, you explicitly agree to both kapa.ai's and Google's privacy policies."
       ></script>
@@ -83,18 +83,19 @@
       implementations:
         title: Implementations
         text: >
+          [.NET](https://arrow.apache.org/dotnet/) <br>
           [C GLib](https://arrow.apache.org/docs/c_glib) <br>
           [C++](https://arrow.apache.org/docs/cpp) <br>
-          [C#](https://github.com/apache/arrow/blob/main/csharp/README.md) <br>
           [Go](https://arrow.apache.org/go/) <br>
+          [JavaScript](https://arrow.apache.org/js/) <br>
           [Java](https://arrow.apache.org/docs/java) <br>
-          [JavaScript](https://arrow.apache.org/docs/js) <br>
           [Julia](https://github.com/apache/arrow-julia/blob/main/README.md) <br>
           [MATLAB](https://github.com/apache/arrow/blob/main/matlab/README.md) <br>
           [Python](https://arrow.apache.org/docs/python) <br>
           [R](index.html) <br>
           [Ruby](https://github.com/apache/arrow/blob/main/ruby/README.md) <br>
-          [Rust](https://docs.rs/crate/arrow/latest)
+          [Rust](https://docs.rs/crate/arrow/latest) <br>
+          [Swift](https://arrow.apache.org/swift/)
       community:
         title: Community
         text: >