2010-01-29
2010-01-27
Resharper:”Access to modified closure”
using System;
namespace ConsoleApplication1
{
class Program
{
delegate void MyDelegate();
static void Main()
{
MyDelegate d = null;
string s;
for (var i = 0; i < 10; i++)
{
s = i.ToString();
d += () => Console.WriteLine(s);
}
d();
}
}
}
输出是什么?如果把s的定义放到循环内部呢?
using System;
namespace ConsoleApplication1
{
class Program
{
delegate void MyDelegate();
static void Main()
{
MyDelegate d = null;
//string s;
for (var i = 0; i <= 10; i++)
{
string s;
s = i.ToString();
d += () => Console.WriteLine(s);
}
d();
}
}
}
第一种情况下,由于s是在循环外部定义的,所有的delegate都是共享的,所以,每循环一次,s增1,到最后,s变为10,最后执行d()的时候,用的都是同一个s,因此输出都是10。resharper 会提定义局部变量保存s的拷贝,如下,这样,每一次执行都会使用自己的copy,也就会输出0 1 2 3 ….10
using System;
namespace ConsoleApplication1
{
class Program
{
delegate void MyDelegate();
static void Main()
{
MyDelegate d = null;
string s;
for (var i = 0; i <= 10; i++)
{
s = i.ToString();
string s1 = s;
d += () => Console.WriteLine(s1);
}
d();
}
}
}
C#: Anonymous methods are not closures
The implementation of anonymous methods in C# and its consequences (part 1)
Resharper 提示”lambda expression to statement”
最近用上了resharper,实时对代码进行改进,碰到这么一个提示“lambda expression to statement”,那什么是lambda expression,什么是lambda statement?二者有什么区别?
Expression:
var exprBooks = books.Find(book => book.Author.Contains("Fowler"));
Statement:
var stmtBooks = books.Find(book => { return book.Author.Contains("Fowler"); });
A lambda statement contains braces and a function body, and can potentially have multiple lines like a standard delegate. A lambda expression is the single line with an implicit return
http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/07/18/expressions-and-lambdas.aspx
2010-01-26
.net links 2010/1/26
Use .NET Built-in Methods to Save Time and Headaches
TryParse() and File.WriteAllText(file, str) are really useful to me!
If you are using a loop, you're doing it wrong
if you can use Linq, do not use for and foreach
.Net Tip: Convert a String to Title Case
string helloWorld = "hello world haha ds s w";
Console.WriteLine(
System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(helloWorld));可以写个扩展方法
IEnumerable, IEnumerator, GetEnumerator()
如果想要自定义类型支持foreach,那么此类型必须实现IEnumerable 接口,然后在GetEnumerator()方法中返回实现IEnumerator接口的对象,实现Current,MoveNext,Reset方法。好消息是2.0中加入了yield关键字,一句yield return,编译器就会给你做剩下的事情
using System;
using System.Collections;
namespace ConsoleApplication2
{
public class Person
{
public Person(string fName, string lName)
{
FirstName = fName;
LastName = lName;
}
public string FirstName;
public string LastName;
}
public class People : IEnumerable
{
private Person[] _people;
public People(Person[] pArray)
{
_people = new Person[pArray.Length];
for (int i = 0; i < pArray.Length; i++)
{
_people[i] = pArray[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
//return new PeopleEnum(_people);
// and you can delete below PeopleEnum class
for (int i = 0; i < _people.Length; i++)
{
yield return _people[i];
}
}
}
public class PeopleEnum : IEnumerator
{
public Person[] _people;
// Enumerators are positioned before the first element
// until the first MoveNext() call.
int position = -1;
public PeopleEnum(Person[] list)
{
_people = list;
}
public bool MoveNext()
{
position++;
return (position < _people.Length);
}
public void Reset()
{
position = -1;
}
public object Current
{
get
{
try
{
return _people[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}
class App
{
static void Main()
{
Person[] peopleArray = new Person[3]
{
new Person("Tom", "Cat"),
new Person("Jon", "Walker"),
new Person("Jet", "Li"),
};
People peopleList = new People(peopleArray);
foreach (Person p in peopleList)
Console.WriteLine(p.FirstName + " " + p.LastName);
}
}
或者是返回IEnumerable的方法
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
foreach (var p in Primes(100))
{
Console.WriteLine(p);
}
}
public static IEnumerable<int> Primes(int max)
{
yield return 2;
var found = new List<int> {3};
var candidate = 3;
while (candidate <= max)
{
var isPrime = found.TakeWhile(
prime => prime*prime <= candidate).All(prime => candidate%prime != 0);
if (isPrime)
{
found.Add(candidate);
yield return candidate;
}
candidate += 2;
}
}
}
}
Implementing iterators with yield statements
Behind the scenes of the C# yield keyword
2010-01-25
typeof() GetType() is
throw ex 和 throw 一样么?
JIT and NGEN
Assembly.LoadFile() Assembly.LoadFrom() Assembly.Load()
1、Assembly.LoadFile()只载入相应的dll文件,比如Assembly.LoadFile(”a.dll”),则载入a.dll,假如a.dll中引用了b.dll的话,b.dll并不会被载入。Assembly.LoadFrom则不一样,它会载入dll文件及其引用的其他dll,比如上面的例子,b.dll也会被载入。
2、用Assembly.LoadFrom()载入一个Assembly时,会先检查前面是否已经载入过相同名字的Assembly,比如a.dll有两个版本(版本1在目录1下,版本2放在目录2下),程序一开始时载入了版本1,当使用Assembly.LoadFrom(”2″”a.dll”)载入版本2时,不能载入,而是返回版本1。Assembly.LoadFile的话则不会做这样的检查,比如上面的例子换成Assembly.LoadFile的话,则能正确载入版本2。
3、Assembly.Load()方法参数为程序集的名称不包含扩展名
.net 4.0 中只保留了LoadFrom() 方法
http://msdn.microsoft.com/en-us/library/ee191568(VS.100).aspx
http://blog.csdn.net/nanqingfei/archive/2009/10/12/4659004.aspx