最好的“不是”;c#语法

本文关键字:语法 不是 | 更新日期: 2023-09-27 18:05:16

对我来说,重要的是我的语法不会让其他开发人员感到困惑。

在这个例子中,我需要知道参数是否是某种类型。

我以前碰到过这个;测试"不是"的最优雅、最清晰的方法是什么?

方法1:

void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    if (!(e.parameter is MyClass)) { /* do something */ }
}
方法2:

void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    if (e.parameter is MyClass) { } else { /* do something */ }
}
方法3:

void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    var _Parameter = e.parameter as MyClass;
    if (_Parameter != null) { /* do something */ }
}
方法4:

void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    var _Type = typeof(MyClass);
    switch (e.parameter.GetType())
    { 
      case _Type: /* do nothing */; break;
      default: /* do something */; break;
    }
}

[EDIT]方法五:

void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    if ((e.parameter is MyClass) == false) { /* do something */ }
}

哪个是最直接的方法?

最好的“不是”;c#语法

这显然是个人意见和风格的问题,所以没有正确的答案,但我认为这是最清楚的:

void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    if ((e.parameter is MyClass) == false) { /* do something */ }
}

== false比!

明显

如果稍后需要这个变量,我会选择3;如果不需要这个变量,我会选择1。2是丑陋的,因为空块。

但是我认为它们都很直接。

我认为只是做一个扩展方法将是一个明确的方式:

public static bool CannotBeCastAs<T>(this object actual)
    where T: class
{
    return (actual as T == null);
}

然后像这样检查:

if(myObject.CannotBeCastAs<SomeClass>())
{
}

方法1和3是我的选择,这取决于我实际想要什么。

方法1"做某事"当且仅当传递的对象不是预期的类型。这意味着传递的对象可以为空,但仍然可以传递。

如果传递的对象不是预期的类型,或者对象为空,方法3"做一些事情"。这基本上是一次检查,您有一个"有效"的类实例来进一步处理。

所以,我想要1还是3取决于我打算做什么。通常,当变量不是预期的类型或为空时,我想抛出异常。如果我对只抛出一种类型的异常(比如只是一个ArgumentException)感到满意,我将使用方法3。如果我想单独检查null并抛出ArgumentNullException,我将使用方法1并添加null检查。

方法2在功能上是正确的,但我宁愿将方法1中的if条件反转,因为一个什么都不做的if块是多余的。

我绝不会使用方法4。用switch语句代替简单的if-else语句是没有必要的,而且令人困惑,尤其是在您使用它的方式中。

对我来说,方法1是最直接的,无论是它本身还是按照惯例。这是我看到最多的语法,如果你只是需要知道一个对象是否"是一个"特定的类。

如果你真的需要对对象"as-a"做一些事情,那么方法3就是最好的选择。

方法1在我看来是最好的。代码的作用非常明显,我可以跟着做。方法2引入了不必要的语法,很容易被方法1纠正。方法3需要我比其他两种思考更多(稍微,但仍然!),它还使用了不需要的额外空间。

请记住,代码是为人们阅读而写的,而不是为机器执行而写的。每次都要清晰。

如果你想要优雅和可读性:

void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    bool isMyClass = e.parameter is MyClass;
    if (!isMyClass) // or isMyClass == false
    { 
        /* do something */ 
    }
}

我总是尽量避免在一行代码中放入太多的逻辑,特别是if条件。我认为类型检查和反运算符第一眼可能会让人讨厌。

方法# 5 (不同的自旋)

public static class TypeExtensions
{
    public static bool IsNotTypeOf<T, X>(this T instance, X typeInstance)
    {
        return instance.GetType() != typeInstance.GetType();
    }
}
// ...
if(e.parameter.IsNotTypeOf(MyClass)) { /* do something */ } ;

我认为大括号功能应该始终匹配应用程序中使用的任何大括号模式。例如,对于迭代或条件块,如果使用:

If (foo != bar)
{
    //Do Something
}

那么这应该是你在任何时候使用大括号模式功能的方式。在阅读别人的代码时,我最大的烦恼之一(尤其是当他们使用CodeRush或Resharper时)就是人们为了显示魔法而添加的不必要的简洁。

我并不是说上面是最好的括号匹配模式,但是,使用任何你觉得舒服的模式,我想要传达的是模式并不重要,重要的是其使用的一致性。

与VB相比,c#是一种简洁的语言。Net中,我会使用长形式的语句或赋值(var初始化除外),而不是更精简的语法,以帮助以后的可读性。

我喜欢一个NUnit Assert使用的方法:

Assert.InstanceOf<MyType>(objectInstance);

顺便说一句,如果您有一组检查对象是否为特定类型,如:

if(objectInstance is TypeA)
{
  // ...
}else
{
  if(objectInstance is TypeC)
  {
    // ...
  }
}

应该有一些设计问题,如少数类型之间的绑定耦合,因此考虑其他方法,如注入关联映射或每个类型的映射算法方法

IDictionary<Type, Func<TParameter>>