置顶随笔
#
摘要: 别被下面那些复杂的表达式吓倒,只要跟着我一步一步来,你会发现正则表达式其实并不像你想像中的那么困难。当然,如果你看完了这篇教程之后发现自己明白了很多,却又几乎什么都记不得,那也是很正常的--其实我认为没接触过正则表达式的人在看完这篇教程后能把提到过的语法记住80%以上的可能性为零。这里只是让你明白基本道理,以后你还需要多练习,多查资料,才能熟练掌握正则表达式。
阅读全文
2010年1月6日
#
using System;
using System.Collections.Generic;
struct SomeStruct
{
public int SomeValue;
}
class SomeContainerClass
{
public SomeStruct Struct;
}
struct SomeContainerStruct
{
public SomeStruct Struct;
}
class Program
{
static void Main()
{
TestStruct();
TestClass();
TestArray();
TestList();
Console.ReadKey();
}
static SomeStruct GetDefaultValue()
{
return new SomeStruct { SomeValue = 100 };
}
private static void TestStruct()
{
ShowTestName("TestStruct:");
var c = new SomeContainerStruct { Struct = GetDefaultValue() };
ShowResult("original:", c.Struct.SomeValue);
var s = c.Struct;
s.SomeValue = 200;
ShowResult("indirectly:", c.Struct.SomeValue);
c.Struct.SomeValue = 300;
ShowResult("directly:", c.Struct.SomeValue);
}
private static void TestClass()
{
ShowTestName("TestClass:");
var c = new SomeContainerClass { Struct = GetDefaultValue() };
ShowResult("original:", c.Struct.SomeValue);
var s = c.Struct;
s.SomeValue = 200;
ShowResult("indirectly:", c.Struct.SomeValue);
c.Struct.SomeValue = 300;
ShowResult("directly:", c.Struct.SomeValue);
}
private static void TestArray()
{
ShowTestName("TestArray:");
var c = new[] { GetDefaultValue() };
ShowResult("original:", c[0].SomeValue);
var s = c[0];
s.SomeValue = 200;
ShowResult("indirectly:", c[0].SomeValue);
c[0].SomeValue = 300;
ShowResult("directly:", c[0].SomeValue);
}
private static void TestList()
{
ShowTestName("TestList:");
var c = new List<SomeStruct> { GetDefaultValue() };
ShowResult("original:", c[0].SomeValue);
var s = c[0];
s.SomeValue = 200;
ShowResult("indirectly:", c[0].SomeValue);
//the follow line won't compile
//Cannot modify the return value of 'System.Collections.Generic.List<StructTest.SomeStruct>.this[int]' because it is not a variable
//c[0].SomeValue = 300;
//ShowTestName("directly:", c[0].SomeValue);
}
static void ShowResult(string condition, int value)
{
Console.Write(condition);
Console.Write("\t");
Console.WriteLine(value);
}
static void ShowTestName(string message)
{
Console.WriteLine();
Console.WriteLine(message);
}
}
2009年12月22日
#
Who's locking my file?
使用这个工具可以查找出哪个进程打开了指定的文件:Handle.
用法: handle <filename>
IIS7.x Application Pool - change user account
选中应用程序池 - 高级设置 - 进程模型 - 标识
2009年11月28日
#
比如你要连接一个Sql Server服务器,你有一个connection string, 但是不知道是否是正确的,你可以这样:
var connection = new SqlConnection(connectionString);
connection.Open();
connection.Close();
如果整个过程中没有异常抛出,则说明connectionString是指向一个Sql Server的服务器。但是,如果connectionString里边的Data Source(或者Server)的值是错的,就要等很久——大约30秒——才能从connection.Open()这一句抛出异常。有没有办法让这个过程快一点呢?
你可以试着在connectionString里添加上: "Connection Timeout=3",这指示超时时间为3秒。但是实际上效果还是一样的,异常仍然要在30秒之后才会抛出。
你也可以试着用另一个线程去连接服务器,主线程在若干秒后调用该线程的 Abort()方法,但是,实验效果是行不通,因为那个线程在connection.Open()里根本出不来,无法被Abort掉。
最后,我的解决方法还是采用后台线程,只不过如果到期尚未成功,那就当做失败,然后把它扔到一边去,不再理它了:
//采用后台线程来连接数据库,以便在服务器输入错误的情况下,不用等待很长的时间才能得到一个错误提示
string error = null;
var success = false;
// ReSharper disable AccessToModifiedClosure
// ReSharper disable UseObjectOrCollectionInitializer
var thread = new Thread(() =>
{
try
{
connection.Open();
connection.Close();
success = true;
}
catch (SqlException ex)
{
error = ex.Message;
}
finally
{
if (connection.State == ConnectionState.Open)
connection.Close();
}
});
// ReSharper restore AccessToModifiedClosure
// ReSharper restore UseObjectOrCollectionInitializer
thread.IsBackground = true;
var sw = Stopwatch.StartNew();
thread.Start();
var timeout = TimeSpan.FromSeconds(3);
while (sw.Elapsed < timeout)
thread.Join(TimeSpan.FromMilliseconds(200));
sw.Stop();
if (!success)
{
throw new Exception(error ?? "连接数据库超时,请检查输入的服务器是否正确。");
}
2009年11月23日
#
TreeView控件在以下情况下会引发非期待中的AfterSelect事件:
- 原始状态为未选中任何结点
- TreeView内容较多,出现了竖向滚动条
- 最小化TreeView所在窗体
- 然后最大化此窗体
步骤4完成后,TreeView会自动选中屏幕上显示的第一个节点,并引发AfterSelect事件。
如果你不想处理此事件,可以检查TreeViewEventArgs.Action, 这种情况下Action的值应该是Unknown。所以微软自己在MSDN Library里对TreeViewEventArgs的示例代码就是这样的:

Code
protected override void OnAfterSelect(TreeViewEventArgs e)
{
// Confirm that the user initiated the selection.
// This prevents the first node from expanding when it is
// automatically selected during the initialization of
// the TreeView control.
if (e.Action != TreeViewAction.Unknown)
{
if (e.Node.IsExpanded)
{
e.Node.Collapse();
}
else
{
e.Node.Expand();
}
}
// Remove the selection. This allows the same node to be
// clicked twice in succession to toggle the expansion state.
SelectedNode = null;
}
只是只口未提刚才我们谈到的这种奇特形为。。。
2009年11月14日
#
注:C#3.0, VB9.0
这里只是一些比较容易弄不清的地方,其它关键字的差异(比如abstract 和 MustInherit之类的)相信都是很简单的了.
- 模块(Module): 模块就是C#里的静态类,但是,在同一命名空间里的其它类型里,调用模块里定义的方法不需要加模块类的名称.比如 AAA.BB.XXModule有个M()方法,则在AA.BB.XXXXClass里可以直接写: M(),而不用写XXModule.M()
- 数组声明: Dim a = new Int() {1, 2, 3} ,或者: Dim a(3) As Integer
- 方法:分为两种,有返回值的叫Function,无返回值的叫Sub
- 声明Function或Property时可以不指定类型(As Type), 默认为Object类型
- 类型转换: C#: var a = (TypeName)b; VB: Dim a = DirectCast(b, TypeName) C#: var a = b as TypeName; VB: Dim a = TryCast(b, TypeName)
- 类型:C#: typeof(TypeName) VB: GetType(TypeName) C#: a is TypeName VB: TypeOf a is TypeName
- 操作符:/返回的是带余数的结果(CInt(46/10) = 5),\返回不带余数的结果, Mod返回余数; VB有 +=, *=等运算符,没有 ++, --等运行符
- 对象初始化表达式: Dim a = new XX with {.Property1 = value1, .Property2 = value2}
- 源码组织:VB里一个语句要放在一行;可以用" _"放在行尾把两行视为逻辑上的一行;语句结尾不要加分号;
- 不使用方括号:VB里数组存取,含参属性等都用圆括号(),不用方括号[], 应用属性Attribute时用尖括号<>
- 泛型:C#: List<string> VB: List(Of String)
- 字符串连接:VB里用 & 来连接字符串( 1 & "2" = "12", 1 + "2" = 3)
- 字符串:没有C#里的@""的对应物;字符转义只支持""转意成"; 换行符等无法直接输入
- Lambda表达式: C#版: x => x.Property; VB版: Function(x) x.Property
- 等同性: C#: x == b VB: x = b(如果有重载=操作符的话,Object类重载的不算) C#: ReferenceEqual(a, b) VB: a is b