switch (one)
{
case 1:
string myName = "张三";
break;
case 2:
myName = "张三"; //正确
break;
case 3:
string myName = "张三"; //报错
break;
}
可以理解 一个 switch 为一个作用域 而并非 一个 case 一个作用域。
那么为什么要这样呢?
这样的优点是什么?
{
case 1:
string myName = "张三";
break;
case 2:
myName = "张三"; //正确
break;
case 3:
string myName = "张三"; //报错
break;
}
可以理解 一个 switch 为一个作用域 而并非 一个 case 一个作用域。
那么为什么要这样呢?
这样的优点是什么?
发现在 case 2 里的myName 仅声明,但就算再 case1 赋值了,在 case2里依旧是未赋值。
是啊。只是搞不懂为什么 CASE1 里的东西, CASE2可以用?那反之,CASE1000声明的变量,CASE1也可以用咯?
鉴于此,我个人认为,这种域的级别是在switch级,而不是case级。
-----------
纯属个人理解,具体为什么我也不怎么明白。
我最常用的是VB.NET,看一段VB.NET代码
Select Case Now.Second Mod 10
Case 1
Dim a As Integer
a = 1
Response.Write(a)
Case 2
Dim a As Integer
a = 2
Response.Write(a)
Case 3
Dim a As Integer
a = 3
Response.Write(a)
Case 4
Dim a As Integer
a = 4
Response.Write(a)
Case Else
Dim a As Integer
a = 5
Response.Write(a)
End Select
以上语句没有问题,由此看来 Select 的作用域是 case 级的
不知道为什么C#中就变成了 Switch 级别的了
表达式的值一量明确不需要 逐一去 case中查找而是一步到位如果有匹配那么直接执行它,如果没 那么直接出去, 并非 逐一去比对,从效率上看 有点象 if()else if()...
在 C# 中,case n: 可以理解为语句标号,可以作为 goto 语句的对象,比如: switch (one)
{
case 1:
string myName = "张三";
break;
case 2:
myName = "李四"; // 正确
goto case 1; // 这是合法的 goto 语句
}
如果变量 one 的值是 2 的话,就不会转到 case 1: 去执行,也就是说 myName = "张三"; 不会执行,但变量声明在 switch 的作用域内该声明之后的地方有效。
而变量赋值则是运行期间的事,与程序的控制流程有关,与 case n: 相关。
感谢空军的解释。不过仍然有些不理解这样做的优点是在哪里?为什么要去声明那些几乎“没用”的东西?
还有与VB.NET SELECT 语句竟然不同?这又作何解释呢?
for (int i = 0; i < 3; i++)
{
// 变量 i 的作用域仅限于此,出了该 for 循环 i 就无定义了。
}
{
for(int i = 0;i<10;i++)
{
//.... 很明显 这里i再出了for就已经无效了 那为什么 在外面再次声明i 会报错?
}
int i = 3;//这么定义C#编译不过去 为什么?好象不符合思维逻辑 是吧?
}如果你要是在C语言下呢? 可以试下能不能通过
{
for(int i = 0;i<10;i++)
{
//.... 很明显 这里i再出了for就已经无效了 那为什么 在外面再次声明i 会报错?
}
int i = 3;//这么定义C#编译不过去 为什么? 见下:
}
error CS0136: 不能在此范围内声明名为“i”的局部变量,因为这样会使“i”具有不同的含义,而它已在“子级”范围中表示其他内容了
倒是从未碰过这个问题。虽然看了VS的提示错误,但仍然十分不解,这样做有什么好处?纵然这样的问题很钻牛角尖,
但是在不明白,i在for的 } 不是已经被终结生命了?似乎和空军的话有些矛盾?
第二、声明变量要放在switch外面,case:……break;之间声明的变量并不必然可以在另一个case:……中有效
如果给case条件下付了值,不加入break,编译都通不过的;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ArrayList al = new ArrayList();
al.Add("a:动物");//单个添加
foreach (string number in new string[2] { "b:植物","c:细菌" })
{
al.Add(number);//集体添加方法一
}
Console.WriteLine("请选择a,b,c:");
foreach (string i in al)
{
Console.Write(i);//遍历方法一
}
Console.Write("\n");
char ch = Console.ReadKey().KeyChar;
Console.Clear();
switch (ch)
{
case 'a':
ArrayList a2 = new ArrayList();
foreach (string animal in new string[2] { "1、海洋动物", "2、陆地动物" })
{
a2.Add(animal);//集体添加方法二
}
Console.WriteLine("a:动物");
foreach (string i in a2)
{
Console.Write(i);//遍历方法二
}
//-------------------------------------
Console.Write("\n");
int j = Console.ReadKey().KeyChar;
Console.Clear();
Console.WriteLine("请选择1,2,3:");
switch (j)
{
case 1:
ArrayList b1 = new ArrayList();
foreach (string animal2 in new string[2] { "1、鲸鱼", "2、鳄鱼" })
{
b1.Add(animal2);//集体添加方法三
}
Console.WriteLine("1、海洋动物");
foreach (string air in b1)
{
Console.Write(air);//遍历方法三
}
break;
case 2:
ArrayList b2 = new ArrayList();
foreach (string animal3 in new string[2] { "1、大象", "2、老虎" })
{
b2.Add(animal3);//集体添加方法二
}
Console.WriteLine("2、陆地动物");
foreach (string load in b2)//不要强制转换
{
Console.Write(load);//遍历方法二
}
break;
}
//----------------------------
break;
case 'b':
ArrayList a3 = new ArrayList();
foreach (string street in new string[2] { "1、孢子植物", "2、无孢子植物" })
{
a3.Add(street);//集体添加方法二
}
Console.WriteLine("b:植物");
foreach (string i in a3)//不要强制转换
{
Console.Write(i);//遍历方法二
}
//-------------------------------------
Console.Write("\n");
int x= Console.ReadKey().KeyChar;
Console.Clear();
Console.WriteLine("请选择1,2,3:");
switch (x)
{
case 1:
ArrayList c1 = new ArrayList();
foreach (string street2 in new string[2] { "1、松树", "2、蒲公英" })
{
c1.Add(street2);//集体添加方法三
}
Console.WriteLine("1、孢子植物");
foreach (string baozi in c1)
{
Console.Write(baozi);//遍历方法三
}
break;
case 2:
ArrayList c2 = new ArrayList();
foreach (string street3 in new string[2] { "1、杨树", "2、榕树" })
{
c2.Add(street3);//集体添加方法二
}
Console.WriteLine("2、无孢子植物");
foreach (string street3 in c2)//不要强制转换
{
Console.Write(street3);//遍历方法二
}
break; }
//----------------------------
break;
case 'c':
ArrayList a4 = new ArrayList();
foreach (string xijun in new string[2] { "1、原生动物", "2、软体动物" })
{
a4.Add(xijun);//集体添加方法一
}
Console.WriteLine("c:细菌");
foreach (string i in a4)//不要强制转换
{
Console.Write(i);//遍历方法一
}
//-------------------------------------
Console.Write("\n");
int y = Console.ReadKey().KeyChar;
Console.Clear();
Console.WriteLine("请选择1,2,3:");
switch (y)
{
case 1:
ArrayList d1 = new ArrayList();
foreach (string xijun2 in new string[2] { "1、真菌", "2、假菌" })
{
d1.Add(xijun2);//集体添加方法三
}
Console.WriteLine("1、孢子植物");
foreach (string xijun3 in d1)
{
Console.Write(xijun3);//遍历方法三
}
break;
case 2:
ArrayList c2 = new ArrayList();
foreach (string street3 in new string[2] { "1、杨树", "2、榕树" })
{
c2.Add(street3);//集体添加方法二
}
Console.WriteLine("2、无孢子植物");
foreach (string street3 in c2)//不要强制转换
{
Console.Write(street3);//遍历方法二
}
break; }
//----------------------------
break;
} Console.Read();
}
}
}
switch作用范围我也想问,我这个就是很典型的switch不能实现的例子,整串代码无误.
public void test()
{
for (int i = 0; i < 10; i++)
{
// .... 很明显 这里i再出了for就已经无效了 那为什么 在外面再次声明i 会报错?
}
int i = 3; // 这里的 i 和前面那个 i 在不同的级别里,
// C#编译器不允许这种情况,是为了防止下述无意中的错误:
}public void test()
{
int i = 3;
for (int i = 0; i < 10; i++)
{
// 这里的 i 无意中屏蔽了上一级别的 i,会造成微妙的错误,
// 所以 C# 编译器不允许在不同的级别上定义相同的变量。
}
}public void test()
{
for (int i = 0; i < 10; i++)
{
// .... 很明显 这里i再出了for就已经无效了 那为什么 在外面再次声明i 会报错?
}
{ int i = 3; } // 加上 {},这样就没问题了。
}