Enforces an int operand on bitwise and shift operations
TRY THIS RULE ID: csharp-best-practices/bitwise-right-operand-int
Language: C#
Severity: Error
Category: Error Prone
Description When a variable is marked dynamic
, the compiler does not validate that the right operand of bitwise or shift operations is valid, which can lead to an unexpected run-time exception. This rule checks that the right operand of bitwise and shift operations is of type int
, sbyte
, byte
, short
, ushort
, or char
.
Input:
dynamic dyn = 4 ;
// The next line causes a run-time exception:
var shifted = dyn << 2.0 ;
Output:
Run-time exception (line 6): Operator '<<' cannot be applied to operands of type 'int' and 'double'\
Stack Trace:\
[Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Operator '<<' cannot be applied to operands of type 'int' and 'double']\
at CallSite.Target(Closure , CallSite , Object , Double )\
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)\
at Program.Main()
Non-Compliant Code Examples class NonCompliant {
public static void Main ()
{
dynamic dyn = 4 ;
var binExp = dyn << 1 ;
binExpr = dyn << new { amount = 1 };
binExpr = dyn << new int [ 1 ];
binExpr = dyn << ( double ) 2 ;
binExpr = dyn << default ( double );
binExpr = dyn << new []{ 1 };
binExpr = dyn << new ( "key" , "value" );
binExpr = dyn << {[ "key" ] = 4 };
binExpr = dyn << $"{2}" ;
binExpr = dyn << 1. . 2 ;
binExpr = dyn << typeof ( int );
binExpr = dyn << 2.0 ;
binExpr = dyn << null ;
binExpr = dyn << true ;
binExpr = dyn << "2" ;
binExpr = dyn << @"2" ;
binExpr = dyn << """2""" ;
binExpr = dyn << 2F ;
binExpr = dyn << 2f ;
binExpr = dyn << 2L ;
binExpr = dyn << 2l ;
binExpr = dyn << 2 U ;
binExpr = dyn << 2 u ;
binExpr = dyn << 2 UL ;
binExpr = dyn << 2 ul ;
binExpr = dyn << 2 M ;
binExpr = dyn << 2 m ;
binExpr = dyn << 2E+1 ;
binExpr = dyn << 2e+1 ;
binExpr = dyn << ( 1 , 2 );
binExpr = dyn << new object ();
var assignment = dyn << 1 ;
assignment <<= new { amount = 1 };
assignment <<= new int [ 1 ];
assignment <<= ( double ) 2 ;
assignment <<= default ( object );
assignment <<= new []{ 1 };
assignment <<= new ( "key" , "value" );
assignment <<= {[ "key" ] = 4 };
assignment <<= $"{2}" ;
assignment <<= 1. . 2 ;
assignment <<= typeof ( int );
assignment <<= 2.0 ;
assignment <<= null ;
assignment <<= true ;
assignment <<= "2" ;
assignment <<= @"2" ;
assignment <<= """2""" ;
assignment <<= 2F ;
assignment <<= 2f ;
assignment <<= 2L ;
assignment <<= 2l ;
assignment <<= 2 U ;
assignment <<= 2 u ;
assignment <<= 2 UL ;
assignment <<= 2 ul ;
assignment <<= 2 M ;
assignment <<= 2 m ;
assignment <<= 2E+1 ;
assignment <<= 2e+1 ;
assignment <<= ( 1 , 2 );
assignment <<= new object ();
}
}
Compliant Code Examples class Compliant {
public static void Main ()
{
dynamic dyn = 4 ;
var binExp = dyn << 1 ;
binExp = dyn << ( int ) 2.1 ;
binExp = dyn << ( byte ) 2.1 ;
binExp = dyn << ( short ) 2.1 ;
binExp = dyn << ( ushort ) 2.1 ;
binExp = dyn << ( char ) 2.1 ;
binExp = dyn << default ( int );
binExp = dyn << 2 ;
binExp = dyn << 0 b0000010 ;
binExp = dyn << 0x2 ;
binExp = dyn << '2' ;
var assignment = dyn << 1 ;
assignment <<= ( int ) 2.1 ;
assignment <<= ( sbyte ) 2.1 ;
assignment <<= ( byte ) 2.1 ;
assignment <<= ( short ) 2.1 ;
assignment <<= ( ushort ) 2.1 ;
assignment <<= ( char ) 2.1 ;
assignment <<= default ( int );
assignment <<= 2 ;
assignment <<= 0 b0000010 ;
assignment <<= 0x2 ;
assignment <<= '2' ;
myObject = new MyObject ( 123 );
}
}
Seamless integrations. Try Datadog Code Analysis