.net 开发 配置文件的灵活使用
配置文件的编写代码:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="spring" type="spring_test.springClass,spring_test"/>
<section name="hellowChild_1" type="spring_test.IFactory.HelloClassChild_1,spring_test"/>
<section name="hellowChild_2" type="spring_test.IFactory.HelloClassChild_2,spring_test"/>
</configSections>
<spring Name="spring_class:this is a test" ></spring>
<hellowChild_1 Name="HelloClassChild_1 : this is a HelloClassChild_1 class" NameSpace="spring_test.IFactory"></hellowChild_1>
<hellowChild_2 Name="HelloClassChild_2 : this is a HelloClassChild_2 class" NameSpace="spring_test.IFactory"></hellowChild_2>
</configuration>
类的编写代码:
public HelloClassChild_2()
{
}
public HelloClassChild_2(string Name, string NameSpace)
{
this.Name = Name;
this.NameSpace = NameSpace;
}
[System.Configuration.ConfigurationProperty("Name", IsRequired = true)]
public string Name
{
get
{
return this["Name"].ToString();
}
set
{
this["Name"] = value;
}
}
[System.Configuration.ConfigurationProperty("NameSpace", IsRequired = true)]
public string NameSpace
{
get
{
return this["NameSpace"].ToString();
}
set
{
this["NameSpace"] = value;
}
}
public string GetWriteLine(string Name,string NameSpace)
{
return string.Format("程序加载的类为:{0} \n所属的命名空间为:{1}", Name, NameSpace);
}
public void WriteLineString(string Name, string NameSpace)
{
Console.WriteLine(GetWriteLine(Name,NameSpace));
}
类的实例化代码:
static void Main(string[] args)
{
var dataClass1 = System.Configuration.ConfigurationManager.GetSection("spring");
springClass spring = dataClass1 as spring_test.springClass;
Console.WriteLine(spring.Name);
var dataClass2 = System.Configuration.ConfigurationManager.GetSection("hellowChild_1");
IFactory.IHello iFactory_1 = dataClass2 as IFactory.IHello;
iFactory_1.WriteLineString(iFactory_1.Name, iFactory_1.NameSpace);
var dataClass3 = System.Configuration.ConfigurationManager.GetSection("hellowChild_1");
IFactory.IHello iFactory_2 = dataClass2 as IFactory.IHello;
iFactory_2.WriteLineString(iFactory_2.Name, iFactory_2.NameSpace);
Console.Read();
}
全面解析C#中参数传递
一、引言
对于一些初学者(包括工作几年的人在内)来说,有时候对于方法之间的参数传递的问题感觉比较困惑的,因为之前在面试的过程也经常遇到参数传递的基础面试题,这样的面试题主要考察的开发人员基础是否扎实,对于C#中值类型和引用类型有没有深入的一个理解——这个说的理解并不是简单的对它们简单一个定义描述,而在于它们在内存中分布。所以本文章将带领大家深入剖析下C#中参数传递的问题,并分享我自己的一个理解,只有你深入理解了才能在不运行程序的情况就可以分析出参数传递的结果的。
二、按值传递
对于C#中的参数传递,根据参数的类型可以分为四类:
- 值类型参数的按值传递
- 引用类型参数的按值传递
- 值类型参数的按引用传递
- 引用类型参数的按引用传递
然而在默认情况下,CLR方法中参数的传递都是按值传递的。为了帮助大家全面理解参数的传递,下面就这四种情况一一进行分析。
2.1 值类型参数的按值传递
对于参数又分为:形参和实参,形参指的是被调用方法中的参数,实参指的是调用方法的参数,下面结合代码帮助大家理解形参和实参的概念:
class Program { static void Main(string[] args) { int addNum = 1; // addNum 就是实参, Add(addNum); } // addnum就是形参,也就是被调用方法中的参数 private static void Add(int addnum) { addnum = addnum + 1; Console.WriteLine(addnum); } }
对于值类型的按值传递,传递的是该值类型实例的一个拷贝,也就是形参此时接受到的是实参的一个副本,被调用方法操作是实参的一个拷贝,所以此时并不影响原来调用方法中的参数值,为了证明这点,看看下面的代码和运行结果就明白了:
class Program { static void Main(string[] args) { // 1. 值类型按值传递情况 Console.WriteLine("按值传递的情况"); int addNum = 1; Add(addNum); Console.WriteLine(addNum); Console.Read(); } // 1. 值类型按值传递情况 private static void Add(int addnum) { addnum = addnum + 1; Console.WriteLine(addnum); }
运行结果为:
从结果中可以看出addNum调用方法之后它的值并没有改变,Add 方法的调用只是改变了addNum的副本addnum的值,所以addnum的值修改为2了。然而我们的分析到这里并没有结束,为了让大家深入理解传递传递,我们有必要知道为什么值类型参数的按值传递不会修改实参的值,相信下面这张图可以解释你所有的疑惑:
2.2 引用类型参数的按值传递
当传递的参数是引用类型的时候,传递和操作的是指向对象的引用(看到这里,有些朋友会觉得此时不是传递引用吗?怎么还是按值传递了?对于这个疑惑,此时确实是按值传递,此时传递的对象的地址,传递地址本身也是传递这个地址的值,所以此时仍然是按值传递的),此时方法的操作就会改变原来的对象。对于这点可能看文字描述会比较难理解下面结合代码和分析图来帮助大家理解下:
class Program { static void Main(string[] args) { // 2. 引用类型按值传递情况 RefClass refClass = new RefClass(); AddRef(refClass); Console.WriteLine(refClass.addnum); } // 2. 引用类型按值传递情况 private static void AddRef(RefClass addnumRef) { addnumRef.addnum += 1; Console.WriteLine(addnumRef.addnum); } } class RefClass { public int addnum=1; }
运行结果为:
为什么此时传递引用就会修改原来实参中的值呢?对于这点我们还是参数在内存中分布图来解释下:
2.3 .String引用类型的按值传递的特殊情况
对于String类型同样是引用类型,然而对于string类型的按值传递时,此时引用类型的按值传递却不会修改实参的值,可能很多朋友对于这点很困惑,下面具体看看下面的代码:
class Program { static void Main(string[] args) { // 3. String引用类型的按值传递的特殊情况 string str = "old string"; ChangeStr(str); Console.WriteLine(str); } // 3. String引用类型的按值传递的特殊情况 private static void ChangeStr(string oldStr) { oldStr = "New string"; Console.WriteLine(oldStr); } }
运行结果为:
对于为什么原来的值没有被改变主要是因为string的“不变性”,所以在被调用方法中执行 oldStr="New string"代码时,此时并不会直接修改oldStr中的"old string"值为"New string",因为string类型是不变的,不可修改的,此时内存会重新分配一块内存,然后把这块内存中的值修改为 “New string”,然后把内存中地址赋值给oldStr变量,所以此时str仍然指向 "old string"字符,而oldStr却改变了指向,它最后指向了 "New string"字符串。所以运行结果才会像上面这样,下面内存分布图可以帮助你更形象地理解文字表述:
三、按引用传递
不管是值类型还是引用类型,我们都可以使用ref 或out关键字来实现参数的按引用传递,然而按引用进行传递的时候,需要注意下面两点:
方法的定义和方法调用都必须同时显式使用ref或out,否则会出现编译错误
CLR允许通过out 或ref参数来实现方法重载。如:
#region CLR 允许out或ref参数来实现方法重载 private static void Add(string str) { Console.WriteLine(str); } // 编译器会认为下面的方法是另一个方法,从而实现方法重载 private static void Add(ref string str) { Console.WriteLine(str); } #endregion
按引用传递可以解决由于值传递时改变引用副本而不影响引用本身的问题,此时传递的是引用的引用(也就是地址的地址),而不是引用的拷贝(副本)。下面就具体看看按引用传递的代码:
class Program { static void Main(string[] args) { #region 按引用传递 Console.WriteLine("按引用传递的情况"); int num = 1; string refStr = "Old string"; ChangeByValue(ref num); Console.WriteLine(num); changeByRef(ref refStr); Console.WriteLine(refStr); #endregion Console.Read(); } #region 按引用传递 // 1. 值类型的按引用传递情况 private static void ChangeByValue(ref int numValue) { numValue = 10; Console.WriteLine(numValue); } // 2. 引用类型的按引用传递情况 private static void changeByRef(ref string numRef) { numRef = "new string"; Console.WriteLine(numRef); } #endregion }
运行结果为:
从运行结果可以看出,此时引用本身的值也被改变了,通过下面一张图来帮忙大家理解下按引用传递的方式:
四、总结
到这里参数的传递所有内容就介绍完了。总之,对于按值传递,不管是值类型还是引用类型的按值传递,都是传递实参的一个拷贝,只是值类型时,此时传递的是实参实例的一个拷贝(也就是值类型值的一个拷贝),而引用类型时,此时传递的实参引用的副本。对于按引用传递,传递的都是参数地址,也就是实例的指针。
所有源码下载:参数传递
如果,您认为阅读这篇博客对你有帮助,点击一下左下角的[推荐]
如果,你想了解我的动态,点击一下左下角的[关注我]
因为,你们的支持正是我学习的动力
如需转载,请注明出处
如果对文章有任何问题,都可以再评论中留言,我会尽可能的答复您,谢谢你的阅读
C#使用技巧之调用JS脚本方法一
有时候我们需要在C#中直接调用js方法,这是完全没问题的。当然,我们也可以把js代码转化为C#,然后在C#中执行,但是这个就得花时间了~~下面我给大家介绍下一种直接在C#中调用JS文件的方法。
0、贴个效果图
1、创建个Winform项目。
2、在From1上增加一个文本框一个按钮。
3、在解决方案中创建一个test.js文件。
test.js代码如下:
function sayHello(str) { return "Hello," + str; }
4、进入Form1.cs编码后台代码。
Form1.cs代码如下:
1 private void button1_Click(object sender, EventArgs e) 2 { 3 string path = AppDomain.CurrentDomain.BaseDirectory + "test.js"; 4 string str2 = File.ReadAllText(path); 5 6 string fun = string.Format(@"sayHello('{0}')" ,this.textBox1.Text.Trim()); 7 string result = ExecuteScript(fun, str2); 8 9 MessageBox.Show(result); 10 } 11 12 /// <summary> 13 /// 执行JS 14 /// </summary> 15 /// <param name="sExpression">参数体</param> 16 /// <param name="sCode">JavaScript代码的字符串</param> 17 /// <returns></returns> 18 private string ExecuteScript(string sExpression, string sCode) 19 { 20 MSScriptControl.ScriptControl scriptControl = new MSScriptControl.ScriptControl(); 21 scriptControl.UseSafeSubset = true; 22 scriptControl.Language = "JScript"; 23 scriptControl.AddCode(sCode); 24 try 25 { 26 string str = scriptControl.Eval(sExpression).ToString(); 27 return str; 28 } 29 catch (Exception ex) 30 { 31 string str = ex.Message; 32 } 33 return null; 34 }
5、测试
效果图如第0步。
注:在后台代码中如果找不到命名空间:MSScriptControl.ScriptControl,请参照下图增加引用。