也許這個問題已經被問過百萬次了,但是我找不到類似的話題。是否有可能寫一個泛型類與多個'where'-s將在編譯時檢查?這是我今天是否有可能在C#中使用類似於C++的泛型?
public class MsBitsEnumWrapper<TC, TE> : IEnumerable<TC>
{
internal class Helper : IEnumerator<TC>
{
private readonly TC[] _data;
private int _pos = -1;
private readonly IEnumBackgroundCopyJobs _jobs;
private readonly IEnumBackgroundCopyFiles _files;
// I miss C++ templates that allows me to implements this method in completelly generic fashion...
public Helper(TE source)
{
_jobs = source as IEnumBackgroundCopyJobs;
_files = source as IEnumBackgroundCopyFiles;
uint count = 0;
if (null != _jobs)
{
_jobs.GetCount(out count);
_jobs.Reset();
}
else
if (null != _files)
{
_files.GetCount(out count);
_files.Reset();
}
_data = new TC[count];
for (uint i = 0; i < count; ++i)
{
uint fetched = 0;
if (null != _jobs)
{
IBackgroundCopyJob job;
_jobs.Next(1, out job, ref fetched);
_data[i] = (TC)job;
}
else
if (null != _files)
{
IBackgroundCopyFile file;
_files.Next(1, out file, ref fetched);
_data[i] = (TC)file;
}
}
}
#region Implementation of IDisposable
public void Dispose() { }
#endregion
#region Implementation of IEnumerator
public bool MoveNext()
{
if (_pos < (_data.Length - 1))
{
_pos++;
return true;
}
return false;
}
public void Reset()
{
_pos = -1;
}
public TC Current
{
get { return _data[_pos]; }
}
object IEnumerator.Current
{
get { return Current; }
}
#endregion
}
private readonly Helper _enumerator;
public MsBitsEnumWrapper(TE source) { _enumerator = new Helper(source); }
#region Implementation of IEnumerable
public IEnumerator<TC> GetEnumerator() { return _enumerator; }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
#endregion
}
很顯然,我不喜歡它,因爲我必須在運行時間檢測的通用參數的類型開關。有沒有可能有這樣的事情?
public class MsBitsEnumWrapper<TC, TE> : IEnumerable<TC>
where TE : IEnumBackgroundCopyJobs, IEnumBackgroundCopyFiles
where TC : IBackgroundCopyJob, IBackgroundCopyFile
{
internal class Helper : IEnumerator<TC>
{
private readonly TC[] _data;
private int _pos = -1;
private readonly TE _iface;
// I miss C++ templates that allows me to implements this method in completelly generic fashion...
public Helper(TE source)
{
_iface = source;
uint count;
_iface.GetCount(out count);
_iface.Reset();
_data = new TC[count];
for (uint i = 0; i < count; ++i)
{
uint fetched = 0;
TC job;
_iface.Next(1, out job, ref fetched);
_data[i] = job;
}
}
#region Implementation of IDisposable
public void Dispose() { }
#endregion
#region Implementation of IEnumerator
public bool MoveNext()
{
if (_pos < (_data.Length - 1))
{
_pos++;
return true;
}
return false;
}
public void Reset()
{
_pos = -1;
}
public TC Current
{
get { return _data[_pos]; }
}
object IEnumerator.Current
{
get { return Current; }
}
#endregion
}
private readonly Helper _enumerator;
public MsBitsEnumWrapper(TE source) { _enumerator = new Helper(source); }
#region Implementation of IEnumerable
public IEnumerator<TC> GetEnumerator() { return _enumerator; }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
#endregion
}
我意識到,如果通用與TE = IEnumBackgroundCopyJobs和TC = IBackgroundCopyFile定義它不會工作,但因爲我是一個誰定義給出接口的TE和TC和函數原型是相同的它很高興能以這種方式工作。
或者可能有另一種方法來簡化當前的代碼?
謝謝!
你想達到什麼目的?您發佈的代碼以什麼特定方式不能滿足您的需求?發佈一個不起作用的*小*代碼示例,並指定您遇到的錯誤。 – Timwi 2010-08-21 02:32:28
目標是能夠使用「foreach」枚舉COM接口IEnumBackgroundCopyFiles或IEnumBackgroundCopyJobs的實例。第一個實施是今天在生產中使用的。使用示例: IEnumBackgroundCopyFiles temp; job.EnumFiles(out temp); var files = new MsBitsEnumWrapper(temp); foreach(IBackgroundCopyFile file in files){} :::在這裏,我必須檢查運行時(在構造函數中)如果給定的參數是通過「as」投射的一個或另一個類型的實例。我想要更通用的解決方案。 –
expert
2010-08-21 02:48:11
魯斯蘭,你是包括太多不相關的細節。另外,請不要試圖將信息填入評論中。請編輯問題,刪除所有不必要的詳細信息和代碼,並且只詢問*相關*的信息*,但當然包括*所有*相關信息。 – Timwi 2010-08-21 03:05:59