77526


VBで書いていたコードをC#に移植しています．VBで動いていた配列の拡張関数がC#ではエラーになってしまいます．解決方法わかりましたらご教示ください．（ちなみにずっとVB頭で、C#はほとんどやっておりません）

※ コード長くなっちゃうんで諸処省いております．ご了解ください．

## VBでの拡張関数の定義 （動いておりました）

[code]

    Imports System.Runtime.CompilerServices
    
    ''' <summary>
    '''  Extend two dimensional array function: get IEnumerble or list of column/row 
    ''' </summary>
    Public Module ArrayEx
        ''' <summary>
        ''' Apply row/column filtering to source array row and get the result as new array.
        ''' </summary>
        ''' <typeparam name="T"></typeparam>
        ''' <param name="srcArray"></param>
        ''' <param name="rowSelectFunc"></param>
        ''' <returns></returns>
        <Extension()>
        Public Function GetFilteredArray(Of T)(ByVal srcArray As T(,), rowSelectFunc As Func(Of IEnumerable(Of T), Boolean), columnSelectFunc As Func(Of IEnumerable(Of T), Boolean)) As T(,)
            If IsNothing(srcArray) Then
                Throw New ArgumentNullException("Two dimensional array: T(,) is null.")
            End If
            If IsNothing(rowSelectFunc) Then
                Throw New ArgumentNullException("rowSelectFunc as Func(Of IEnumerable(Of T), Boolean) is null.")
            End If
            If IsNothing(columnSelectFunc) Then
                Throw New ArgumentNullException("columnSelectFunc as Func(Of IEnumerable(Of T), Boolean) is null.")
            End If
            Dim columnIndex As Integer() = srcArray.GetColumnIndex(columnSelectFunc)
            Dim filteredRows As IEnumerable(Of IEnumerable(Of T)) = srcArray.GetRows(rowSelectFunc, columnIndex)
            Dim filteredArray As Array = filteredRows.ToArray
            Return filteredArray
        End Function
    
    End Module
    
    
[/code]

## VBでの拡張関数の呼び出し（動いておりました）

[code]

    ' Make original title/data array from Excel range object
    Dim rangeArray As Array = Array.CreateInstance(GetType(ATLCellInfo), mRowCount, mColumnCount)
    ' ... 配列の内容を設定
    ' Remove empty rows and columns
    Dim filteredArray As ATLCellInfo(,) = DirectCast(rangeArray, ATLCellInfo(,)).GetFilteredArray(Function(row As IEnumerable(Of ATLCellInfo))
                                                                                                              Return row.OneOrMore(Function(cell As ATLCellInfo)
                                                                                                                                       Return cell.HasValue
                                                                                                                                   End Function)
                                                                                                          End Function,
                                                                                                          Function(column As IEnumerable(Of ATLCellInfo))
                                                                                                              Return column.First.HasValue
                                                                                                          End Function)
    
[/code]

## 移植したC#の拡張関数

[code]

    namespace ArrayExNs
    {
        /// <summary>
        /// '''  Extend two dimensional array function: get IEnumerble or list of column/row 
        /// ''' </summary>
        public static class ArrayEx
        {
            /// <summary>
            /// Apply row/column filtering to source array row and get the result as new array.
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="srcArray"></param>
            /// <param name="rowSelectFunc"></param>
            /// <param name="columnSelectFunc"></param>
            /// <returns></returns>
            public static T[,] GetFilteredArray<T>(this T[,] srcArray, Func<IEnumerable<T>, bool> rowSelectFunc, Func<IEnumerable<T>, bool> columnSelectFunc)
            {
                if (srcArray == null)
                    throw new ArgumentNullException("Two dimensional array: T(,) is null.");
                if (rowSelectFunc == null)
                    throw new ArgumentNullException("rowSelectFunc as Func(Of IEnumerable(Of T), Boolean) is null.");
                if (columnSelectFunc == null)
                    throw new ArgumentNullException("columnSelectFunc as Func(Of IEnumerable(Of T), Boolean) is null.");
                int[] columnIndex = srcArray.GetColumnIndex(columnSelectFunc);
                IEnumerable<IEnumerable<T>> filteredRows = srcArray.GetRows(rowSelectFunc, columnIndex);
                Array filteredArray = filteredRows.ToArray();
                return (T[,])filteredArray;
            }
        }
    }
    
[/code]

## C#での拡張関数の呼び出し（コンパイルエラーです）

[code]

    using ArrayExNs;
    ...
    // Make original title/data array from Excel range object
    Array rangeArray = Array.CreateInstance(typeof(ATLCellInfo), mRowCount, mColumnCount);
    // ... 配列の内容を設定
    // Remove empty rows and columns
    ATLCellInfo[,] filteredArray = (ATLCellInfo[,])rangeArray.GetFilteredArray((row) =>
                                                                                   {
                                                                                       return row.OneOrMore(cell =>
                                                                                       {
                                                                                           return cell.HasValue;
                                                                                       });
                                                                                   }, (column) =>
                                                                                       {
                                                                                           return column.First.HasValue;
                                                                                       }
                                                                                   );
    
[/code]

GetFilteredArrayの箇所に以下のエラーが出てしまいます．

[code]

    Error CS1061 'Array' does not contain a definition for 'GetFilteredArray' and no accessible extension method 'GetFilteredArray' accepting a first argument of type 'Array' could be found (are you missing a using directive or an assembly reference?)
    
[/code]

ちなみに「移植した」といいつつも、VB⇒C#のコンバータにかけて、エラーを取ったレベルです．

以上 よろしくお願いいたします．


CC BY-SA 4.0
2021-06-13T11:10:49.687
77525
2021-06-13T16:57:04.660
2021-06-13T16:57:04.660
3060
9503
question
c#
C#での配列の拡張関数の書き方


キャスト演算子`(T)`とメンバーアクセス演算子`.`では、メンバーアクセス演算子のほうが優先順位は上です。

  * [C# operators and expressions - C# reference | Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/#operator-precedence)

要するに、`(ATLCellInfo[,])rangeArray.GetFilteredArray(...)`は誤りで、  
単純に`((ATLCellInfo[,])rangeArray).GetFilteredArray(...)`とすればいいんじゃないでしょうか。

エラーメッセージをよく読めば、わざわざ誰かに聞くまでもなく、何が間違っているのかすぐに分かるはずです。

  * [ペアプログラミングして気がついた新人プログラマの成長を阻害する悪習 - Qiita](https://qiita.com/hirokidaichi/items/27c757d92b6915e8ecf7#%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%83%AD%E3%82%B0%E3%82%92%E8%AA%AD%E3%81%BE%E3%81%AA%E3%81%84)
  * [プログラミング言語 - エラー文って読まないの？｜teratail](https://teratail.com/questions/76445)
  * [エラーメッセージの読み方と対処, 検索や質問の原則 - Qiita](https://qiita.com/cannorin/items/eb062aae88bfe2ad6fe5)


CC BY-SA 4.0
2021-06-13T11:44:53.987
77526
2021-06-13T11:57:40.637
2021-06-13T11:57:40.637
15413
15413
77525
answer