{
try
{
Response.Write(1);
return;
}
catch (Exception ex)
{
Response.Write(2);
}
finally
{
Response.Write(3);
}
}
protected void Page_Load(object sender, EventArgs e)
{
try
{
Response.Write(1);
string a = "12a3";
int i = Convert.ToInt32(a);
}
catch (Exception ex)
{
Response.Write(2);
return;
}
finally
{
Response.Write(3);
}
}
session喜欢丢值且占内存,Cookis不安全,请问用什么办法代替这两种原始的方法
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 ASP.NET页面之间传递值的几种方式 2 3 页面传值是学习asp.net初期都会面临的一个问题,总的来说有页面传值、存储对象传值、ajax、类、model、表单等。但是一般来说,常用的较简单有QueryString,Session,Cookies,Application,Server.Transfer。 4 5 6 7 一、QueryString 8 9 QueryString是一种非常简单的传值方式,他可以将传送的值显示在浏览器的地址栏中。如果是传递一个或多个安全性要求不高或是结构简单的数值时,可以使用这个方法。但是对于传递数组或对象的话,就不能用这个方法了。 10 11 这种方法的优点:1.使用简单,对于安全性要求不高时传递数字或是文本值非常有效。 12 这种方法的缺点:1.缺乏安全性,由于它的值暴露在浏览器的URL地址中的。 13 2.不能传递对象。 14 15 使用方法:1.在源页面的代码中用需要传递的名称和值构造URL地址。 16 2.在源页面的代码用Response.Redirect(URL);重定向到上面的URL地址中。 17 3.在目的页面的代码使用Request.QueryString["name"];取出URL地址中传递的值。 18 19 例子:(1)a.aspx 20 21 private void Button1_Click(object sender, System.EventArgs e) 22 { 23 string s_url; 24 s_url = "b.aspx?name=" + Label1.Text; 25 Response.Redirect(s_url); 26 } 27 28 (2)b.aspx 29 30 private void Page_Load(object sender, EventArgs e) 31 { 32 Label2.Text = Request.QueryString["name"]; 33 } 34 35 36 37 二、Session 38 39 想必这个肯定是大家使用中最常见的用法了,其操作与Application类似,作用于用户个人,所以,过量的存储会导致服务器内存资源的耗尽。 40 41 优点:1.使用简单,不仅能传递简单数据类型,还能传递对象。 42 2.数据量大小是不限制的。 43 44 缺点:1.在Session变量存储大量的数据会消耗较多的服务器资源。 45 46 2.容易丢失。 47 48 使用方法:1.在源页面的代码中创建你需要传递的名称和值构造Session变量:Session["Name"]="Value(Or Object)"; 49 50 2.在目的页面的代码使用Session变量取出传递的值。Result = Session["Nmae"] 51 52 注意:session不用时可以销毁它,销毁的方法是:清除一个:Session.Remove("session名"); 53 54 清除所有:Session.Clear(); 55 56 例子:(1)a.aspx 57 58 private void Button1_Click(object sender, System.EventArgs e) 59 { 60 Session["name"] = Label.Text; 61 } 62 63 (2)b.aspx 64 65 private void Page_Load(object sender, EventArgs e) 66 { 67 string name; 68 name = Session["name"].ToString(); 69 } 70 71 72 73 三、Cookie 74 75 这个也是大家常使用的方法,Cookie用于在用户浏览器上存储小块的信息,保存用户的相关信息,比如用户访问某网站时用户的ID,用户的偏好等,用户下次访问就可以通过检索获得以前的信息。所以Cookie也可以在页面间传递值。Cookie通过HTTP头在浏览器和服务器之间来回传递的。Cookie只能包含字符串的值,如果想在Cookie存储整数值,那么需要先转换为字符串的形式。 76 77 与Session一样,其是什对每一个用户而言的,但是有个本质的区别,即Cookie是存放在客户端的,而session是存放在服务器端的。而且Cookie的使用要配合ASP.NET内置对象Request来使用。 78 79 优点:1.使用简单,是保持用户状态的一种非常常用的方法。比如在购物网站中用户跨多个页面表单时可以用它来保持用户状态。 80 81 缺点:1.常常被人认为用来收集用户隐私而遭到批评。 82 83 2.安全性不高,容易伪造。 84 85 86 87 使用方法:1.在源页面的代码中创建你需要传递的名称和值构造Cookie对象: 88 89 HttpCookie objCookie = new HttpCookie("myCookie","Hello,Cookie!"); 90 Response.Cookies.Add(cookie); 91 92 2.在目的页面的代码使用Cookie对象取出传递的值:Result = Request.Cookies[ "myCookie" ].Value; 93 94 例子:(1)a.aspx 95 96 private void Button1_Click(object sender, System.EventArgs e) 97 { 98 HttpCookie objCookie = new HttpCookie("myCookie","Hello,Cookie!"); 99 Response.Cookies.Add(objCookie); 100 } 101 102 (2)b.aspx 103 104 string myName1Value; 105 myName1Value = Request.Cookies[ "myCookie" ].Value; 106 107 108 109 四、Application 110 111 Application对象的作用范围是整个全局,也就是说对所有用户都有效。它在整个应用程序生命周期中都是有效的,类似于使用全局变量一样,所以可以在不同页面中对它进行存取。它和Session变量的区别在于,前者是所有的用户共用的全局变量,后者是各个用户独有的全局变量。 112 113 可能有人会问,既然所有用户都可以使用application变量,那他可以用在什么场合呢?这里举个例子:网站访问数。多个请求访问时都可以对它进行操作。 114 115 优点:1.使用简单,消耗较少的服务器资源。 116 117 2.不仅能传递简单数据,还能传递对象。 118 119 3.数据量大小是不限制的。 120 121 缺点:1.作为全局变量容易被误操作。所以单个用户使用的变量一般不能用application。 122 123 使用方法:1.在源页面的代码中创建你需要传递的名称和值构造Application变量:Application["Nmae"]="Value(Or Object)"; 124 125 2.在目的页面的代码使用Application变量取出传递的值。Result = Application["Nmae"] 126 127 注意:常用lock和unlock方法用来锁定和解锁,为了防止并发修改。 128 129 例子:(1)a.aspx 130 131 private void Button1_Click(object sender, System.EventArgs e) 132 { 133 Application["name"] = Label1.Text; 134 } 135 136 (2)b.aspx 137 复制代码 138 139 private void Page_Load(object sender, EventArgs e) 140 { 141 string name; 142 Application.Lock(); 143 name = Application["name"].ToString(); 144 Application.UnLock(); 145 } 146 147 复制代码 148 149 150 151 五、Server.Transfer 152 153 这个才可以说是面象对象开发所使用的方法,其使用Server.Transfer方法把流程从当前页面引导到另一个页面中,新的页面使用前一个页面的应答流,所以这个方法是完全面象对象的,简洁有效。 154 155 Server.Transfer是从当前的ASPX页面转到新的ASPX页面,服务器端执行新页并输出,在新页面中通过Context.Handler来获得前一个页面传递的各种数据类型的值、表单数据、QueryString.由于重定向完全在服务器端完成,所以客户端浏览器中的URL地址是不会改变的。调用Server.Transfer时,当前的ASPX页面终止执行,执行流程转入另一个ASPX页面,但新的ASPX页面仍使用前一ASPX页面创建的应答流。 156 157 ps:比较Server.Transfer和Response.Redirect的区别。 158 (1)Server.Transfer在服务器端完成,所以客户端浏览器中的URL地址是不会改变的;Response.Redirect是客户端完成,向服务器端提出新的页面处理请求,所以客户端浏览器中的URL地址是会改变的。 159 (2)Server.Transfer在服务器端完成,不需要客户端提出请求,减少了客户端对服务器端提出请求。[2] 160 (3)Server.Transfer只能够转跳到本地虚拟目录指定的页面,也就是工程项目中的页面,而Response.Redirect则十分灵活,可以跳转到任何URL地址。 161 (4)Server.Transfer可以将前一个页面的各种类型的值传到新的页面;Response.Redirect则只能借助URL中带参数或是结合上面四种办法把各种类型的值传到新的页面。 162 163 优点:1.直接在服务器端重定向,使用简单方便,减少了客户端对服务器端提出请求。 164 165 2.可以传递各种数据类型的值和控件的值。 166 167 缺点:1.客户端浏览器中的URL地址是不改变,会导致在新的页面可能出现一些意想不到的问题。比如如果源页面和目的页面不在同一个虚拟目录或其子目录下,那么使用相对路径的图片、超链接都会导致错误的指向。 168 169 使用方法:1.在源页面的代码中,使用Page类的Server.Transfer跳到另一个页面传递页面数据:Server.Transfer("b.aspx","false")。 170 171 2.在目的页面中,使用Context.Handler来接收数据:FormerPage formerPage = (FormerPage)Context.Handler; 然后用formerPage的属性和方法来获取前一个页面的值,或者直接用Context.Items["myParameter "] 172 173 例子:(1)a.aspx 174 复制代码 175 176 public string Name 177 { 178 get{ return Label1.Text;} 179 } 180 private void Button1_Click(object sender, System.EventArgs e) 181 { 182 Server.Transfer("b.aspx"); 183 } 184 185 复制代码 186 187 (2)b.aspx 188 复制代码 189 190 private void Page_Load(object sender, EventArgs e) 191 { 192 a newWeb; //实例a窗体 193 newWeb = (source)Context.Handler; 194 string name; 195 name = newWeb.Name; 196 } 197 198 复制代码 199 200 201 202 以上就是常用的几种页面间传值的方法,我一般使用session和querystring来传值,少数情况会使用到cookie。本篇文章仅仅是介绍这几种方法的使用方法,内部原理没有过多的解释,关于session的存储方式请参见:session的存储方式和配置
C#中的委托是什么?事件是不是一种委托?
委托可以把一个方法作为参数代入另一个方法。
委托可以理解为指向一个函数的引用。
是,是一种特殊的委托
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
using
System;
using
System.Collections.Generic;
using
System.Text;
namespace
Delegate
{
//定义委托,它定义了可以代表的方法的类型
public
delegate
void
GreetingDelegate(
string
name);
class
Program
{
private
static
void
EnglishGreeting(
string
name)
{
Console.WriteLine(
"Morning, "
+ name);
}
private
static
void
ChineseGreeting(
string
name)
{
Console.WriteLine(
"早上好, "
+ name);
}
//注意此方法,它接受一个GreetingDelegate类型的参数,该参数是返回值为空,参数为string类型的方法
private
static
void
GreetPeople(
string
name, GreetingDelegate MakeGreeting)
{
MakeGreeting(name);
}
static
void
Main(
string
[] args)
{
GreetPeople(
"Jimmy Zhang"
, EnglishGreeting);
GreetPeople(
"张子阳"
, ChineseGreeting);
Console.ReadKey();
}
}
}
|
1
2
3
4
5
6
7
8
|
static
void
Main(
string
[] args) {
GreetingDelegate delegate1;
delegate1 = EnglishGreeting;
// 先给委托类型的变量赋值
delegate1 += ChineseGreeting;
// 给此委托变量再绑定一个方法
// 将先后调用 EnglishGreeting 与 ChineseGreeting 方法
GreetPeople(
"Jimmy Zhang"
, delegate1);
Console.ReadKey();
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
using
System;
using
System.Collections.Generic;
using
System.Text;
namespace
Delegate {
// 热水器
public
class
Heater {
private
int
temperature;
public
delegate
void
BoilHandler(
int
param);
//声明委托
public
event
BoilHandler BoilEvent;
//声明事件
// 烧水
public
void
BoilWater() {
for
(
int
i = 0; i <= 100; i++) {
temperature = i;
if
(temperature > 95) {
if
(BoilEvent !=
null
) {
//如果有对象注册
BoilEvent(temperature);
//调用所有注册对象的方法
}
}
}
}
}
// 警报器
public
class
Alarm {
public
void
MakeAlert(
int
param) {
Console.WriteLine(
"Alarm:嘀嘀嘀,水已经 {0} 度了:"
, param);
}
}
// 显示器
public
class
Display {
public
static
void
ShowMsg(
int
param) {
//静态方法
Console.WriteLine(
"Display:水快烧开了,当前温度:{0}度。"
, param);
}
}
class
Program {
static
void
Main() {
Heater heater =
new
Heater();
Alarm alarm =
new
Alarm();
heater.BoilEvent += alarm.MakeAlert;
//注册方法
heater.BoilEvent += (
new
Alarm()).MakeAlert;
//给匿名对象注册方法
heater.BoilEvent += Display.ShowMsg;
//注册静态方法
heater.BoilWater();
//烧水,会自动调用注册过对象的方法
}
}
}
|
override与重载的区别
override 与重载的区别。重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要,实现多态.
Override 是进行基类中函数的重写,实现多态.
重载是平行的,重写是垂直的.
请编程遍历页面上所有TextBox控件并给它赋值为string.Empty?
在winform中
foreach (System.Windows.Forms.Control control in this.Controls)
{
if (control is System.Windows.Forms.TextBox)
{
System.Windows.Forms.TextBox tb = (System.Windows.Forms.TextBox)control ;
tb.Text = String.Empty ;
}
}
什么是装箱和拆箱?
从值类型接口转换到引用类型装箱。从引用类型转换到值类型拆箱。
托管代码是运行.NET 公共语言运行时CLR的代码 unsafe:非托管代码。不经过CLR运行。
非托管代码(Unmanaged Code)不由CLR公共语言运行库执行,而是由操作系统直接执行的代码。
ASP.net的身份验证方式有哪些?分别是什么原理?
Windwos(默认)用IIS控制
From(窗体)用帐户
Passport(密钥)
在C#中,string str = null 与 string str = “” 请尽量使用文字或图象说明其中的区别
string str = null 是不给他分配内存空间,而string str = "" 给它分配长度为空字符串的内存空间。
请详述在dotnet中类(class)与结构(struct)的异同?
class可以被实例化,属于引用类型,class可以实现接口和单继承其他类,还可以作为基类型,是分配在内存的堆上的
struct属于值类型,不能作为基类型,但是可以实现接口,是分配在内存的栈上的.
string strTmp = "abcdefg某某某";
int i= System.Text.Encoding.Default.GetBytes(strTmp).Length;
int j= strTmp.Length;
以上代码执行完后,i= j=
i=13,j=10
能用foreach遍历访问的对象需要实现 __IEnumerable__接口或声明__GetEnumerator_方法的类型。
能够进行foreach的类型结构,都必须实现IEnumerable接口。
IEnumerable接口,有一个GetEnumerator的方法,返回一个实现IEnumerator接口的对象。
IEnumerator接口,有Current只读属性,MoveNext方法,Reset方法。
比如类型结构 TestForeach 一个对象tf ,在进行foreach的时候,比如如下:
foreach(var a in tf){
console.writeLine(a.toString());
}
程序运行到var a in tf时,实际上,调用了TestForeach的GetEnumerator()方法,返回一个a,当运行完console.writeLine(a.toString());
后,继续运行 var a in tf,其实是调用了 上一次的a.MoveNext()放法,直到a.MoveNext=false
foreach运行完毕。
如果一个类不与具体的事物相联系,而只是表达一种抽象的概念,仅仅是作为其派生类的一个基类,这样的类就是抽象类,在抽象类中声明方法时,如果加上abstract时就是抽象方法
1.抽象类概述及声明
抽象类与非抽象类的主要区别:
·抽象类不能直接被实例化
·抽象类中可以包含抽象成员,但非抽象类中不可以
·抽象类不能被密封
举个小例子
public abstract class oneClass
{
public int i;
public void denylau()
{
}
}
2.抽象方法概述及声明
声明抽象方法时需注意:·抽象方法必须声明在抽象类中 ·声明抽象方法时,不能使用virtual、static、private修饰符。
在抽象类中抽象方法不提供实现。
如:
public abstract class myTestClass()
{
public abstract void method();
}
3.抽象类与抽象方法的使用
直接举例子,讲解例子喽!
using System;
using System.Collections.Generic;
using System.Text;
namespace _
{
public abstract class myClass
{
private string id = "";
private string name = "";
/// <summary>
/// 编号属性及实现
/// </summary>
public string ID
{
get
{
return id;
}
set
{
id = value;
}
}
/// <summary>
/// 姓名属性及实现
/// </summary>
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
/// <summary>
/// 抽象方法,用来输出信息
/// </summary>
public abstract void ShowInfo();
}
public class DriveClass:myClass //继承抽象类
{
/// <summary>
/// 重写抽象类中输出信息的方法
/// </summary>
public override void ShowInfo()
{
Console.WriteLine(ID + " " + Name);
}
}
class Program
{
static void Main(string[] args)
{
DriveClass driveclass = new DriveClass(); //实例化派生类
myClass myclass = driveclass; //使用派生类对象实例化抽象类
myclass.ID = "BH0001"; //使用抽象类对象访问抽象类中的编号属性
myclass.Name = "TM"; //使用抽象类对象访问抽象类中的姓名属性
myclass.ShowInfo(); //使用抽象类对象调用抽象类中的的抽象方法
}
}
}
上例中通过派生类的对象driveclass来实例化抽象类,然后使用抽象类访问抽象类中的属性及方法。
上面这个小例子,细心的朋友会发现,怎么抽象类和我们上一篇文章讲的接口差不多吗?那么究竟抽象类和接口存在哪些区别呢?
Ok,下面就介绍下抽象类和接口的区别喽:
·它们的派生类只能继承一个基类,即只能继承一个抽象类,但是可以继承多个接口。
·抽象类中可以定义成员的实现,但接口中不可以。
·抽象类中包含字段、构造函数、析构函数、静态成员或常量等,接口中不可以。
·抽象类中的成员可以私有的(只要不是抽象的)、受保护的、内部的或受保护的内部成员,但接口中的成员必须是公共的。
PS:抽象类和接口这两种类型用于完全不同的目的。抽象类主要用作对象系列的基类,共享某些主要特性,例如共同的目的和结构。接口则主要用于类,这些类在基础水平上有所不同,但仍然可以完成某些相同的任务。
http://home.cnblogs.com/u/ArmyShen/ 可以去学习 这个是ArmyShen的博客园
using System.Threading.Tasks;
namespace ConsoleApplication5
{
public abstract class a
{
public int i = 0;
public string abcdefg()
{
return "HELLO,你好!";
}
public abstract void abcd();
public virtual string efg()
{
return i.ToString();
}
public virtual void eat()
{
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication5
{
public class b:a
{
public override void abcd()
{
Console.WriteLine("abcd");
Console.ReadKey();
}
public override void eat()
{
Console.WriteLine("try");
}
public override string efg()
{
return "虛方法重寫需要自己手動添加!";
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
b ab = new b();
Console.WriteLine(ab.abcdefg());
Console.WriteLine(ab.efg());
ab.eat();
ab.abcd();
}
}
}
运行效果:
接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?
接口可以继承接口
抽象类可以实现(implements)接口
抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数 (抽象类与一般类唯一的不同,就是它可以含有抽象成员,它本身不可实例化。除此以外,没有其他区别)
是否可以继承String类?
String类是密封类故不可以继承
try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
会执行,在return前执行(验证过的)
数组有没有length()这个方法? String有没有length()这个方法?
数组没有length()这个方法,有length的属性。String没有length()这个方法,有length属性
如何处理几十万条并发数据?
用存储过程或事务
Session有什么重大BUG,微软提出了什么方法加以解决?
是iis中由于有进程回收机制,系统繁忙的话Session会丢失,可以用Sate server或SQL Server数据库的方式存储Session不过这种方式比较慢,而且无法捕获Session的END事件
产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
int[] str = new int[100];
ArrayList al = new ArrayList();//寫法一
List<int> ls = new List<int>();//寫法二
while (al.Count < 100)
{
Random rd = new Random();
int i = rd.Next(0, 101);
if (!al.Contains(i))
{
al.Add(i);
}
}
while (ls.Count < 100)
{
Random rd = new Random();
int i= rd.Next(0, 101);
if (ls.Contains(i))
{
ls.Add(i);
}
}
for (int j = 0; j < 100; j++)
{
str[j]=(int)al[j];
}
for (int j = 0; j < 100; j++)
{
str[j] = (int)ls[j];
}
}
}
}
软件开发过程一般有几个阶段?每个阶段的作用?
可行性分析(风险控制),需求分析,架构设计,代码编写,测试,部署,维护
需要实现对一个字符串的处理,首先将该字符串首尾的空格去掉,如果字符串中间还有连续空格的话,仅保留一个空格,即允许字符串中间有多个空格,但连续的空格数不可超过一个
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
string str = " abc def ";
Console.WriteLine(str.Trim());//abc def
Console.WriteLine(str.Trim().Length);//9
Console.WriteLine(str.Length);//11
Console.WriteLine(Regex.Replace(str.Trim()," +"," "));//在正則中*表示0個或者多個 +表示一個或者多個
Console.WriteLine(Regex.Replace(str.Trim()," +"," ").Length);//7
Console.ReadKey();
}
}
}
XML可扩展性语言
const不能用static修饰。
在Asp.net中所有的自定义用户控件都必须继承自__Control_
62-63=1 等式不成立,请移动一个数字(不可以移动减号和等于号),使得等式成立,如何移动
62移动成2的6次方
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
int i = 5;
int j = 5;
string x = "abc";
string y = "abc";
if (object.Equals(i, j))
{
Console.WriteLine("1true");
}
if (object.ReferenceEquals(i,j))
{
Console.WriteLine("2true");
}
if (object.Equals(x, y))
{
Console.WriteLine("3true");
}
if (object.ReferenceEquals(x,y))
{
Console.WriteLine("4true");
}
Console.ReadKey();
}
}
}
运行结果1 3 4
写一个HTML页面,实现以下功能,左键点击页面时显示“您好”,右键点击时显示“禁止右键”。并在2分钟后自动关闭页面
<script language=javascript>
setTimeout('window.close();',3000);
function show()
{
if (window.event.button == 1)
{
alert("左");
}
else if (window.event.button == 2)
{
alert("右");
}
}
</script>
<%# %> 和 <% %> 有什么区别?
<%# %>表示绑定的数据源
<% %>是服务器端代码块
ref和out的使用与区别
out的使用
class Program
{
static void Main(string[] args)
{
string tmp; //先声明,但不初始化
User _user=new User();
_user.Name(out tmp); //调用Name方法
Console.WriteLine("{0}",tmp); //这时tmp的值为“在这里面赋值了”
Console.ReadKey(true);
}
}
class User
{
public void Name(out string tmps)
{
tmps="在这里面赋值了";
}
}
结果:
在这里面赋值了
—————————————————————————————————————————————————
ref的使用
—————————————————————————————————————————————————
class Program
{
static void Main(string[] args)
{
string tmp="传值之前"; //声明并初始化 这时如果输出tmp值为"传值之前"
User _user=new User();
_user.Name(ref tmp);
Console.WriteLine("{0}",tmp);
Console.ReadKey(true);
}
}
class User
{
public void Name(ref string tmps)
{
tmps="传值之后";
}
}
结果:
传值之后
—————————————————————————————————————————————————
区别:
ref和out的区别在C# 中,既可以通过值也可以通过引用传递参数。通过引用传递参数允许函数成员更改参数的值,并保持该更改。若要通过引用传递参数, 可使用ref或out关键字。ref和out这两个关键字都能够提供相似的功效,其作用也很像C中的指针变量。它们的区别是:
1、使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化。
2、使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。
3、out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。
out
方法参数上的 out 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。
当希望方法返回多个值时,声明 out 方法非常有用。使用 out 参数的方法仍然可以返回一个值。一个方法可以有一个以上的 out 参数。
若要使用 out 参数,必须将参数作为 out 参数显式传递到方法。out 参数的值不会传递到 out 参数。
不必初始化作为 out 参数传递的变量。然而,必须在方法返回之前为 out 参数赋值。
属性不是变量,不能作为 out 参数传递。
ref是 有进有出,而out是 只出不进。
C#索引器详解
索引器允许类和结构的实例按照与数组相同的方式进行索引,索引器类似与属性,不同之处在于他们的访问器采用参数。被称为有参属性。
简单的索引器实例:
class Program
{
static void Main(string[] args)
{
IndexClass a = new IndexClass();
a[0] = "张三";
a[1] = "李四";
a[2] = "王五";
Console.WriteLine("a[0]=" + a[0]);
Console.WriteLine("a[1]=" + a[1]);
Console.WriteLine("a[2]=" + a[2]);
Console.ReadKey();
}
}
class IndexClass
{
private string[] name = new string[10];
public string this[int index]
{
get { return name[index]; }
set { this.name[index] = value; }
}
}
索引器与数组的比较:
索引器的索引值不受类型限制。用来访问数组的索引值一定是整数,而索引器可以是其他类型的索引值。
索引器允许重载,一个类可以有多个索引器。
索引器不是一个变量没有直接对应的数据存储地方。索引器有get和set访问器。
索引器允许类和结构的实例按照与数组相同的方式进行索引,索引器类似与属性,不同之处在于他们的访问器采用参数。被称为有参属性。
简单的索引器实例:
索引器与属性的比较:
标示方式:属性以名称来标识,索引器以函数签名来标识。
索引器可以被重载。属性则不可以被重载。
属性可以为静态的,索引器属于实例成员,不能被声明为static
多参数索引器实例:
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace Study
{
class Program
{
static void Main(string[] args)
{
ScoreIndex s = new ScoreIndex();
s["张三", 1] = 90;
s["张三", 2] = 100;
s["张三", 3] = 80;
s["李四", 1] = 60;
s["李四", 2] = 70;
s["李四", 3] = 50;
Console.WriteLine("张三课程编号为1的成绩为:" + s["张三",1]);
Console.WriteLine("张三的所有成绩为:");
ArrayList temp;
temp = s["张三"];
foreach (IndexClass b in temp)
{
Console.WriteLine("姓名:" + b.Name + "课程编号:" + b.CourseID + "分数:" + b.Score);
}
Console.ReadKey();
}
}
class IndexClass
{
private string _name;
private int _courseid;
private int _score;
public IndexClass(string _name, int _courseid, int _score)
{
this._name = _name;
this._courseid = _courseid;
this._score = _score;
}
public string Name
{
get { return _name; }
set { this._name = value; }
}
public int CourseID
{
get { return _courseid; }
set { this._courseid = value; }
}
public int Score
{
get { return _score; }
set { this._score = value; }
}
}
class ScoreIndex
{
private ArrayList arr;
public ScoreIndex()
{
arr = new ArrayList();
}
public int this[string _name, int _courseid]
{
get
{
foreach (IndexClass a in arr)
{
if (a.Name == _name && a.CourseID == _courseid)
{
return a.Score;
}
}
return -1;
}
set
{
arr.Add(new IndexClass(_name, _courseid, value)); //arr["张三",1]=90
}
}
//重载索引器
public ArrayList this[string _name]
{
get
{
ArrayList temp = new ArrayList();
foreach (IndexClass b in arr)
{
if (b.Name == _name)
{
temp.Add(b);
}
}
return temp;
}
}
}
}
备注:
所有索引器都使用this关键词来取代方法名。Class或Struct只允许定义一个索引器,而且总是命名为this。
索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器类似于属性,不同之处在于它们的访问器采用参数。
get 访问器返回值。set 访问器分配值。
this 关键字用于定义索引器。
value 关键字用于定义由 set 索引器分配的值。
索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制。
索引器可被重载。
索引器可以有多个形参,例如当访问二维数组时。
索引器可以使用百数值下标,而数组只能使用整数下标:如下列定义一个String下标的索引器
public int this [string name] {...}
属性和索引器
属性和索引器之间有好些差别:
类的每一个属性都必须拥有唯一的名称,而类里定义的每一个索引器都必须拥有唯一的签名(signature)或者参数列表(这样就可以实现索引器重载)。
属性可以是static(静态的)而索引器则必须是实例成员。
写的例子 泛型类
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ConsoleApplication5
{
class SampleCollection<T>
{
private T[] arr = new T[100];
public T this[int i]
{
get
{
return arr[i];
}
set
{
arr[i] = value;
}
}
}
class SampleCollectionTwo
{
List<string> lso = new List<string>();
private string[] arr = new string[100];
public string this[int i]
{
get
{
return arr[i];
}
set
{
arr[i] = value;
}
}
}
class SampleCollectionThree<T>
{
private T[] arr = new T[100];
public T this[int i]
{
get
{
return arr[i];
}
set
{
arr[i] = value;
}
}
}
class Program
{
static void Main(string[] args)
{
SampleCollection<string> stringCollection = new SampleCollection<string>();
stringCollection[0] = "Hello, World";
System.Console.WriteLine(stringCollection[0]);
Console.WriteLine(" ");
SampleCollectionTwo sct = new SampleCollectionTwo();
sct[0] = "Hello Ajax";
System.Console.WriteLine(sct[0]);
Console.ReadKey();
}
}
}
转换数组转换为arraylist
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
//
string[] str = new string[] {"111","222222" };
//把數組轉化成arraylist例子一
ArrayList al = new ArrayList(str);
Console.WriteLine(al.Count);
//例子二
ArrayList alt = new ArrayList();
alt.AddRange(str);
Console.WriteLine(alt.Count);
Console.ReadKey();
//輸出2
//輸出2
}
}
}
描述线程与进程的区别?(*)
1.线程(Thread)与进程(Process)二者都定义了某种边界,不同的是进程定义的是应用程序与应用程序之间的边界,不同的进程之间不能共享代码和数据空间,而线程定义的是代码执行堆栈和执行上下文的边界。
2.一个进程可以包括若干个线程, 同时创建多个线程来完成某项任务,便是多线程。而同一进程中的不同线程共享代码和数据空间。用一个比喻来说,如果一个家庭代表一个进程,在家庭内部,各个 成员就是线程,家庭中的每个成员都有义务对家庭的财富进行积累,同时也有权利对家庭财富进行消费,当面对一个任务的时候,家庭也可以派出几个成员来协同完 成,而家庭之外的人则没有办法直接消费不属于自己家庭的财产。
发送邮件
发送邮件重要是两个类MailMessage和SmtpClient两个类
Assembly.Load("foo.dll"); 这句话是否正确?(*)
错误,正确的应该是Assembly.Load("foo"); 或者Assembly.LoadFrom("foo.dll");