何时使用!()或!=如果不为null

时间:2012-01-05 09:40:12

标签: c# coding-style

虽然重构代码我改变了所有if not null条件,以遵循我的代码中的多数约定

if (!(foo == null))

而不是

if (foo != null)

这两种说法都有任何优势吗?

c#中的任何一个语句都有什么优势吗?

10 个答案:

答案 0 :(得分:28)

我发现第二个更具可读性。

除此之外,没有区别。

与团队一起选择约定并在任何一个特定的代码库中坚持下去更为重要。

答案 1 :(得分:10)

假设您没有损坏== / !=运算符重载,我只是使用第二种形式以获得简单/可读性。如果已经破坏了重载,使得两者之间存在语义差异,那么我建议修复这些重载:)

在极少数情况下,foo == null更清楚地表明某些事情,我可能会重构它以使用局部变量:

bool somethingIsMissing = foo == null;
if (!somethingIsMissing)
{
    ...
}

围绕foo == null的括号现在是可选的 - 根据品味使用或不使用。主要的是你可以使用变量名来使语义意义非常清楚

答案 2 :(得分:6)

通常if (!(foo == null))用于考虑更多变量,例如

if (!(f1 == 'a' && f2 != 'b'))

有时更容易这样将所有内容转换为相反的内容,特别是当您使用按位运算符时。

答案 3 :(得分:5)

第一个使用两个运算符,第二个使用一个。从技术上讲,第二个更简单。

答案 4 :(得分:3)

我将使用!(a == b)的唯一地方将在!=的运算符实现中这样:

public static bool operator != (MyType a, MyType b)
{
    return !(a == b);
}

答案 5 :(得分:2)

在我看来,没有区别,编译器无论如何都会优化代码。但我更喜欢if(foo != null)。括号少,易于阅读。

答案 6 :(得分:1)

我喜欢的是第二个,因为它比第一个更易读。

他们没有任何区别,所以这只是你的选择。

但是,如果if子句中有许多其他变量,则第一个可能是要使用的变量。

你最终的选择。

答案 7 :(得分:0)

因为,第一种形式使用2对1 C#操作符,它可能编译为更多的CIL代码,虽然在大多数用例中大多数会遇到,但它可能不会产生重要的代码大小或表现差异。

可能产生显着差异的是可读性,因此在编写/修改时可能出错。我愿意(而你谢尔顿现在可能想要遮住你的眼睛)避免使用“!”运营商com-PLETELY。 “喘息!我 - 你的话!”是的,我说了。我明白了!充满激情!它很容易被遗漏,因为它通常旁边是一个看起来相似的标点字符(即左边的“(”)和右边的类似标识字母(即“我”)。并且错过它可能会产生严重的后果,因为这意味着你认为代码正在做它实际正在做的事情的确切对立!它也可能更有可能被诵读困难所遗漏,使得它可能成为受ADA保护的残疾人权利问题。

考虑以下非常可能的例子:

   if (!IsIisServerConnected)
   if (IsOfflineMode || !(IsIisLocalServerConnected || IsIisCloudServerConnected))

我会写下以下内容:

   if (false.Equals(IsIisServerConnected))
   if 
   (
     IsOfflineMode 
     || false.Equals
     (
         IsIisLocalServerConnected 
         || IsIisCloudServerConnected
     )
   )

或者在你的情况下:

   if (false.Equals(foo == null))

请记住,C(C#,C ++,JavaScript,Java和许多其他当前流行语言最终继承了基本语法的语言)的语言是在此时创建的打卡仍然很常见。使用现代CPU,RAM,显示器和IDE(可以使用自定义键盘快捷键生成“false.Equals(?)”代码段),对于大多数应用程序的大多数人来说,可读性非常多,很多(我提到过“ “?”比保存一些代码字符更重要。

P.S。您还可以向调用它的Boolean Struct添加扩展方法,哦,我不知道,Not! ; D所以你可以写:

if (IsIisServerConnected.Not())
if ((foo == null).Not())

答案 8 :(得分:0)

可读性是关键,因此当您使用等于运算符时,应将!=放在此处以使其更清晰

var app = angular.module('IBMfinder', ['ngRoute']); app.config(['$routeProvider', function($routeProvider, settings) { $routeProvider .when('/main', { templateUrl: 'welcome.html', controller: 'welcomeCtrl', }) .when('/find', { templateUrl: 'find.html', controller: 'findCtrl', }) .when('/chat', { templateUrl: 'chat.html', controller: 'chatCtrl', }) .otherwise({ templateUrl: 'welcome.html', controller: 'welcomeCtrl', }) }]) app.controller('userCount', ['$scope', 'socket', function($scope, socket){ socket.on('userCount', function(amount){ $scope.online = amount; }) }]); app.controller('welcomeCtrl', ['$scope', '$location', 'settings', 'socket', function($scope, $location, settings, socket){ $scope.users = 13; if(settings.getUsername()!==""){ socket.emit('delete'); settings.reset(); } $scope.enter = function(){ settings.setUsername($scope.name); $location.path('/find'); } }]); app.controller('findCtrl', ['$scope', '$location', 'settings', 'socket', '$rootScope', function($scope, $location, settings, socket, $rootScope){ $scope.username = settings.getUsername(); if(!$scope.username || $scope.username == ""){ location.href = "index.html"; } if(settings.exists){ socket.emit('delete'); location.href = "index.html"; } $scope.chatlog = []; if(!settings.exists){ var username = $scope.username; settings.setExists(true); socket.emit('new user', username ); }; socket.on('match', function (data) { settings.setPartner(data['username'], data['id']); $location.path('/chat'); }); }]); app.controller('chatCtrl', ['$scope', '$location', 'settings', 'socket', '$rootScope', '$timeout', '$window', '$interval', function($scope, $location, settings, socket, $rootScope, $timeout, $window, $interval){ var typing = false; var focus = true; var titleTimer; var onFocus = function(){ focus = true; $interval.cancel(titleTimer); document.title = 'Chat-Box'; } var onBlur = function(){ focus = false; } $window.onfocus = onFocus; $window.onblur = onBlur; $scope.username = settings.getUsername(); $scope.partnerTyping = false; if(!$scope.username || $scope.username == ""){ location.href = "index.html"; } $scope.chatlog = []; if(!settings.exists){ var username = $scope.username; settings.setExists(true); socket.emit('new user', username ); }; socket.on('incoming message', function(data){ if($scope.chatlog[$scope.chatlog.length-1]){ if($scope.chatlog[$scope.chatlog.length-1].sentby == data.userID){ $scope.chatlog[ $scope.chatlog.length] = { sentby:data.userID, chatusername: '', chatmessage: data.message } }else{ $scope.chatlog[ $scope.chatlog.length] = { sentby:data.userID, chatusername: data.user + ": ", chatmessage: data.message } } }else{ $scope.chatlog[ $scope.chatlog.length] = { sentby:data.userID, chatusername: data.user + ": ", chatmessage: data.message } } if(!focus){ document.title = 'New Message!'; $interval.cancel(titleTimer); titleTimer = $interval(function(){ if(document.title == 'New Message!'){ document.title = 'Chat-Box'; }else{ document.title = 'New Message!'; } }, 1000) } }); socket.on('aborted', function(data){ alert('Your partner left, sorry!'); socket.emit('delete'); settings.reset(); location.href = "index.html"; }) $scope.typing = function(){ if(!typing){ socket.emit('typing', settings.getID()); typing = true; var stop = $timeout(function() { typing = false; socket.emit('stop typing', settings.getID()); }, 2000); } } socket.on('typing', function(data){ $scope.partnerTyping = true; $('#chatbox').scrollTop(10000); }) socket.on('stop typing', function(data){ $scope.partnerTyping = false; $('#chatbox').scrollTop(10000); }) $scope.sendMessage = function(){ if($scope.message==""){ }else{ socket.emit( 'new message', { message:$scope.message, partner:$scope.partner, partnerID: settings.getID() }); } $scope.message = ""; } $scope.partner = settings.getPartner(); }]); app.service('settings', function() { this.exists = false; this.username = ""; this.partner = ""; this.partnerID = ""; this.userdata = {} this.setExists = function(bool){ this.exists = bool; } this.setUsername = function(uname){ this.username = uname; } this.getUsername = function(){ return(this.username); } this.setUserID = function(id){ this.userdata.id = id; } this.getuserdata = function(){ return(this.userdata); } this.setPartner = function(uname, id){ this.partner = uname; this.partnerID = id; } this.getPartner = function(){ return(this.partner); } this.getID = function(){ return(this.partnerID); } this.reset = function(){ this.exists = false; this.username = ""; this.partner = ""; this.partnerID = ""; this.userdata = {} } }); app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); }, emit: function (eventName, data, callback) { socket.emit(eventName, data, function () { var args = arguments; $rootScope.$apply(function () { if (callback) { callback.apply(socket, args); } }); }) }, disconnect: function(id){ socket.disconnect(id); } }; }); app.directive('myEnter', function () { return function (scope, element, attrs) { element.bind("keydown keypress", function (event) { if(event.which === 13) { scope.$apply(function (){ scope.$eval(attrs.myEnter); }); event.preventDefault(); } }); }; }); app.directive('schrollBottom', function () { return { scope: { schrollBottom: "=" }, link: function (scope, element) { scope.$watchCollection('schrollBottom', function (newValue) { if (newValue) { $(element).scrollTop(100000); } }); } } }) if ( (a != b) and (a != c) )更清晰。但是,当您具有返回布尔值(如if (!( (a == b) or (a == c) ))if !()

的函数时,if !(a.valid())格式会更好。

如果您的相等表达式变得特别复杂,这也可能会损害可读性,那时候最好将测试移至具有清晰名称(例如if !( String.IsNullOrEmpty(a) )

)的函数

答案 9 :(得分:0)

在C#8中,您现在可以编写“价值在哪里”

strip()

它也可以与可空引用功能配合使用,该功能将于2021年启用。