简化的方法来做C#运行时类型识别,避免NULL检查?

时间:2013-02-09 20:57:10

标签: c# null rtti

我发现自己使用了一种常见的运行时类型识别模式,特别是在编写处理不同类型控件的代码时。这是模式:

if (ctrl is ControlTypeEtc)
    (ctrl as ControlTypeEtc).SomeMethod();

我这样做是为了避免在 as 运算符返回NULL的情况下进行NULL检查。有没有办法将其简化为单一操作?

3 个答案:

答案 0 :(得分:4)

无法在一次操作中执行此操作。

但是,使用as并检查null会更便宜,因为代码示例中只有一种情况而不是两种情况。

答案 1 :(得分:1)

我会把它写成:

ControlTypeEtc ctrl2 = ctrl as ControlTypeEtc;
if (ctrl2 != null)
    ctrl2.SomeMethod();

这避免了双重检查(可以优化为一个,但我不确定)。

另一种方式:

try
{
    ControlTypeEtc ctrl2 = (ControlTypeEtc)ctrl;
    ctrl2.SomeMethod();
}
catch (InvalidCastException e)
{
}

答案 2 :(得分:1)

底线是,“大图”你应该知道你的实例是否为null,然后再对它进行编码。没有理由在这一步找到捷径。

也就是说,如果您使用的是C#3或更高版本,则可以使用扩展方法,这些方法可用于从代码的主逻辑中“隐藏”此详细信息。请参阅下面的示例,其中包含'SomeType'和'SomeMethod',然后是一个名为'SomeMethodSafe'的扩展方法。你可以在Null引用上调用'SomeMethodSafe'而不会出错。

不要在家里试试。

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            SomeType s = null;
            //s = new SomeType();
            // uncomment me to try it with an instance

            s.SomeMethodSafe();

            Console.WriteLine("Done");
            Console.ReadLine();
        }
    }

    public class SomeType
    {
        public void SomeMethod()
        {
            Console.WriteLine("Success!");
        }
    }

    public static class SampleExtensions
    {
        public static void SomeMethodSafe(this SomeType t)
        {
            if (t != null)
            {
                t.SomeMethod();
            }
        }
    }
}