在C#中使用“ is”关键字的“好”用例是什么?

时间:2019-04-05 23:27:37

标签: c# keyword language-features software-quality

我们今天在工作中讨论了用例,其中您有类似以下代码的内容:

using System;

namespace test
{
    class Program
    {
        public class A
        {
            public void Foo()
            {
                Console.WriteLine("This is A.");
            }
        }

        public class B
        {
            public void Foo()
            {
                Console.WriteLine("This is B");
            }
        }

        public static void Test(object obj)
        {
            if (obj is A a)
            {
                a.Foo();
            }
            else if (obj is B b)
            {
                b.Foo();
            }
        }

        static void Main(string[] args)
        {
            Test(new A());
        }
    }
}

然后,我们讨论了如何通过抽象这样的行为(或使用接口,取决于在上下文中哪种效果最佳)来删除“ is”关键字:

using System;

namespace test
{
    class Program
    {
        public abstract class Base
        {
            public abstract void Foo();
        }

        public class A : Base
        {
            public override void Foo()
            {
                Console.WriteLine("This is A.");
            }
        }

        public class B : Base
        {
            public override void Foo()
            {
                Console.WriteLine("This is B");
            }
        }

        public static void Test(Base obj)
        {
            obj.Foo();
        }

        static void Main(string[] args)
        {
            Test(new A());
        }
    }
}

因此,从那里开始,我们一群人试图弄清楚在哪种情况下使用“ is”关键字确实是合理的。我们可以提出的所有示例均被排除,因为它们来自其他代码气味。

我在网上做了一些研究以寻找答案,但是大多数网站只提供定义和如何使用关键字,但找不到任何可以引用与该关键字有关的“良好做法”的资料。

总而言之,我的问题是,在哪些情况下(如果有的话)使用“ is”关键字是合理的(必要/更优雅)?

编辑:更多信息需要澄清。在很多情况下,即使不是大多数关键字/声明/指令,也存在使用有意义的上下文以及其他使用不合理的上下文。

例如,trycatchthrow非常适合当您需要对程序运行时出现的异常情况(例如尝试除法)做出响应时减零。但是,大多数程序员都同意将它们用于控制流是一个坏主意。

出于同样的考虑,goto可用于开关或嵌套循环中,这是通常接受的用法。但是,如果您开始使用goto在代码中跳来跳去,那么再次被大多数程序员认为是一个坏主意。

因此,我想确定is的哪些用例将被大多数程序员拒绝,哪些用例将被大多数程序员拒绝?

1 个答案:

答案 0 :(得分:2)

一切对某人来说都是代码的味道,有些比其他东西更有趣。

is (C# Reference)

  

检查对象是否与给定类型兼容,或(以   C#7.0)针对模式测试表达式。

寻求is的合法使用就像要求合法使用水一样。它永无止境,所有人都可以整日辩论……如果您某人竭尽全力证明一切都是气味,那么您将永远不会获胜。

但是,我们所知道的是。如果您需要检查对象是否与给定类型兼容,那么您有一个合法的用例,以故事。

考虑事件和发送者参数。

考虑基本类型列表。

<insert oodles of more list items here>

BCL示例

public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source)
{
   if (source == null) throw Error.ArgumentNull("source");
   return OfTypeIterator<TResult>(source);
}

static IEnumerable<TResult> OfTypeIterator<TResult>(IEnumerable source)
{
   foreach (object obj in source)
   {
      if (obj is TResult) yield return (TResult)obj;
   }
}