You will need Visual Studio .NET 2003 or higher. (Released April 2003). .NET Framework. 1.1.
In the foreach example below, we have a custom collection that is iterated over by a for loop.
To work with foreach, an object should be enumerable, meaning it implements either IEnumerable or IEnumerable<T>.
The compiler will also accept as enumerable, any object that implmeents a method with the right signature 'public IEnumerator GetEnumerator()'.
It is in this situation that the Dispose method of the enumerator will not be called. This is fixed for C# 1.2.
var myCollection = new MyCollection();
foreach(var item in myCollection)
{
Console.WriteLine(item.ToString());
}
class MyCollection
{
ArrayList _items = new ArrayList();
public MyCollection()
{
_items.Add("item 1");
_items.Add("item 2");
}
// operations
public int GetCount()
{
return _items.Count;
}
public string GetAt(int index)
{
return (string)_items[index];
}
// IEnumerator
public IEnumerator GetEnumerator()
{
return new MyEnumerator(this);
}
}
class MyEnumerator : IEnumerator, IDisposable
{
private MyCollection _collection;
private int _index = -1;
public MyEnumerator(MyCollection collection)
{
_collection = collection;
}
public object Current
{
get { return _collection.GetAt(_index); }
}
public bool MoveNext()
{
return ++_index < _collection.GetCount();
}
public void Reset()
{
_index = -1;
}
// IDisposable
public void Dispose()
{
Console.WriteLine("MyEnumerator.Dispose()");
}
}
In the code below, MyClass implements a property called Name. The compiler converts property declarations into a pair of functions, with the appropriate signature, called get_Name() and set_Name(). If a language doesn't support properties, it can still access the values through a method call.
The prior bug was that the compiler allowed you to declare a class with one of these reserved names.
The compiler now reports an error.
public class MyClass
{
public string Name
{
get
{ // get code here
return "";
}
set
{ // set code here
}
}
// Error: MyClass already reserves a member called 'get_Name' with the same parameter types
public string get_Name()
{
}
// Error: MyClass already reserves a member called 'set_Name' with the same parameter types
public void set_Name(string name)
{
}
}
The code below attempts to set a private variable using a named parameter in the constructor argument list of an Attribute.
This worked previously, but now results in a compile error.
[AttributeUsage(AttributeTargets.All)]
public class DescriptionAttribute : System.Attribute
{
private string descriptionText;
public DescriptionAttribute(string description)
{
this.descriptionText = description;
}
}
public partial class Program
{
// Error 'description' is inaccessible due to its protection level
[Description(descriptionText = "Just an example")]
public class MyClass
{
}
}
}
When iterating over a string, the foreach statement now uses the string's indexer rather than the enumerator pattern, resulting in greater performance.