也许这个问题已经被问过百万次了,但是我找不到类似的话题。是否有可能写一个泛型类与多个'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