Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么这种打开类型的案例会令人困惑?_C#_Switch Statement - Fatal编程技术网

C# 为什么这种打开类型的案例会令人困惑?

C# 为什么这种打开类型的案例会令人困惑?,c#,switch-statement,C#,Switch Statement,我一直在寻找一种方法来重构和简化一个函数,在这个函数中,我必须根据输入类类型进行数据排序,但却被困在开关(input.GetType()): 快速搜索让我找到了一个链接 我阅读了文档,但没有理由认为情况令人困惑 从文章中: 不幸的是,就像许多“简单的” 语言功能,类型开关不可用 就像它第一次出现一样简单。这个 当你看到一个更大的问题时,麻烦就开始了 意义重大,但同样重要, 例如: 这有什么不简单的?调用typeof(e)无法返回-这是一个ID和C。它必须返回类型而不是接口和类类型的数组-类型[]

我一直在寻找一种方法来重构和简化一个函数,在这个函数中,我必须根据输入类类型进行数据排序,但却被困在
开关(input.GetType()):

快速搜索让我找到了一个链接

我阅读了文档,但没有理由认为情况令人困惑

从文章中:

不幸的是,就像许多“简单的” 语言功能,类型开关不可用 就像它第一次出现一样简单。这个 当你看到一个更大的问题时,麻烦就开始了 意义重大,但同样重要, 例如:

这有什么不简单的?调用
typeof(e)
无法返回-这是一个
I
D
C
。它必须返回
类型
而不是接口和类类型的数组-
类型[]
。因此
类D
的类型是
D
。而
D
对应于
默认值:
分支


I遗漏了什么?

您似乎不希望开关在子类上匹配。但这将打破利斯科夫替代原则。(如果你传入一个C对象,代码就可以工作,但不能与D一起工作,即使D是C的一个子类)。

我认为Peter Hallam的博客文章中的一个非常有效的论点是,如果你对事物进行重新排序,你不希望
switch
语句会有所不同,因此只有在只有一个分支可以同时有效的情况下,它才真正有用,而对于
类型
来说,一个类总是继承链上的多个不同类型


没有人会阻止您使用if…else链来执行此操作,您确实希望它按照您放置东西的顺序进行评估。

但它不会有所不同,因为在这两种情况下,只会考虑默认分支。类型是D,它不是一组类型,所以分支I或C无法执行。您必须将类强制转换为C才能获得分支C。种类-((ClassC)输入)。GetType()。不,D也是C和I(和对象),任何类都是继承链上其祖先的有效类型。当然,您可以构造语句,使其从更高级别/更具体的类定义转换为更通用的类定义,但关键是,在使用
开关时,这种排序不应该是这样做的要求,但您可以使用if…else进行排序,这样可以按顺序计算条件,直到找到第一个匹配项。但它的类型是D,除非它被强制转换到不同的对象。我们不是在上课。虽然它们可以是有效的类型,但您不会期望字符串;a、 GetType();返回对象。如果您已经执行了强制转换,您会这样做。好的
typeof
Object.GetType()
返回一个
System.Type
,它可能会在不太严格的基础上进行比较,例如即使对于继承的类型也返回true。您可以尝试比较
Type.FullName
,例如,如果您希望它更严格。是的,因为我们不是在类上分支,所以我们是在typeof(class)上分支,它是一个单一的、定义良好的值,就像普通的int一样。如果它被定义为(int32)32或(int64),您不会在值32上分支到不同的分支32.该原则是一本很好的读物。我猜在某些情况下,有人可以通过将D类更改为它的子类来破坏应用程序
class C {}
interface I {}
class D : C, I {}

switch typeof(e) {
case C: ... break;
case I: ... break;
default: ... break;
}