C# .NET迭代器来包装API
我有一个带有API的类,它允许我请求对象,直到它抛出一个C# .NET迭代器来包装API,c#,.net,exception,yield-return,C#,.net,Exception,Yield Return,我有一个带有API的类,它允许我请求对象,直到它抛出一个IndexOutOfBoundsException 我想把它包装成一个迭代器,以便能够编写更干净的代码。但是,我需要捕获异常以停止迭代: static IEnumerable<object> Iterator( ExAPI api ) { try { for( int i = 0; true; ++i ) { yield return api[i]; // will throw even
IndexOutOfBoundsException
我想把它包装成一个迭代器,以便能够编写更干净的代码。但是,我需要捕获异常以停止迭代:
static IEnumerable<object> Iterator( ExAPI api ) {
try {
for( int i = 0; true; ++i ) {
yield return api[i]; // will throw eventually
}
}
catch( IndexOutOfBoundsException ) {
// expected: end of iteration.
}
}
静态IEnumerable迭代器(ExAPI){
试一试{
for(int i=0;true;++i){
yield return api[i];//最终将抛出
}
}
捕获(IndexOutOfBoundsException){
//预期:迭代结束。
}
}
但是
与表达式连用时,表示让步
return语句不能出现在
catch块或在具有
一个或多个catch子句。更多
有关详细信息,请参阅异常处理
语句(C#参考)。语句(C#参考)。
(摘自)
如何仍然包装此api?您只需将
yield return
语句移到try
块之外,如下所示:
static IEnumerable<object> Iterator( ExAPI api ) {
for( int i = 0; true; ++i ) {
object current;
try {
current = api[i];
} catch(IndexOutOfBoundsException) { yield break; }
yield return current;
}
}
静态IEnumerable迭代器(ExAPI){
for(int i=0;true;++i){
目标电流;
试一试{
当前=api[i];
}catch(IndexOutOfBoundsException){yield break;}
产生回流电流;
}
}
只需重新排列代码:
static IEnumerable<object> Iterator( ExAPI api ) {
bool exceptionThrown = false;
object obj = null;
for( int i = 0; true; ++i ) {
try {
obj = api[i];
}
catch( IndexOutOfBoundsException ) {
exceptionThrown = true;
yield break;
}
if (!exceptionThrown) {
yield return obj;
}
}
}
静态IEnumerable迭代器(ExAPI){
bool exceptionThrown=false;
objectobj=null;
for(int i=0;true;++i){
试一试{
obj=api[i];
}
捕获(IndexOutOfBoundsException){
exceptionThrown=true;
屈服断裂;
}
如果(!ExceptionRown){
收益率目标;
}
}
}
您可以将获取对象的简单操作包装到单独的函数中。您可以在其中捕获异常:
bool TryGetObject( ExAPI api, int idx, out object obj )
{
try
{
obj = api[idx];
return true;
}
catch( IndexOutOfBoundsException )
{
return false;
}
}
然后,调用该函数并在必要时终止:
static IEnumerable<object> Iterator( ExAPI api )
{
bool abort = false;
for( int i = 0; !abort; ++i )
{
object obj;
if( TryGetObject( api, i, out obj ) )
{
yield return obj;
}
else
{
abort = true;
}
}
}
静态IEnumerable迭代器(ExAPI)
{
bool abort=false;
对于(int i=0;!abort;++i)
{
对象对象对象;
if(TryGetObject(api、i、out obj))
{
收益率目标;
}
其他的
{
中止=真;
}
}
}
如果你根本无法检查对象的边界,你可以这样做
static IEnumerable<object> Iterator( ExAPI api )
{
List<object> output = new List<object>();
try
{
for( int i = 0; true; ++i )
output.Add(api[i]);
}
catch( IndexOutOfBoundsException )
{
// expected: end of iteration.
}
return output;
}
静态IEnumerable迭代器(ExAPI)
{
列表输出=新列表();
尝试
{
for(int i=0;true;++i)
新增(api[i]);
}
捕获(IndexOutOfBoundsException)
{
//预期:迭代结束。
}
返回输出;
}
虽然现在我看这里,我相信上面的答案更好。发布的一个。静态IEnumerable迭代器(ExAPI api)
static IEnumerable<object> Iterator(ExAPI api)
{
int i = 0;
while (true)
{
Object a;
try
{
a = api[i++];
}
catch (IndexOutOfBoundsException)
{
yield break;
}
yield return a;
}
}
{
int i=0;
while(true)
{
对象a;
尝试
{
a=api[i++];
}
捕获(IndexOutOfBoundsException)
{
屈服断裂;
}
收益率a;
}
}
不,我想我写得太快了。。。。不管怎样,你下面的答案更清晰更好:-)现在你有了一个无用的变量。是的-但是如果我改变了,我的答案将是你答案的直接副本,这将有点蹩脚,即使它是正确的-你写了正确的代码,你应该得到学分!我不太喜欢这种方法。如果api仅通过此方法访问,则获取对象的单独方法有点多余。尽管您不需要“If(current!=null)yield return current”?哦,等等,我错过了yield break。msdn上没有
yield break
语句文档。。。谢谢你的指点!事实上:我的意图不是填充容器,而是提供迭代器。