2011年4月25日 星期一

iOS開發中常用代碼解釋

#include /* 说明 malloc, NULL, size_t */
#include /* 说明 va_ 相关类型和函数 */
#include /* 说明 strcat 等 */
char *vstrcat(const char *first, ...)
{
size_t len;
char *retbuf;
va_list argp;
char *p;
if(first == NULL)
return NULL;
len = strlen(first);
va_start(argp, first);
while((p = va_arg(argp, char *)) != NULL)
len += strlen(p);
va_end(argp);
retbuf = malloc(len + 1); /* +1 包含终止符 \0 */
if(retbuf == NULL)
return NULL; /* 出错 */
(void)strcpy(retbuf, first);
va_start(argp, first); /* 重新开始扫描 */
while((p = va_arg(argp, char *)) != NULL)
(void)strcat(retbuf, p);
va_end(argp);
retbuf = malloc(len + 1); /* +1 包含终止符 \0 */
if(retbuf == NULL)
return NULL; /* 出错 */
(void)strcpy(retbuf, first);
va_start(argp, first); /* 重新开始扫描 */
while((p = va_arg(argp, char *)) != NULL)
(void)strcat(retbuf, p);
va_end(argp);
return retbuf;
}
%c 一个单一的字符
%d 一个十进制整数
%i 一个整数
%e, %f, %g 一个浮点数
%o 一个八进制数
%s 一个字符串
%x 一个十六进制数
%p 一个指针
%n 一个等于读取字符数量的整数
%u 一个无符号整数
%[] 一个字符集
%% 一个精度符号
//一、NSString
/*----------------创建字符串的方法----------------*/
1、创建常量字符串。
NSString *astring = @"This is a String!";
2、创建空字符串,给予赋值。
NSString *astring = [[NSString alloc] init];
astring = @"This is a String!";
NSLog(@"astring:%@",astring);
[astring release];
3、在以上方法中,提升速度:initWithString方法
NSString *astring = [[NSString alloc] initWithString:@"This is a String!"];
NSLog(@"astring:%@",astring);
[astring release];
4、用标准c创建字符串:initWithCString方法
char *Cstring = "This is a String!";
NSString *astring = [[NSString alloc] initWithCString:Cstring];
NSLog(@"astring:%@",astring);
[astring release];
5、创建格式化字符串:占位符(由一个%加一个字符组成)
int i = 1;
int j = 2;
NSString *astring = [[NSString alloc]
initWithString:[NSString stringWithFormat:@"%d.This is %i string!",i,j]];
NSLog(@"astring:%@",astring);
[astring release];
6、创建临时字符串
NSString *astring;
astring = [NSString stringWithCString:"This is a temporary string"];
NSLog(@"astring:%@",astring);
/*----------------从文件读取字符串:initWithContentsOfFile方法 ----------------*/
NSString *path = @"astring.text";
NSString *astring = [[NSString alloc] initWithContentsOfFile:path];
NSLog(@"astring:%@",astring);
[astring release];
/*----------------写字符串到文件:writeToFile方法 ----------------*/
NSString *astring = [[NSString alloc] initWithString:@"This is a String!"];
NSLog(@"astring:%@",astring);
NSString *path = @"astring.text";
[astring writeToFile: path atomically: YES];
[astring release];
/*---------------- 比较两个字符串----------------*/
用C比较:strcmp函数
char string1[] = "string!";
char string2[] = "string!";
if(strcmp(string1, string2) = = 0)
{
NSLog(@"1");
}
isEqualToString方法
NSString *astring01 = @"This is a String!";
NSString *astring02 = @"This is a String!";
BOOL result = [astring01 isEqualToString:astring02];
NSLog(@"result:%d",result);
compare方法(comparer返回的三种值)
NSString *astring01 = @"This is a String!";
NSString *astring02 = @"This is a String!";
BOOL result = [astring01 compare:astring02] = = NSOrderedSame;
NSLog(@"result:%d",result);
NSOrderedSame 判断两者内容是否相同
NSString *astring01 = @"This is a String!";
NSString *astring02 = @"this is a String!";
BOOL result = [astring01 compare:astring02] = = NSOrderedAscending;
NSLog(@"result:%d",result);
//NSOrderedAscending 判断两对象值的大小(按字母顺序进行比较,astring02大于astring01为真)
NSString *astring01 = @"this is a String!";
NSString *astring02 = @"This is a String!";
BOOL result = [astring01 compare:astring02] = = NSOrderedDescending;
NSLog(@"result:%d",result);
//NSOrderedDescending 判断两对象值的大小(按字母顺序进行比较,astring02小于astring01为真)
不考虑大 小写比较字符串1
NSString *astring01 = @"this is a String!";
NSString *astring02 = @"This is a String!";
BOOL result = [astring01 caseInsensitiveCompare:astring02] = = NSOrderedSame;
NSLog(@"result:%d",result);
//NSOrderedDescending判断两对象值的大小(按字母顺序进行比较,astring02小于astring01为 真)
不考虑大小写比较字符串2
NSString *astring01 = @"this is a String!";
NSString *astring02 = @"This is a String!";
BOOL result = [astring01 compare:astring02
options:NSCaseInsensitiveSearch | NSNumericSearch] = = NSOrderedSame;
NSLog(@"result:%d",result);
//NSCaseInsensitiveSearch:不区分大小写比较 NSLiteralSearch:进行完全比较,区分大小写 NSNumericSearch:比较字符串的字符个数,而不是字符值。
/*----------------改变字符串的大小写----------------*/
NSString *string1 = @"A String";
NSString *string2 = @"String";
NSLog(@"string1:%@",[string1 uppercaseString]);//大写
NSLog(@"string2:%@",[string2 lowercaseString]);//小写
NSLog(@"string2:%@",[string2 capitalizedString]);//首字母大小
/*----------------在串中搜索子串 ----------------*/
NSString *string1 = @"This is a string";
NSString *string2 = @"string";
NSRange range = [string1 rangeOfString:string2];
int location = range.location;
int leight = range.length;
NSString *astring = [[NSString alloc]
initWithString:[NSString stringWithFormat:@"Location:%i,Leight:%i"
,location,leight]];
NSLog(@"astring:%@",astring);
[astring release];
/*----------------抽取子串 ----------------*/
-substringToIndex: 从字符串的开头一直截取到指定的位置,但不包括该位置的字符
NSString *string1 = @"This is a string";
NSString *string2 = [string1 substringToIndex:3];
NSLog(@"string2:%@",string2);
-substringFromIndex: 以指定位置开始(包括指定位置的字符),并包括之后的全部字符
NSString *string1 = @"This is a string";
NSString *string2 = [string1 substringFromIndex:3];
NSLog(@"string2:%@",string2);
-substringWithRange: //按照所给出的位置,长度,任意地从字符串中截取子串
NSString *string1 = @"This is a string";
NSString *string2 = [string1 substringWithRange:NSMakeRange(0, 4)];
NSLog(@"string2:%@",string2);
const char *fieldValue = [value cStringUsingEncoding:NSUTF8StringEncoding];
const char *fieldValue = [value UTF8String];
NSString 转 NSData
NSString* str= @"kilonet";
NSData* data=[str dataUsingEncoding:NSUTF8StringEncoding];
Date format用法:
-(NSString *) getDay:(NSDate *) d
{
NSString *s ;
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"YYYY/MM/dd hh:mm:ss"];
s = [format stringFromDate:d];
[format release];
return s;
}
各地时区获取:
NSDate *nowDate = [NSDate new];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
// 根据时区名字获取当前时间,如果该时区不存在,默认获取系统当前时区的时间
// NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Europe/Andorra"];
// [formatter setTimeZone:timeZone];
//获取所有的时区名字
NSArray *array = [NSTimeZone knownTimeZoneNames];
// NSLog(@"array:%@",array);
//for循环
// for(int i=0;i<[array count];i++)
// {
// NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:[array objectAtIndex:i]];
// [formatter setTimeZone:timeZone];
// NSString *locationTime = [formatter stringFromDate:nowDate];
// NSLog(@"时区名字:%@ : 时区当前时间: %@",[array objectAtIndex:i],locationTime);
// //NSLog(@"timezone name is:%@",[array objectAtIndex:i]);
// }
//快速枚举法
for(NSString *timeZoneName in array){
[formatter setTimeZone:[NSTimeZone timeZoneWithName:timeZoneName]];
NSLog(@"%@,%@",timeZoneName,[formatter stringFromDate:nowDate]);
}
[formatter release];
[nowDate release];
NSCalendar用法:
-(NSString *) getWeek:(NSDate *) d {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
unsigned units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit;
NSDateComponents *components = [calendar components:units fromDate:d];
[calendar release];
switch ([components weekday]) {
case 2:
return @"Monday";
break;
case 3:
return @"Tuesday";
break;
case 4:
return @"Wednesday";
break;
case 5:
return @"Thursday";
break;
case 6:
return @"Friday";
break;
case 7:
return @"Saturday";
break;
case 1:
return @"Sunday";
break;
default:
return @"No Week";
break;
}
// 用components,我们可以读取其他更多的数据。
}
4. 用Get方式读取网络数据:
将网络数读取为字符串
- (NSString *) getDataByURL:(NSString *) url {
return [[NSString alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]] encoding:NSUTF8StringEncoding];
}
//读取网络图片
- (UIImage *) getImageByURL:(NSString *) url {
return [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]]];
}
多线程
[NSThread detachNewThreadSelector:@selector(scheduleTask) toTarget:self withObject:nil];
-(void) scheduleTask {
//create a pool
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//release the pool;
[pool release];
}
//如果有参数,则这么使用:
[NSThread detachNewThreadSelector:@selector(scheduleTask:) toTarget:self withObject:[NSDate date]];
-(void) scheduleTask:(NSDate *) mdate {
//create a pool
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//release the pool;
[pool release];
}
//注意selector里有冒号。
//在线程里运行主线程里的方法
[self performSelectorOnMainThread:@selector(moveToMain) withObject:nil waitUntilDone:FALSE];
6. 定时器NSTimer用法:
代码
// 一个可以自动关闭的Alert窗口
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:[@"一个可以自动关闭的Alert窗口"
delegate:nil
cancelButtonTitle:nil //NSLocalizedString(@"OK", @"OK") //取消任何按钮
otherButtonTitles:nil];
//[alert setBounds:CGRectMake
(alert.bounds.origin.x, alert.bounds.origin.y,
alert.bounds.size.width, alert.bounds.size.height+30.0)];
[alert show];
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
// Adjust the indicator so it is up a few pixels from the bottom of the alert
indicator.center = CGPointMake(alert.bounds.size.width/2, alert.bounds.size.height-40.0);
[indicator startAnimating];
[alert insertSubview:indicator atIndex:0];
[indicator release];
[NSTimer scheduledTimerWithTimeInterval:3.0f
target:self
selector:@selector(dismissAlert:)
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:alert,
@"alert", @"testing ", @"key" ,nil] //如果不用传递参数,那么可以将此项设置为nil.
repeats:NO];
NSLog(@"release alert");
[alert release];
-(void) dismissAlert:(NSTimer *)timer{
NSLog(@"release timer");
NSLog([[timer userInfo] objectForKey:@"key"]);
UIAlertView *alert = [[timer userInfo] objectForKey:@"alert"];
[alert dismissWithClickedButtonIndex:0 animated:YES];
}
定时器停止使用:
[timer invalidate];
timer = nil;
7. 用户缺省值NSUserDefaults读取:
//得到用户缺省值
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
//在缺省值中找到AppleLanguages, 返回值是一个数组
NSArray* languages = [defs objectForKey:@"AppleLanguages"];
NSLog(@"all language语言 is %@", languages);
//在得到的数组中的第一个项就是用户的首选语言了
NSLog(@"首选语言 is %@",[languages objectAtIndex:0]);
//get the language & country code
NSLocale *currentLocale = [NSLocale currentLocale];
NSLog(@"Language Code is %@", [currentLocale objectForKey:NSLocaleLanguageCode]);
NSLog(@"Country Code is %@", [currentLocale objectForKey:NSLocaleCountryCode
8. View之间切换的动态效果设置:
SettingsController *settings = [[SettingsController alloc]initWithNibName:@"SettingsView" bundle:nil];
settings.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; //水平翻转
[self presentModalViewController:settings animated:YES];
[settings release];
9.NSScrollView 滑动用法:
-(void) scrollViewDidScroll:(UIScrollView *)scrollView{
NSLog(@"正在滑动中...");
}
//用户直接滑动NSScrollView,可以看到滑动条
-(void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
}
// 通过其他控件触发NSScrollView滑动,看不到滑动条
- (void) scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
}
11.键盘处理系列
//set the UIKeyboard to switch to a different text field when you press return
//switch textField to the name of your textfield
[textField becomeFirstResponder];
srandom(time(NULL)); //随机数种子
id d = random(); // 随机数
4. iPhone的系统目录:
//得到Document目录:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//得到temp临时目录:
NSString *tempPath = NSTemporaryDirectory();
//得到目录上的文件地址:
NSString *文件地址 = [目录地址 stringByAppendingPathComponent:@"文件名.扩展名"];
5. 状态栏显示Indicator:
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
6.app Icon显示数字:
- (void)applicationDidEnterBackground:(UIApplication *)application{
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:5];
}
7.sqlite保存地址:
代码
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *thePath = [paths objectAtIndex:0];
NSString *filePath = [thePath stringByAppendingPathComponent:@"kilonet1.sqlite"];
NSString *dbPath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:@"kilonet2.sqlite"];
8.Application退出:exit(0);
9. AlertView,ActionSheet的cancelButton点击事件:
代码
-(void) actionSheet :(UIActionSheet *) actionSheet didDismissWithButtonIndex:(NSInteger) buttonIndex {
NSLog(@"cancel actionSheet........");
//当用户按下cancel按钮
if( buttonIndex == [actionSheet cancelButtonIndex]) {
exit(0);
}
// //当用户按下destructive按钮
// if( buttonIndex == [actionSheet destructiveButtonIndex]) {
// // DoSomething here.
// }
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
NSLog(@"cancel alertView........");
if (buttonIndex == [alertView cancelButtonIndex]) {
exit(0);
}
}
10.给Window设置全局的背景图片:
window.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"coolblack.png"]];
11. UITextField文本框显示及对键盘的控制:
代码
#pragma mark -
#pragma mark UITextFieldDelegate
//控制键盘跳转
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField == _txtAccount) {
if ([_txtAccount.text length]==0) {
return NO;
}
[_txtPassword becomeFirstResponder];
} else if (textField == _txtPassword) {
[_txtPassword resignFirstResponder];
}
return YES;
}
//输入框背景更换
-(BOOL) textFieldShouldBeginEditing:(UITextField *)textField{
[textField setBackground:[UIImage imageNamed:@"ctext_field_02.png"]];
return YES;
}
-(void) textFieldDidEndEditing:(UITextField *)textField{
[textField setBackground:[UIImage imageNamed:@"ctext_field_01.png"]];
}
12.UITextField文本框前面空白宽度设置以及后面组合按钮设置:
代码
//给文本输入框后面加入空白
_txtAccount.rightView = _btnDropDown;
_txtAccount.rightViewMode = UITextFieldViewModeAlways;
//给文本输入框前面加入空白
CGRect frame = [_txtAccount frame];
frame.size.width = 5;
UIView *leftview = [[UIView alloc] initWithFrame:frame];
_txtAccount.leftViewMode = UITextFieldViewModeAlways;
_txtAccount.leftView = leftview;
13. UIScrollView 设置滑动不超出本身范围:
[fcScrollView setBounces:NO];
14. 在drawRect里画文字:
UIFont * f = [UIFont systemFontOfSize:20];
[[UIColor darkGrayColor] set];
NSString * text = @"hi \nKiloNet";
[text drawAtPoint:CGPointMake(center.x,center.y) withFont:f];
15. NSArray查找是否存在对象时用indexOfObject,如果不存在则返回为NSNotFound.
16. NString与NSArray之间相互转换:
array = [string componentsSeparatedByString:@","];
string = [[array valueForKey:@"description"] componentsJoinedByString:@","];
17. TabController随意切换tab bar:
[self.tabBarController setSelectedIndex:tabIndex];
或者 self.tabBarController.selectedIndex = tabIndex;
或者实现下面的delegate来扑捉tab bar的事件:
代码-(BOOL) tabBarController:(UITabBarController *)tabBarController
shouldSelectViewController:(UIViewController *)viewController
{ if ([viewController.tabBarItem.title isEqualToString: NSLocalizedString(@"Logout",nil)])
{ [self showLogout]; return NO; } return YES;}
18. 自定义View之间切换动画:
代码
- (void) pushController: (UIViewController*) controller
withTransition: (UIViewAnimationTransition) transition
{
[UIView beginAnimations:nil context:NULL];
[self pushViewController:controller animated:NO];
[UIView setAnimationDuration:.5];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationTransition:transition forView:self.view cache:YES];
[UIView commitAnimations];
}
CATransition *transition = [CATransition animation];
transition.duration = kAnimationDuration;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromTop;
transitioning = YES;
transition.delegate = self;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
self.navigationController.navigationBarHidden = NO;
[self.navigationController pushViewController:tableViewController animated:YES];
20.计算字符串长度:
CGFloat w = [title sizeWithFont:[UIFont fontWithName:@"Arial" size:18]].width;
23.在使用UISearchBar时,将背景色设定为clearColor,或者将translucent设为YES,都不能使背景透明,经过一番研究,发现了一种超级简单和实用的方法:
1
[[searchbar.subviews objectAtIndex:0]removeFromSuperview];
背景完全消除了,只剩下搜索框本身了。
24. 图像与缓存 :
UIImageView *wallpaper = [[UIImageView alloc] initWithImage:
[UIImage imageNamed:@"icon.png"]]; // 会缓存图片
UIImageView *wallpaper = [[UIImageView alloc] initWithImage:
[UIImage imageWithContentsOfFile:@"icon.png"]]; // 不会缓存图片
25. iphone-常用的对视图图层(layer)的操作
对图层的操作:
(1.给图层添加背景图片:
myView.layer.contents = (id)[UIImage imageNamed:@"view_BG.png"].CGImage;
(2.将图层的边框设置为圆脚
myWebView.layer.cornerRadius = 8;
myWebView.layer.masksToBounds = YES;
(3.给图层添加一个有色边框
myWebView.layer.borderWidth = 5;
myWebView.layer.borderColor = [[UIColor colorWithRed:0.52 green:0.09 blue:0.07 alpha:1] CGColor];

2011年4月22日 星期五

關於.NET Framework / ASP.NET這條路

.NET Framework歷史版本及功能,第6點是我自己整理。
.NET Framework 1.0
.NET Framework 1.1
.NET Framework 2.0
CLR + Windows forms + Web Services + ASP.NET
.NET Framework 3.0
.NET Framework 2.0 + WCF + WF + WPF + CardSpace
.NET Framework 3.5
.NET Framework 3.0 + LINQ + AJAX + REST
.NET Framework 4.0
.NET Framework 3.5 + Entity Framework + ASP.NET MVC + Parallel
先說結論,再說故事。

結論
通常第一版都是實驗性質或有很大的改進空間,不管是多好的東西都一樣。從第二版開始,似乎是個不錯的開始。

故事1--.NET Framework 2.0

現在的資訊爆炸,但這些資訊你可以不看。但就資訊技術人員而言,技術更新的速度才是一大挑戰,以前一個技術能讓你十年有飯吃,現在一個技術能讓你三年有飯吃就很不錯了,技術更新的速度讓人「怕怕的」,我實在很敬佩那些永遠走在資訊前端的前輩,有著過人的領悟力與學習力。

話說從前,我是學習Visual Basic 6與ASP,為什學這兩樣?也沒有什麼特別的原因,學校教什麼,我們就學什麼,而且從Visual Basic 6接ASP(VB Script)還很順,所以在使用ASP上還算順手。

後來,微軟登高一呼:「我們要進入.NET的世界!」然後推出了.NET Framework 1.0,那時的ASP由2.0到3.0,ASP 3.0之後微軟也很明確表示,ASP不再更新維護了,因為微軟要全力推「.NET」這個…產品嗎?概念嗎?程式語言嗎?反正那時候認為是新一代的ASP就是了。

我還很認真的去買書來看,結果一個月後我就放棄了,那ASP.NET 1.0是什麼鬼東西,看不懂,結果我又回到ASP的身邊,反正工作上也只用的到ASP,會不會ASP.NET也不影響工作。

一段時間又過去了,突然發現,怎麼大家又在推「ASP.NET 2.0」,而且這一次好像又不一樣了,Survey之後發現,.NET Framework 2.0是個全新的改版,不同於.NET Framework 1.0 / 1.1,而且微軟似乎也發現開發人員的辛苦,承諾未來的改版會使用「積木式」方式來改版,就是說,你學了.NET Framework 2.0的東西,拿到.NET Framework 3.0 / 3.5 / 4.0上一樣都可以使用,讓你不會天天做打掉重練的工作。就是這一點,讓我試著相信它,開始學習著ASP.NET 2.0。

另外在.NET Framework 2.0還有一項重要事,那就是開發工具的完備,那是在.NET Framework 1.0 / 1.1所沒有的。在.NET Framework 2.0有Visual Studio 2005 / 2008兩個版本,我學ASP.NET 2.0時已經是Visual Studio 2008版本,就Visual Studio 2008來開發ASP.NET 2.0而言,還蠻快樂的。

[Key Point 1].NET Framework → .NET Framework 2.0

故事2--LINQ to SQL

時間飛快,在學習.NET Framework 2.0不久,.NET Framwork 3.0推出,3.0還沒有什麼感覺,又不久之後,馬上再推出.NET Framework 3.5,這個3.5版的推出又是一個高潮 ,因為它提供了幾個重要的元素「LINQ + AJAX + REST」,其中最紅的就是LINQ(Language-Integrated Query),LINQ是個統稱,內容幾項重要的技術內容LINQ to Object、LINQ to ADO.NET(LINQ to DataSet、LINQ to SQL)、LINQ to XML、LINQ to Entities。

如果有學LINQ,我相信其中的LINQ to SQL會是你的一項主力。不過,就在2008一篇「Update on LINQ to SQL and LINQ to Entities Roadmap」的微軟官方文章,給所有有學LINQ to SQL的人一顆炸彈,他們的一句「他們會很認真的聽取 LINQ to SQL 社群的聲音,然後好好的來加強我們的 Entity Framework 產品」嚇死了一堆人。

很明顯,他們將主力放在Entity Framework上面(可看成LINQ to Entities這一項),那LINQ to SQL呢?在.NET Framework 4.0有做一些錯誤修正,但請注意,他們已經很明顯未來會不斷加強的是Entity Framework,目前在.NET Framework 4.0裡的是Entity Framework 4.0,現在已經有Entity Framework 4.1版本可以下載安裝使用。

[Key Point 2] LINQ to SQL → LINQ to Entities → Entity Famework

故事3--Web Service

在ASP.NET 2.0時,提供了一個很棒的Web Services服務,也就是說,我可以把相關Function透過伺服器分享出來,分享給網路上其他需要的人使用。使用者只要引用我的Web Services,就可以立即擁有我所提供的服務。

Web Services好是好,但也是有一些問題,所以Microsoft在.NET Framework 3.5又提出了一個 REST,董大偉老師有篇介紹 REST 文章,可以知一二。

[Key Point 3] Web Service → REST

故事4-- ASP.NET MVC 2.0

在Visual Studio 2008 + .NET Framework 3.5時,微軟還推出了一個很重要的Web技術,即ASP.NET MVC 1.0,老實說,ASP.NET MVC 1.0我連碰都沒碰過,但我碰了ASP.NET MVC 2.0。ASP.NET MVC 2.0對我而言,感覺又回到寫ASP,再強調一下,是「感覺」,不是「回到寫ASP」,什麼感覺,是一種「操之在我」的感覺,但靈活度是ASP及ASP.NET完全比不上的感覺。

ASP.NET Web Form入門而言,實在好學好用,但當你要深入一些時,會發現就沒那怎容易,當你想把你的魔手伸的越深入,你就會發現Web Form的控制項越複雜。但一切一切問題在ASP.NET MVC身上都沒有,因為它根本沒有控制項!

不過想要學習、使用ASP.NET MVC,就我個人認為,不是件簡單的事,因為有許多觀念必須先行建立,物件導向程式設計、Visual Basic 9/10語法熟悉度、LINQ、.NET Framework Class…這些都會了,再學習ASP.NET MVC會比較輕鬆,不然走一步算一步是比較辛苦點。

最近,ASP.NET MVC 3又正式推出,在ASP.NET MVC 3裡有一個重點Razor View Engine,Razor是一個新的View Engine,在我們撰寫ASP.NET MVC 3時,它提供了更簡潔的語法。不過馬上就有人指出,使用Razor怪怪的,因為它會破壞MVC的規則,將Controller的內容放到View裡。但Razor也讓我們在撰寫View提供了很好的規範,不會整個畫面裡都是<% ~ %>的符號。

Razor最早是與另一套微軟免費入門網頁開發軟體WebMatrix所採用,後來可能覺的很不錯,所以在ASP.NET MVC 3.0也加入了Razor的支援。所以到了ASP.NET MVC 3.0你可以選擇使用<% ~ %>的Visual Basic語法,也可以使用Razor的@Code ~ End Code或@ViewData()之類的語法。

[Key Point 4] ASP.NET MVC 1.0 → ASP.NET MVC 2.0 / 3.0, Razor View Engine

整理一下Key Point

[Key Point 1] .NET Framework 1.0 → .NET Framework 2.0
[Key Point 2] LINQ to SQL → LINQ to Entities
[Key Point 3] Web Services → REST
[Key Point 4] Web Form → ASP.NET MVC
每個技術背景都有故事,在.NET Framework的裡的每個進步,都是為了解決一些前一代的一些問題或提供更好的解決方案。我們不能怪微軟說,為什麼說放就放,說改就改,而是要去思考及了解前因後果,當然不是每件事的回答或解釋都讓開發人員滿意。

由以上來看,.NET Framework到目前為止,所推出的第一代技術都會被第二代技術替代,其實這是必然的結果,只是改的太兇,苦的是這是程式開發人員。但我們在每一項新技術推出之時,每篇文章、專欄、ABC大會、XYZ研討會…你都只會聽到「優點」,但我在意的是「缺點」呢?例如,這一篇「對Entity Framework Performance 抱怨以及建議」,說明Entity Framework 1.0版實在不怎麼樣,但現在的Entity Framework 4.0到是沒聽到這種聲音了,原因前提過了,Entity Framework是現在的主力。而缺點,通常會在一段時間,實際使用於專案上之後,才會出現。

如果你現在才要進入.NET Framework的世界,我個人是建議,如果是那種「最新」的技術,有精力再去研究,如果是第二版之後改進的技術,通常是可以上場見世面了。了解每一項技術所提供的優點及缺點,所以當我聽完優點後,會靜一靜,等等看市場上有沒有其他聲音。以上是我個人就我在.NET Framework/ASP.NET的學習上的驗經談。我的時間、精力有限,所以在.NET Framework/ASP.NET這條路,我是選擇走「老二哲學」。

source: http://kkbruce.blogspot.com/2011/04/net-framework-aspnet.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+KingkongBruce+%28KingKong+Bruce%E8%A8%98%E4%BA%8B%29&utm_content=Google+Reader