错误:IEnumerable无法在非泛型静态类中定义

时间:2015-02-12 04:10:23

标签: c# generics compiler-errors ienumerable

具有IEnumerable接口的类在编译时出错。

必须在非通用静态类中定义扩展方法

请帮忙。我不希望该类是静态的,这将导致更多的错误(某些东西不能在静态类中定义)。

非常感谢!

namespace phyl
{
    public class DnaSequenceList : IEnumerable<DnaSequence>
    {
        // DNA sequences.
        public DnaSequence[] mySequence;
        // Mapping from site (index) to whether site is informative (true/false). If
        // null, must be recomputed.
        private bool[] isInformative;
        // Number of informative sites.
        private int nInformative;
        // Number of state changes in uninformative sites.
        private int nChanges;

        /**
        * Construct a new DNA sequence list.
        */
        public DnaSequenceList()
        {
        }
        /**
        * Construct a new DNA sequence list that is a copy of the given DNA
        * sequence list.
        * <P>
        * <I>Note:</I> The DNA sequences in the new list are copies of (not
        * references to) the DNA sequences in the given list.
        *
        * @param list DNA sequence list to copy.
        *
        * @exception NullPointerException
        * (unchecked exception) Thrown if <TT>list</TT> is null.
        */
        public DnaSequenceList(DnaSequenceList list)
        {
            int N = list.mySequence.Length;
            this.mySequence = new DnaSequence[N];
            for (int i = 0; i < N; ++i)
            {
                this.mySequence[i] = new DnaSequence(list.mySequence[i]);
            }
            if (list.isInformative != null)
            {
                this.isInformative = list.isInformative;
            }
            this.nInformative = list.nInformative;
            this.nChanges = list.nChanges;
        }
        /**
        * Obtain this DNA sequence list's length.
        *
        * @return Length <I>N</I> (number of DNA sequences).
        */
        public int length()
        {
            return mySequence.Length;
        }

        /**
        * Get the DNA sequence at the given index in this DNA sequence list.
        *
        * @param i Index, 0 &le; <TT>i</TT> &le; <I>N</I>&minus;1.
        *
        * @return DNA sequence.
        *
        * @exception ArrayIndexOutOfBoundsException
        * (unchecked exception) Thrown if <TT>i</TT> is out of bounds.
        */
        public DnaSequence seq(int i)
        {
            return mySequence[i];
        }


        public int exciseUninformativeSites()
        {
            int S = mySequence.Length;
            int N = mySequence[0].length();
            // Determine which sites are informative.
            computeInformativeSites();
            // Excise uninformative sites from sequences.
            for (int s = 0; s < S; ++s)
            {
                byte[] oldSites = mySequence[s].mySites;
                mySequence[s] = new DnaSequence (nInformative,mySequence[s].myScore,mySequence[s].myName);
                byte[] excSites = mySequence[s].mySites;
                int j = 0;
                for (int i = 0; i < N; ++i)
                {
                    if (isInformative[i])
                    {
                        excSites[j++] = oldSites[i];
                    }
                }
            }
            // Mark all sites as informative.
            isInformative = new bool[nInformative];
            ArraysFill(isInformative, true);
            // Return number of state changes.
            return nChanges;
        }

        /**
        * Returns the number of informative sites in this DNA sequence list.
        *
        * @return Number of informative sites.
        */
        public int informativeSiteCount()
        {
            computeInformativeSites();
            return nInformative;
        }

        /**
        * Compute information about informative sites.
        */
        private void computeInformativeSites()
        {
            if (isInformative != null) return;
            int S = mySequence.Length;
            int N = mySequence[0].length();
            // Allocate storage to remember each site's category: true =
            // informative, false = uninformative. Also count number of informative
            // sites and number of state changes in uninformative sites.
            isInformative = new bool[N];
            nInformative = 0;
            nChanges = 0;
            // Allocate storage to count states at each site.
            int[] stateCount = new int[16];
            // Examine all sites.
            for (int i = 0; i < N; ++i)
            {
                ArraysFill(stateCount, 0);
                // Examine current site in all sequences.
                for (int s = 0; s < S; ++s)
                {
                    ++stateCount[mySequence[s].mySites[i]];
                }
                // Count how many values in stateCount are 2 or greater.
                int x = 0;
                for (int j = 0; j < 16; ++j)
                {
                    if (stateCount[j] >= 2) ++x;
                }
                // Categorize current site.
                if (x >= 2)
                {
                    // Informative site.
                    isInformative[i] = true;
                    ++nInformative;
                }
                else
                {
                    // Uninformative site. Increase number of state changes by
                    // (number of different states - 1).
                    isInformative[i] = false;
                    for (int j = 0; j < 16; ++j)
                    {
                        if (stateCount[j] > 0) ++nChanges;
                    }
                    --nChanges;
                }
            }
        }

        /**
         * Determine the number of absent states after adding each sequence in this
         * DNA sequence list to a tree. The return value <I>A</I> is an
         * <I>N</I>-element array, where <I>N</I> is the length of this DNA sequence
         * list. As sequences from this list are added to a tree in order from
         * <I>i</I> = 0 to <I>N</I>&minus;1, <I>A</I>[<I>i</I>] is the number of
         * character states that do not yet appear in the tree. Thus, the number of
         * state changes in the tree must increase by at least <I>A</I>[<I>i</I>]
         * when the sequences after sequence <I>i</I> are added to the tree. This
         * can be used to prune a branch-and-bound search.
         *
         * @return  Array <I>A</I>.
         */
        public int[] countAbsentStates()
        {
            int N = mySequence.Length;
            int L = mySequence[0].length();
            int[] A = new int[N];

            // Compute the union of all the DNA sequences.
            byte[] sites = new byte[L];
            for (int i = 0; i < N; ++i)
            {
                byte[] mysites_i = mySequence[i].mySites;
                for (int j = 0; j < L; ++j)
                {
                    sites[j] |= mysites_i[j];
                }
            }

            // Subtract each sequence from the union, count and record states.
            for (int i = 0; i < N; ++i)
            {
                byte[] mysites_i = mySequence[i].mySites;
                int count = 0;
                for (int j = 0; j < L; ++j)
                {
                    sites[j] &= mysites_i[j];
                    count += DnaSequence.state2bitCount[sites[j]];
                }
                A[i] = count;
            }

            return A;
        }

        /**
         * Create a DNA sequence tree from this DNA sequence list and the given tree
         * signature. The tree signature is an array of indexes of length <I>N</I>,
         * where <I>N</I> is the length of this list. To construct the tree, for all
         * <I>i</I> from 0 to <I>N</I>&minus;1, the DNA sequence at index <I>i</I>
         * in this list is added to the tree at index <TT>signature[i]</TT> using
         * the <TT>DnaSequenceTree.add()</TT> method. For all <I>i</I>,
         * <TT>signature[i]</TT> must be in the range 0 ..
         * 2(<I>i</I>&nbsp;&minus;&nbsp;1), except <TT>signature[0]</TT> is 0.
         * <P>
         * <I>Note:</I> The returned tree has references to (not copies of) the DNA
         * sequences in this list.
         *
         * @param  signature  Tree signature (array of tree indexes).
         *
         * @return  Tree.
         */
        public DnaSequenceTree toTree(int[] signature)
        {
            int N = mySequence.Length;
            DnaSequenceTree tree = new DnaSequenceTree(2 * N - 1);
            for (int i = 0; i < N; ++i)
            {
                tree.add(signature[i], mySequence[i]);
            }
            return tree;
        }


        public static void ArraysFill<T>(this T[] originalArray, T with)
        {
            for (int i = 0; i < originalArray.Length; i++)
            {
                originalArray[i] = with;
            }
        }
       /// <summary>
       /// //////////////////////////////////////////////////////////////
       /// </summary>
       /// <returns></returns>
        // Implementation for the GetEnumerator method.
        IEnumerator IEnumerable.GetEnumerator()
        {
            return (IEnumerator)GetEnumerator();
        }

        public DnaSequenceEnum GetEnumerator()
        {
            return new DnaSequenceEnum(mySequence);
        }


    }

    // When you implement IEnumerable, you must also implement IEnumerator. 
    public class DnaSequenceEnum : IEnumerator
    {
        public DnaSequence[] _DnaSequenceList;

        // Enumerators are positioned before the first element 
        // until the first MoveNext() call. 
        int i = 0;

        public DnaSequenceEnum(DnaSequence[] list)
        {
            _DnaSequenceList = list;
        }

        public bool MoveNext()
        {
            i++;
            return i < _DnaSequenceList.Length;
        }

        public DnaSequence next()
        {

            return _DnaSequenceList[i++];
        }

        public void remove()
        {
            throw new NotSupportedException();
        }
        public DnaSequence Current
        {
            get
            {
                try
                {
                    return _DnaSequenceList[i];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }
        object IEnumerator.Current { get { return Current; } }

        public void Reset()
        {
            i = -1;
        }

    }

}

2 个答案:

答案 0 :(得分:2)

错误说明的是 - 你在非静态类中有一个扩展方法。扩展方法必须是静态类。将其移动到不同的静态类或使用常规方法(通过删除this

由于您未将该方法称为扩展程序,而是将其作为常规方法调用,我只需从this的第一个参数中删除ArraysFill

答案 1 :(得分:1)

您的ArrayFill(...)方法是一种扩展方法。必须在静态和非泛型类中创建扩展方法。创建一个新的静态类并在其中移动您的方法。

public static class ExtensionMethod
{
     public static void ArraysFill<T>(this T[] originalArray, T with)
    {
        for (int i = 0; i < originalArray.Length; i++)
        {
            originalArray[i] = with;
        }
    }
}