RSS 2.0 Feed

Saturday, May 12, 2007

posted @ | Feedback (16) | Filed Under [ .NET ]

Tuesday, May 01, 2007

打算编写一个基于Google Image的Linq实现,算是作为学习Linq,特别是IQueryable/Expression Tree的一个手段吧。

这里起一个头,希望实验过程中不会犯懒吧...

posted @ | Feedback (0) | Filed Under [ .NET ]

Tuesday, April 24, 2007

终于算是完成了从C# 1.0到C# 3.0的大跃进,开始看一些Linq方面的东西。当然最感兴趣的是C#底层是如何实现Linq的(Extension Methods, Lambda Expression, Expression Tree, yadayada...),做了一些小实验:

posted @ | Feedback (15) | Filed Under [ .NET ]

Thursday, March 01, 2007

我胡汉三又回来了!
不过识别两年,技术前沿生疏了许多。看思归的文章犹如读字母天书,WPF, WCP横行,幸好没有WTF。
重回CSDN上混,我的账号居然还在。

现在的考量是把和.NET无关的东西放在我的blogspot英文博客上,这里放CSDN上遇到的问题和解决方法。是该重新收拾对.NET地了解了——“无他,但手熟尔”。

posted @ | Feedback (13) | Filed Under [ 乱谈 ]

Friday, November 11, 2005

Having deserted this blog for more than a year, I finally decided to start blogging all over again. However, I also decided to move to a new space. Several reasons:

  • I would prefer blogging in English, just as a practise, a way to learn.
  • I'm currently getting an MBA in Economics and Finance at Baruch College, CUNY. So occasionally I will write my study notes on my blog, which doesn't really fit the style of JoyCode blogs.
  • As I started my new job, I'm finally moving away from back end server/engine design and towards the really world business applications. As a result, I will be documenting stuff that I'm not really familiar with (For example, database design, GUI programming, and so on). Since these are not my specialties, I'm not sure people here would like to read them.
  • I'm neither a Microsoft employee or MVP at this moment.

  Joy, I would like to keep a copy of my old blogs, so it would be great if you can still keep it around for some time.

posted @ | Feedback (10) | Filed Under [ .NET ]

Thursday, September 30, 2004

  A dedicated QA has been testing one of my application during the past few days. The good news is that fortunately, I'm still a qualified developer: the program design is solid, there is no design flaw and there is no data damage under exceptional conditions. The bad part is, I didn't pay enough attention to those details that I should have paid attention to. Here is a list of things, check how many of them are in your program:

  1. While using strtol or _strtoi64 to convert a user input string to numeric value, it returns the largest possible value when the number overflows. So if you use that as a criteria for overflow, you will miss out the largest value itself.
  2. We know port 0 through 1024 are reserved for system use, is 1024 included?
  3. Do you know that fopen can't open files that is located under a directory whose name contains non-ASCII characters?
  4. inet_addr accepts ip addresses like 10.0.1, and converts it to 10.0.1.0.
  5. Under what condition is “C:Temp“ a valid directory name?

posted @ | Feedback (9) | Filed Under [ 乱谈 ]

Wednesday, September 22, 2004

  I have been thinking about the notion of “Weak Delegate” for a long time. For those who don't want to remove (-=) the delegate everytime, here is a thorough description about the potential memory leak problem and the solution and sample code by Greg Schechter.  And here is a generic version by Ian Griffiths.
  Be advised: Weak Delegate or not, A Memory Leak is a memory leak. You should ALWAYS remember to remove the eventhandler once the listener is out of scope.

posted @ | Feedback (11) | Filed Under [ .NET ]

Sunday, September 19, 2004

  A question pops up from the forum regarding the const correctness in C++: “Why don't we have it in C#?”
  In C++, if a method is declared like this: 
               class MyClass {
                       void foo() const;
               };

  It implies that the author claims that the method won't change any internal data of MyClass object. It's a very handy way to allow compiler to check the semantics of your program. In C#, however, we don't have any corresponding constructs. An explanation from Anders Hejlsberg can be found
here (Check out the immutable section).

  My understanding of the problem is that C++ is a designed to be flexible: most of the things are optional. Even inside a const function, for example, you still have the option of using const_cast to strip the const and get a mutable version. C#, on the other hand, is designed to have unified and strong semantics: If you ever have the keyword “const“ in C#, there is a good chance that you won't be able to cast it away.

   Const correctness is a very nice feature to have. But like
checked exceptions, once enforced strictly by the language and runtime, it will make your life miserable. For example, once you get a const reference, you CAN'T call any member method that is not marked const. Even worse, the reference to a member variable will be const too. If the class library is not designed extremely careful, this chain react will eventually make you wish the const constraint were never there.

 

 

posted @ | Feedback (10) | Filed Under [ .NET ]

Sunday, September 12, 2004

Monday, August 23, 2004

贴了关于.NET String ImmutableImplementaion的blog,收到下面两个回复:

  • 对于定义如 public void xx(string yy);的函数,传进去的yy的值是改不了的.
    下面的程序展示了如何在Native函数中修改字符串参数的值:
        //Native.cpp: the exported native dll function
        extern "C" _declspec(dllexport) void _stdcall ModifyString(LPWSTR str) {
             str[0] = L'X';
        }

        //Test.cs: Csharp function:
        [DllImport(“Native.dll”, CharSet=CharSet.Unicode)]
        public static extern void ModifyString(string str);

        public static void Main() {
           string str = “Hello, World”;
           ModifyString(str);
           Console.WriteLine(str);        
        }

    这里的关键是Unicode,.NET String的内部编码是UCS2,如果Native函数参数恰好用的是UCS2,出于性能考虑,CLR会直接把string内部字符串的地址传给Native;如果Native函数接受ASCII编码,CLR就不得不做一个拷贝了。
  • Hash算法从来都不保证不同的值生成的Hash值不同!
    正是因为散列函数可能出现冲突,所以在散列查找之后还必须比较键值以确定查找的正确性,所以一旦加入Hashtable,对象的键值是不能改变的。下面的程序用CLR内部的InternTable来展示改变一个Intern字符串的结果:
      static unsafe void ModifyConst() {
          string str = "Hello";
          fixed(char* pstr = str) {
              pstr[0] = 'X';
          }
      }

      static void Main() {
          ModifyConst();
          StringBuilder sb = new StringBuilder("Hel");
          sb.Append("lo");
          string str = sb.ToString();
      
       Console.WriteLine(str);

          switch(str) {
          case "Xello":
              Console.WriteLine("string is Xello"); break;
          case "Hello":
              Console.WriteLine("string is Hello"); break;
          default:
              Console.WriteLine("Not Found"); break;
          }
      }

    不妨猜猜看程序的输出是什么。(Warning: Think at your own risk. Potential side effects include dry mouth, sleepless and mind blow). :)

posted @ | Feedback (17) | Filed Under [ .NET ]

Saturday, August 21, 2004

  毫无疑问:String是引用类型。另一方面,String和int (Int32), Single (float)一样都是.NET的Primitive类型,CLR完全了解String对象的内部构造,并且有内建的用于String操作的指令(ldstr)。String的源代码不是用.NET语言/C#实现的,而是在CLR代码当中。在SSCLI的代码中Object.H里面可以找到下面的结构:
               class StringObject : public Object
               {
                  private:
                            DWORD   m_ArrayLength;
                            DWORD   m_StringLength;
                            WCHAR   m_Characters[0];
                 ...
                };

    另外,.NET程序仍然有办法打破String的Immutable——当然通常不建议这样做:

  • unsafe code: C#可以使用unsafe代码直接编辑一个String的字符序列:
               fixed (char* p = str) {
                     p[2] = 'X';
               }
  • P/Invoke: 传递String作为变量给Native函数的时候,Native函数可以改变String的值。

             

posted @ | Feedback (10) | Filed Under [ .NET ]

    一直都想当然的接受了“strings are immutable”的事实,倒是没有仔细深入地想过原因。Google了一下,也没有找到满意的答案。我觉得大概有下面这些原因:

  •  避免字符串拷贝:如果String的内容可以改变,那么多个对象最好不要保存同一个字符串的引用,否则其中一个改变了String的内容就可能造成程序错误。这在多线程的环境下尤其重要,如果String不是immutable,那么它的所有编辑成员函数(Append, UpperCase等等)都必须要保证县城安全,性能损失惨重。如果每个对象保存String的一份Copy,则会消耗大量内存。Immutable实际上是一种近似于Copy-On-Write的折衷实现。
  • 维护集合语义:String是最常用来作为集合(Map,Hashtable) 键值得类型,而一旦一个String对象被用作集合的键值,改变String的内容就会破坏集合的语义,造成程序错误。
  • String Interning: 几乎没有人在程序中显式调用过String.Intern方法,但是Interning可能是.NET对String做的最重要的优化。简单的说,CLR为系统中的所有常量字符串维护了一张Hash表,所谓Interning就是在这个Hash表中找到一个动态生成的字符串的等值对象。通常比较两个String是否相等我们需要逐个字符的比较,但是如果两个String都经过Interning处理,因为Hashtable中的String都是唯一的,我们只需要比较这两个String的引用是否相等(是否指向同一个对象)。下面是String.Intern的一个简单的例子:
            bool StringEquals(string a, string b) {
                    string ia = string.Intern(a);
                    string ib = string.Intern(b);
                    return Object.ReferenceEquals(ia, ib);
            }

     C#编译器在两个地方隐含的使用了String Interning: 1) 如果在源代码中多次出现同样的字符串,只有一个对应的String会被放在CLR的StringPool当中,这个String对象会在代码中多次引用到。2) C/C++不支持基于String的switch/case,但是C#支持,这就是通过Intern实现的:C#编译器先把switch对应的字符串进行Interning处理,然后和下面的case进行引用比较就可以了。
     显然,String的Intern语义依赖于其不可变性:如果系统Intern Pool中的字符串可能会被改变,CLR就不能隐式的重用这些对象。

 

posted @ | Feedback (11) | Filed Under [ .NET ]

Wednesday, August 04, 2004

无意中发现Google针对几个Term的特殊搜索,包括MicrosoftAppleBSDLinux

查找Microsoft相关内容的时候msdn,gotdotnet等等网站的Page Ranking会被提高,这样更容易找到相关的信息。以后查找东西的时候就不用加上MSDN或者site:msdn.microsoft.com做关键字了。:)

上帝说的,有问题,找GOOGLE !!

posted @ | Feedback (16) | Filed Under [ .NET ]

  为回答一个CSDN上的问题Google了半天,居然没能找到一个像样的C#访问Structure Storage的例子。没办法,自己动手丰衣足食了。:)

  用C#作Structure Storage最大的麻烦是无数的COM Interface和API调用,实在没有心情把一堆COM接口函数都写出来了,只写了用到的几个: StgOpenStorageEx、IPropertySetStorage::Open、IPropertyStorage::ReadMultiple,而且功能也不全,只是取得Document的Creating Application属性,但是可以解决上面的问题了。(下载,没有找到合适的上传空间,随手申请了一个Free的)

如何判断一个文档是否是office文档????

FROM MY REPLY:

Office文件都是使用结构化存储复合文件(Structured Storage, Compound File),可以从它们的文件属性里面取得创建的应用程序,例如,在文件属性对话框当中的Summary一页有定义Application Name,可以看到文件使用Excel或者Word创建的。

但是在dotNet程序读取这些信息比较麻烦:
1)需要声明StgOpenStorageEx函数,包括参数的结构和常量定义。
2) 需要声明IPropertySetStorage,IPropertyStorage和IEnumSTATPROPSTG COM接口。
3) 定义Summary Information property set的FMTID:F29F85E0-4FF9-1068-AB91-08002B27B3D9。
4)通过StgOpenStorageEx打开文件,取得IPropertySetStorage.
5)用ReadMultiple读取Property ID = 0x12 (Creating Application),如果名字是Excel或者Word,那么是Office文件。

posted @ | Feedback (18) | Filed Under [ .NET ]

Thursday, July 22, 2004

  从MSN Explorer新申请的@msn.com email账号已经升级成了2G。这个比GMail的好处是直接支持POP3收件。如果你没有安装MSN Explorer的话,可以从这里下载。

posted @ | Feedback (31) | Filed Under [ 乱谈 ]