2

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

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

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

4

3 回答 3

4

没有办法在一次操作中做到这一点。

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

于 2013-02-09T20:59:46.223 回答
1

我会把它写成:

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

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

其他方式:

try
{
    ControlTypeEtc ctrl2 = (ControlTypeEtc)ctrl;
    ctrl2.SomeMethod();
}
catch (InvalidCastException e)
{
}
于 2013-02-09T21:03:13.080 回答
1

底线是“大图”,在您继续编码之前,您应该知道您的实例是否为空。确实没有理由在该步骤周围找到捷径。

也就是说,如果您使用的是 C# 3 或更好的版本,则可以使用 Extensions 方法从代码的主要逻辑中“隐藏”此细节。请参见下面的示例,其中包含“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();
            }
        }
    }
}
于 2013-02-09T21:07:52.747 回答