注意这不是关于如何在C#中实现或模拟duck typing的问题...
几年来,我的印象是某些C#语言特性对语言本身定义的数据结构感到沮丧(这对我来说似乎总是一个奇怪的鸡蛋和鸡蛋场景).例如,我的印象是foreach循环只能用于实现的类型IEnumerable.
从那时起,我开始明白C#编译器使用duck typing来确定是否可以在foreach循环中使用对象,GetEnumerator而不是查找方法IEnumerable.这很有意义,因为它消除了鸡蛋和鸡蛋的难题.
我有点困惑,为什么这不是using块的情况似乎并非如此IDisposable.是否有任何特殊原因编译器不能使用duck typing并查找Dispose方法?造成这种不一致的原因是什么?
或许还有其他东西在IDisposable的引擎盖下进行?
讨论为什么你会永远有未实现IDisposable是这个问题的范围之外的Dispose方法的对象:)
在这个答案中,https: //stackoverflow.com/a/8649429/1497 Eric Lippert说"我们很有可能在下一版本的C#中解决这个问题;对于开发人员而言,这是一个主要的痛点". foreach循环使用变量.
在下一个版本中,每次运行"foreach"循环时,我们将生成一个新的循环变量,而不是每次都关闭相同的变量.这是一个"突破"的变化,但在绝大多数情况下,"休息"将是修复而不是导致错误.
我无法找到任何表明此更改尚未完成的内容.有没有迹象表明这是foreach循环在C#5中的工作方式?
究竟是如何foreach在C#中实现的?
我想它的一部分看起来像:
var enumerator = TInput.GetEnumerator();
while(enumerator.MoveNext())
{
// do some stuff here
}
Run Code Online (Sandbox Code Playgroud)
但是我不确定究竟发生了什么.enumerator.Current每个周期使用什么方法返回?它是为[每个循环]返回还是需要匿名函数或其他东西才能执行foreach?
我知道关于foreach循环如何在C#中工作的基础知识(foreach循环如何在C#中工作)
我想知道是否使用foreach分配可能导致垃圾收集的内存?(适用于所有内置的系统类型).
例如,在System.Collections.Generic.List<T>类上使用Reflector ,这里是GetEnumerator的实现:
public Enumerator<T> GetEnumerator()
{
return new Enumerator<T>((List<T>) this);
}
Run Code Online (Sandbox Code Playgroud)
在每次使用时,这将分配一个新的枚举器(和更多的垃圾).
所有类型都这样做吗?如果是这样,为什么?(不能重用一个枚举器吗?)
我正在准备我的C#EXAM.我对这个问题的答案感到困惑:
程序可以使用
IEnumerable和IEnumerator接口来执行以下哪项操作?一个.使用MoveNext和Reset来移动对象列表.
湾 使用foreach移动对象列表.
C.按索引移动对象列表.
d.使用yield return语句创建迭代对象列表.
我的回答是b).但是这本书:MCSD认证工具包说它是a).
有人可以告诉我为什么吗?我意识到你可以获得Enumerator使用GetEnumerator()然后调用MoveNext和Reset方法来遍历列表(并用于Current访问迭代器引用的当前元素).但是没有实现IEnumerable和IEnumerator在foreach循环中使用对象的原因?
可能重复:
foreach循环如何在C#中工作?
我一直在网上搜索,我很难找到任何关于foreachC#循环幕后真实情况的答案.
我知道这个问题并不真正与实际编码有关,但它困扰着我.我对OO编程很熟悉,特别是接口.我知道他们是合同,我知道如何IEnumerable和IEnumerator工作-我还是这么认为.
我一直在MSDN上阅读这篇文章: IEnumerable Interface
我理解一切都是如何建立的.我有点不清楚,虽然在Main循环中如何foreach知道通过所有的值来迭代_people.怎么知道这个?它如何Current通过调用来跟踪return new PeopleEnum(_people);?
编辑:我不知道这是一个完全重复.是的,它的类似理由和同样的问题被问到,但我们正在寻找不同的答案或我想要的答案在前一个问题中没有讨论过.
像foreach(在obj中的int i){...}等等的foreach循环等同于
......"有点"不是我正在寻找的答案.
我有多线程应用程序,我得到这个错误
************** Exception Text **************
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
...
Run Code Online (Sandbox Code Playgroud)
我的收藏可能有问题,因为在一个线程上我读取了我的收藏,在另一个线程上我修改了收藏.
public readonly ObservableCollectionThreadSafe<GMapMarker> Markers = new ObservableCollectionThreadSafe<GMapMarker>();
public void problem()
{
foreach (GMapMarker m in Markers)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我试图用这段代码锁定集合,但不起作用.
public void problem()
{
lock(Markers)
{
foreach (GMapMarker m in Markers)
{
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
有什么想法来解决这个问题?
我正在看这个代码示例C# 7.0,我不确定引擎盖下发生了什么以及这个循环的性能.
foreach (var c in text ?? throw new ArgumentNullException(nameof(text)))
{
...
}
Run Code Online (Sandbox Code Playgroud)
我的问题:
可能重复:
foreach循环如何在C#中工作?
就像经典迭代语句一样,for,while或do-while,is foreach loop is a new loop statment in c#?或in other languages such as php
要么
在幕后,它将我们的代码转换为for,while或do-while循环.
我有一个转换Address为oneline字符串的扩展方法:
public static class AddressExtensions
{
public static string ToOneLine(this Address address)
{
var sb = new StringBuilder();
sb.Append(address.Street);
if (!string.IsNullOrWhiteSpace(address.City)) sb.Append(string.Format("{0}, ",address.City));
if (!string.IsNullOrWhiteSpace(address.State)) sb.Append(string.Format("{0}, ", address.State));
if (!string.IsNullOrWhiteSpace(address.Zip)) sb.Append(string.Format("{0}, ", address.Zip));
return sb.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
然后我用它将数据从域模型传输到我的DTO.下面的代码使用foreach和工作正常:
var entity=_repository.GetAll();
var model = new List<SummaryViewModel>();
foreach (var e in entity)
{
model.Add(new SummaryViewModel
{
Address = e.Address.ToOneLine(),
Name = e.Name,
Id = e.Id
});
}
Run Code Online (Sandbox Code Playgroud)
但是在使用时LINQ,
var model = entity.Select(e => new SummaryViewModel
{ …Run Code Online (Sandbox Code Playgroud) 我在代码库中遇到了这个问题:
foreach (var evtType in EventLocator.GetTypes())
Run Code Online (Sandbox Code Playgroud)
并且记住Shlemiel画家的算法会EventLocator.GetTypes()在每个循环上调用该方法还是只调用一次?
如何让foreach指令在"files"变量和"names"数组中进行迭代?
var files = Directory.GetFiles(@".\GalleryImages");
string[] names = new string[8] { "Matt", "Joanne", "Robert","Andrei","Mihai","Radu","Ionica","Vasile"};
Run Code Online (Sandbox Code Playgroud)
我尝试了2个选项..第一个给了我很多错误,第二个显示了8种各种图像
foreach(var file in files,var i in names)
{
//Do stuff
}
Run Code Online (Sandbox Code Playgroud)
和
foreach(var file in files)
{
foreach (var i in names)
{
//Do stuff
}
}
Run Code Online (Sandbox Code Playgroud) 在foreach loop当条件是有一个意外的行为true其实都是指令后内if statement,循环中断.我试着评论if语句并且一切正常(将所有元素迭代到ienumerable中).有人能解释我为什么吗?
var allRef = projDefinition
.Element(msbuild + "Project")
.Elements(msbuild + "ItemGroup")
.Elements(msbuild + "COMReference")
.Where(refElem => find.Any(f => refElem.FirstAttribute.Value.ToLower().Contains(f)))
.Select(refElem => refElem);
foreach (var xElement in allRef)
{
var name = xElement.FirstAttribute.Value;
var dllPath = dllFiles.FirstOrDefault(dll => dll.ToLower().Contains(name.ToLower()));
if (dllPath != null)
{
var dllName = dllPath.Substring(dllPath.LastIndexOf('\\') + 1, dllPath.LastIndexOf('.') - dllPath.LastIndexOf('\\') - 1);
xElement.Remove();
XElement elem = new XElement(msbuild + "Reference", new XAttribute("Include", dllName));
elem.Add(new XElement(msbuild + "HintPath", HintPath.GetHintPath(dllPath)));
elem.Add(new XElement(msbuild …Run Code Online (Sandbox Code Playgroud) c# ×13
foreach ×7
loops ×3
.net ×2
clr ×2
linq ×2
.net-4.5 ×1
c#-5.0 ×1
c#-7.0 ×1
duck-typing ×1
enumerator ×1
idisposable ×1
php ×1
wpf ×1
xml ×1