今天我们在讨论用例的工作中进行了讨论,其中您的代码与此类似:
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());
}
}
}
然后我们讨论了如何通过抽象这样的行为(或使用接口,取决于在上下文中最好的工作)来删除“是”关键字:
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”关键字的情况哪些是合理的。我们可以提出的所有例子都被排除了,因为它们来自其他代码味道。
我在网上做了一些研究以获得答案,但大多数网站只提供定义以及如何使用关键字,但我找不到任何可以引用与关键字相关的“良好实践”的来源。
总之,我的问题是,使用“是”关键字的情况(必要/更优雅)是什么(如果有的话)?
编辑:更多信息以澄清。对于很多,如果不是大多数关键字/语句/指令,有上下文使用它和其他使用不合理的上下文是有意义的。
例如,try
,catch
,throw
非常棒,当您需要对程序运行时出现的异常情况做出响应时,例如尝试除以零。但是,大多数程序员都同意将它们用于控制流程是一个坏主意。
在同样的问题上,goto
可以用在交换机或嵌套循环中,这通常被接受。但是,如果你开始使用goto
在代码中跳转,那么大多数程序员再次认为这是一个坏主意。
因此,我想确定哪些用例会被is
接受,哪些用户会被大多数程序员拒绝?
一切都是某人的代码味道,有些人比其他人更多。
检查对象是否与给定类型兼容,或者(从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;
}
}