具有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 ≤ <TT>i</TT> ≤ <I>N</I>−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>−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>−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> − 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;
}
}
}
答案 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;
}
}
}