分类目录归档:.Net

.Net

String.getBytes()方法中的中文编码问题

String 的getBytes()方法是得到一个字串的字节数组,这是众所周知的。但特别要注意的是,本方法将返回该操作系统默认的编码格式的字节数组。如果你在使 用这个方法时不考虑到这一点,你会发现在一个平台上运行良好的系统,放到另外一台机器后会产生意想不到的问题。

String的getBytes()方法是得到一个字串的字节数组,这是众所周知的。但特别要注意的是,本方法将返回该操作系统默认的编码格式的字 节数组。如果你在使用这个方法时不考虑到这一点,你会发现在一个平台上运行良好的系统,放到另外一台机器后会产生意想不到的问题。比如下面的程序:

class TestCharset 
{

    public static void main(String[] args) 
{
new TestCharset().execute();
}

    private void execute() {
String s = "Hello!你好!";

byte[] bytes = s.getBytes();

        System.out.println("bytes
lenght is:" + bytes.length);

}

}

在一个中文WindowsXP系统下,运行时,结果为:

bytes lenght is:12

 但是如果放到了一个英文的UNIX环境下运行:

$ java TestCharset
bytes lenght is:9

如果你的程序依赖于该结果,将在后续操作中引起问题。为什么在一个系统中结果为12,而在另外一个却变成了9了呢?上面已经提到了,该方法是和平台(编码)相关的。

在中文操作系统中,getBytes方法返回的是一个GBK或者GB2312的中文编码的字节数组,其中中文字符,各占两个字节。而在英文平台中,一般的默认编码是“ISO-8859-1”,每个字符都只取一个字节(而不管是否非拉丁字符)。

Java中的编码支持

Java是支持多国编码的,在Java中,字符都是以Unicode进行存储的,比如,“你”字的Unicode编码是“4f60”,我们可以通过下面的实验代码来验证:

class TestCharset 
{

    public static void main(String[] args) 
{
char c = ‘你’;
int i = c;
System.out.println(c);
System.out.println(i);
}

}

不管你在任何平台上执行,都会有相同的输出:

20320

20320就是Unicode “4f60”的整数值。其实,你可以反编译上面的类,可以发现在生成的.class文件中字符“你”(或者其它任何中文字串)本身就是以Unicode编码进行存储的:

char c = ‘u4F60’;
… …

即使你知道了编码的编码格式,比如:

javac -encoding GBK TestCharset.java

编译后生成的.class文件中仍然是以Unicode格式存储中文字符或字符串的。使用String.getBytes(String charset)方法

所以,为了避免这种问题,我建议大家都在编码中使用String.getBytes(String charset)方法。下面我们将从字串分别提取ISO-8859-1和GBK两种编码格式的字节数组,看看会有什么结果:

class TestCharset 
{

    public static void main(String[] args) 
{
new TestCharset().execute();
}

    private void execute() {
String s = "Hello!你好!";

byte[] bytesISO8859 =null;
byte[] bytesGBK = null;

        try
{
bytesISO8859 =
s.getBytes("iso-8859-1");
bytesGBK = s.getBytes("GBK");
}
catch
(java.io.UnsupportedEncodingException e)
{
e.printStackTrace();
}

        System.out.println
("————–
n 8859 bytes:");
System.out.println("bytes is:     " + arrayToString(bytesISO8859));
System.out.println("hex format is:"
+ encodeHex(bytesISO8859));
System.out.println();

        System.out.println
("————–
n GBK bytes:");
System.out.println("bytes is:   
" + arrayToString(bytesGBK));
System.out.println("hex format
is:" + encodeHex(bytesGBK));

    }

    public static final String
encodeHex (byte[] bytes)
{
StringBuffer buff =
new StringBuffer(bytes.length * 2);
String b;
for (int i=0; i< bytes.length ; i++)
{
b = Integer.toHexString(bytes[i]); 
// byte是两个字节的,
而上面的Integer.toHexString会把字节扩展为4个字节
buff.append(b.length() > 2 ? b.substring(6,8) : b); 
buff.append(" ");
}
return buff.toString();
}

    public static final String
arrayToString (byte[] bytes)
{
StringBuffer buff = new StringBuffer();
for (int i=0; i< bytes.length ; i++)
{
buff.append(bytes[i] + " ");
}
return buff.toString();
}

}

执行上面程序将打印出:

————–
8859 bytes:
bytes is:     72 101 108 108 111 33 63 63 63
hex format is:48 65 6c 6c 6f 21 3f 3f 3f

————–
GBK bytes:
bytes is:     72 101 108 108 111 33
-60 -29 -70 -61 -93 -95
hex format is:48 65 6c 6c 6f 21 c4 e3 ba c3 a3 a1

可见,在s中提取的8859-1格式的字节数组长度为9,中文字符都变成了“63”,ASCII码为63的是“?”,一些国外的程序在国内中文环境下运行时,经常出现乱码,上面布满了“?”,就是因为编码没有进行正确处理的结果。

而提取的GBK编码的字节数组中正确得到了中文字符的GBK编码。字符“你”“好”“!”的GBK编码分别是:“c4e3”“bac3”“a3a1”。得到了正确的以GBK编码的字节数组,以后需要还原为中文字串时,可以使用下面方法:

new String(byte[] bytes,
String charset)

.net mvc html form beginform beginrouteform

FormExtensions类
该类定了3种类型的扩展方法,它们分别是BeginForm,BeginRouteForm,EndForm
BeginForm共有13种重载方法,这里参数不一一介绍。
BeginRouteForm共有12种重载方法,主要表现定义表单的开始部分,其中是以路由的方式设置action的值
EndForm 主要表现在表单的结尾,生成</form>
如下表单使用的几种方式:
方式1:

<%=Html.BeginForm("Login", "Home", FormMethod.Post, new { id="name"})%>
姓名<%=Html.TextBox("name", null, new { id="name",width="200px"})%><br />
密码<%=Html.Password("pass", null, new { id = "pass", width = "200px" })%><br />
<input type="submit" id="btnSubmit" value="Submit" />
<%Html.EndForm(); %>

这里注意<%=Html.BeginForm() %><%Html.EndForm();%>后者有 " ; "
Login:是指Action,Home是指Conroller,FormMethod.Post是指用Post方式来提交表单
new{id="name"} 是指表单元素属性。<form id="name" action="Home/Login" method="post"></form>

方式2:

<fieldset>
<%=Html.BeginRouteForm("Start", new { controller = "Home", action = "Login" }, FormMethod.Post)%>
姓名<%=Html.TextBox("name", null, new { id="name",width="200px"})%><br />
密码<%=Html.Password("pass", null, new { id = "pass", width = "200px" })%><br />
<input type="submit" id="Submit1" value="Submit" />
<%Html.EndForm(); %>
</fieldset>

这种方式的表单是以路由的方式设置action 的,"Start" 是路由的名称:

routes.MapRoute(
"Start",
"{controller}/{action}",
new { controller="Home",action="Index"}
);

方式3:

<fieldset>
<%using (Html.BeginForm("Login", "Home", FormMethod.Post, new { id = "name" }))
{
%>
姓名<%=Html.TextBox("name", null, new { id="name",width="200px"})%><br />
密码<%=Html.Password("pass", null, new { id = "pass", width = "200px" })%><br />
<input type="submit" id="btnSubmit" value="Submit" />
<%
} %>
</fieldset>

这种方式不需要<%Html.EndForm();%> 其余的方式基本相同

方式4:
就是普通的html代码

<form id="name" method="post" action="Home/Login">
</form>

这里不做介绍

C#中class和struct的区别和用法

1,class 是引用类型,structs是值类型

既然class是引用类型,class可以设为null。但是我们不能将struct设为null,因为它是值类型。

struct AStruct
{
  int aField;
}
class  AClass
{
  int aField;
}
class MainClass
{
  public static void Main()
  {
    AClass b = null; // No error.
    AStruct s = null; // Error [ Cannot convert null to 'AStruct'
    because it is a value type ].
  }
}

2,当你实例一个class,它将创建在堆上。而你实例一个struct,它将创建在栈上

3,你使用的是一个对class实例的引用。而你使用的不是对一个struct的引用。(而是直接使用它们)

4,当我们将class作为参数传给一个方法,我们传递的是一个引用。struct传递的是值而非引用。

5,structs, 不可以有初始化器,class可以有初始化器。

class MyClass
{
  int myVar =10;  //  no syntax error.
  public void MyFun( )
  {
    // statements
  }
}
struct MyStruct
{
  int myVar = 10;  //  syntax error.
  public void MyFun( )
  {
    // statements
  }
}

6,Classes 可以有明显的无参数构造器,但是Struct不可以

class MyClass
{
  int myVar = 10;
  public MyClass( ) // no syntax error.
  {
    // statements
  }
}
struct MyStruct
{
  int myVar;
  public MyStruct( ) // syntax error.
  {
    // statements
  }
}

7, 类使用前必须new关键字实例化,Struct不需要

MyClass aClassObj;     //  MyClass aClassObj=new MyClass(); is the correct format.aClassObj.
myVar=100;//NullReferenceException(because aClassObj does not contain a reference to an object of type myClass).
MyStruct  aStructObj;
aStructObj.myVar=100; //  no exception.

8, class支持继承和多态,Struct不支持. 注意:但是Struct 可以鹤类一样实现接口

9, 既然Struct不支持继承,其成员不能以protected 或Protected Internal 修饰

10, Class的构造器不需要初始化全部字段,Struct的构造器必须初始化所有字段

class MyClass    //No error( No matter whether the Field ’ MyClass.myString ’ is initialized or not ).
{
  int myInt;
  string myString;
  public MyClass( int aInt )
  {
    myInt = aInt;
  }
}
struct MyStruct    // Error ( Field ’ MyStruct.myString ’ must be fully assigned before it leaves the constructor ).
{
  int myInt;
  string myString;
  public MyStruct( int aInt )
  {
    myInt = aInt;
  }
}

11, Class可以定义析构器但是Struct不可以

12, Class比较适合大的和复杂的数据,Struct适用于作为经常使用的一些数据组合成的新类型。

适用场合:Struct有性能优势,Class有面向对象的扩展优势。
用于底层数据存储的类型设计为Struct类型,将用于定义应用程序行为的类型设计为Class。如果对类型将来的应用情况不能确定,应该使用Class。

C# 合并两个 list

using System;
using System.Collections.Generic;
class Program
{
  static void Main()
  {
    List a = new List();
    a.Add(1);
    a.Add(2);
    a.Add(5);
    a.Add(6);
    // Contains:
    // 1
    // 2
    // 5
    // 6
    int[] b = new int[3];
    b[0] = 7;
    b[1] = 6;
    b[2] = 7;
    a.AddRange(b);
    // Contains:
    // 1
    // 2
    // 5
    // 6
    // 7 [added]
    // 6 [added]
    // 7 [added]
    foreach (int i in a)
    {
      Console.WriteLine(i);
    }
  }
}
=== Output of the program ===
1
2
5
6
7
6
7

String.Format格式说明

C#格式化数值结果表

字符 说明 示例 输出
C 货币 string.Format("{0:C3}", 2) $2.000
D 十进制 string.Format("{0:D3}", 2) 002
E 科学计数法 1.20E+001 1.20E+001
G 常规 string.Format("{0:G}", 2) 2
N 用分号隔开的数字 string.Format("{0:N}", 250000) 250,000.00
X 十六进制 string.Format("{0:X000}", 12) C
string.Format("{0:000.000}", 12.2) 012.200

Strings

There really isn’t any formatting within a strong, beyond it’s alignment. Alignment works for any argument being printed in a String.Format call.

Sample Generates
String.Format("->{1,10}<-", "Hello"); -> Hello<-
String.Format("->{1,-10}<-", "Hello"); ->Hello <-

Numbers

Basic number formatting specifiers:

Specifier Type Format Output (Passed Double 1.42) Output (Passed Int -12400)
c Currency {0:c} $1.42 -$12,400
d Decimal (Whole number) {0:d} System.FormatException -12400
e Scientific {0:e} 1.420000e+000 -1.240000e+004
f Fixed point {0:f} 1.42 -12400.00
g General {0:g} 1.42 -12400
n Number with commas for thousands {0:n} 1.42 -12,400
r Round trippable {0:r} 1.42 System.FormatException
x Hexadecimal {0:x4} System.FormatException cf90

Custom number formatting:

Specifier Type Example Output (Passed Double 1500.42) Note
0 Zero placeholder {0:00.0000} 1500.4200 Pads with zeroes.
# Digit placeholder {0:(#).##} (1500).42
. Decimal point {0:0.0} 1500.4
, Thousand separator {0:0,0} 1,500 Must be between two zeroes.
,. Number scaling {0:0,.} 2 Comma adjacent to Period scales by 1000.
% Percent {0:0%} 150042% Multiplies by 100, adds % sign.
e Exponent placeholder {0:00e+0} 15e+2 Many exponent formats available.
; Group separator see below  

The group separator is especially useful for formatting currency values which require that negative values be enclosed in parentheses. This currency formatting example at the bottom of this document makes it obvious:

Dates

Note that date formatting is especially dependant on the system’s regional settings; the example strings here are from my local locale.

Specifier Type Example (Passed System.DateTime.Now)
d Short date 10/12/2002
D Long date December 10, 2002
t Short time 10:11 PM
T Long time 10:11:29 PM
f Full date & time December 10, 2002 10:11 PM
F Full date & time (long) December 10, 2002 10:11:29 PM
g Default date & time 10/12/2002 10:11 PM
G Default date & time (long) 10/12/2002 10:11:29 PM
M Month day pattern December 10
r RFC1123 date string Tue, 10 Dec 2002 22:11:29 GMT
s Sortable date string 2002-12-10T22:11:29
u Universal sortable, local time 2002-12-10 22:13:50Z
U Universal sortable, GMT December 11, 2002 3:13:50 AM
Y Year month pattern December, 2002

The ‘U’ specifier seems broken; that string certainly isn’t sortable.
Custom date formatting:
 

Specifier Type Example Example Output
dd Day {0:dd} 10
ddd Day name {0:ddd} Tue
dddd Full day name {0:dddd} Tuesday
f, ff, … Second fractions {0:fff} 932
gg, … Era {0:gg} A.D.
hh 2 digit hour {0:hh} 10
HH 2 digit hour, 24hr format {0:HH} 22
mm Minute 00-59 {0:mm} 38
MM Month 01-12 {0:MM} 12
MMM Month abbreviation {0:MMM} Dec
MMMM Full month name {0:MMMM} December
ss Seconds 00-59 {0:ss} 46
tt AM or PM {0:tt} PM
yy Year, 2 digits {0:yy} 02
yyyy Year {0:yyyy} 2002
zz Timezone offset, 2 digits {0:zz} -05
zzz Full timezone offset {0:zzz} -05:00
: Separator {0:hh:mm:ss} 10:43:20
/ Separator {0:dd/MM/yyyy} 10/12/2002

Enumerations

 

Specifier Type
g Default (Flag names if available, otherwise decimal)
f Flags always
d Integer always
x Eight digit hex.

Some Useful Examples

String.Format("{0:$#,##0.00;($#,##0.00);Zero}", value);
This will output "$1,240.00" if passed 1243.50. It will output the same format but in parentheses if the number is negative, and will output the string "Zero" if the number is zero.
String.Format("{0:(###) ###-####}", 18005551212);
This will output "(800) 555-1212".
 
变量.ToString()
字符型转换 转为字符串

12345.ToString("n"); //生成 12,345.00
12345.ToString("C"); //生成 ¥12,345.00
12345.ToString("e"); //生成 1.234500e+004
12345.ToString("f4"); //生成 12345.0000
12345.ToString("x"); //生成 3039 (16进制)
12345.ToString("p"); //生成 1,234,500.00%

C# List 排序

写一个sorter

public class CourseSorter:IComparer
{
  #region IComparer Members
  public int Compare(CourseDto x, CourseDto y)
  {
    return x.Title.CompareTo(y.Title);
  }
  #endregion
}

用的时候list.sort(new Sorter());即可

NHibernate??????sql°??±?????????á??×??????è??·????à?????????à??

public IList<ShopDownloadAmountEntity> GetDayByShopBetween(int shopID, DateTime startTime, DateTime endTime)
{
StringBuilder sb = new StringBuilder();
sb.Append("SELECT sum(sizeamount) as SizeAmount,[ShopID],");

sb.Append("dateadd(hh, – datepart(hour,downloadtime) % 24 ,downloadtime) as DownloadTime ");
sb.Append("FROM ShopDownloadAmount ");
sb.Append("WHERE downloadtime between ‘" + startTime + "’ and ‘" + endTime + "’");
sb.Append(" GROUP BY shopid, dateadd(hh, – datepart(hour,downloadtime) % 24 ,downloadtime) ");
sb.Append(" order by dateadd(hh, – datepart(hour,downloadtime) % 24 ,downloadtime)");//sql string

ISQLQuery sql = NHibernateSession.CreateSQLQuery(sb.ToString());
sql.AddScalar("SizeAmount", NHibernateUtil.Int32);//set type of data
sql.AddScalar("ShopID", NHibernateUtil.Int32);
sql.AddScalar("DownloadTime", NHibernateUtil.DateTime);
sql.SetResultTransformer(Transformers.AliasToBean(typeof(ShopDownloadAmountEntity)));//make the result set to entity
return sql.List<ShopDownloadAmountEntity>();
}
ShopDownloadAmountEntity???????à??SizeAmount??ShopID??DownloadTime??setter

Nhibernate ICriteria sum字段求和

ICriteria criteria = NHibernateSession.CreateCriteria(typeof(DownloadLogEntity));
criteria.CreateAlias("Enduser", "enduser");
criteria.Add(Expression.Eq("enduser.EnduserID",enduserID));
criteria.Add(Expression.Between("DownloadTime", day, day.AddDays(1)));
criteria.SetProjection(Projections.Sum("FileSize"));
return (int)criteria.UniqueResult();