|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Analyzers.HiddenExplicitCast;
using Microsoft.CodeAnalysis.CSharp.CodeFixes.HiddenExplicitCast;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
using Microsoft.CodeAnalysis.Testing;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.HiddenExplicitCast;
using VerifyCS = CSharpCodeFixVerifier<
CSharpHiddenExplicitCastDiagnosticAnalyzer,
CSharpHiddenExplicitCastCodeFixProvider>;
public sealed class HiddenExplicitCastTests
{
[Fact]
public Task TestInheritanceAndUserDefined()
=> new VerifyCS.Test
{
TestCode = """
class Base { }
class Derived : Base { }
class Castable
{
public static explicit operator Base(Castable c) => new Base();
}
class C
{
static void Main(string[] args)
{
var v = [|(Derived)new Castable()|];
}
}
""",
FixedCode = """
class Base { }
class Derived : Base { }
class Castable
{
public static explicit operator Base(Castable c) => new Base();
}
class C
{
static void Main(string[] args)
{
var v = (Derived)(Base)new Castable();
}
}
""",
}.RunAsync();
[Fact]
public Task TestNullableAndUserDefined()
=> new VerifyCS.Test
{
TestCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
static void Main(string[] args)
{
S? s = new S();
int i = [|(int)s|];
}
}
""",
FixedCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
static void Main(string[] args)
{
S? s = new S();
int i = (int)(decimal?)s;
}
}
""",
}.RunAsync();
[Fact]
public Task TestNumericAndUserDefined()
=> new VerifyCS.Test
{
TestCode = """
struct UnixTime
{
public static explicit operator UnixTime(int i)
{
return default;
}
}
class C
{
public UnixTime M(long i) => [|(UnixTime)i|];
}
""",
FixedCode = """
struct UnixTime
{
public static explicit operator UnixTime(int i)
{
return default;
}
}
class C
{
public UnixTime M(long i) => (UnixTime)(int)i;
}
""",
}.RunAsync();
[Fact]
public Task TestTopLevel()
=> new VerifyCS.Test
{
TestCode = """
S? s = new S();
int i = [|(int)s|];
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
""",
FixedCode = """
S? s = new S();
int i = (int)(decimal?)s;
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
""",
LanguageVersion = LanguageVersion.CSharp10,
TestState = { OutputKind = OutputKind.ConsoleApplication },
}.RunAsync();
[Fact]
public Task TestArgument()
=> new VerifyCS.Test
{
TestCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
static void Main(string[] args)
{
S? s = new S();
Goo([|(int)s|]);
}
static void Goo(int i) { }
}
""",
FixedCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
static void Main(string[] args)
{
S? s = new S();
Goo((int)(decimal?)s);
}
static void Goo(int i) { }
}
""",
}.RunAsync();
[Fact]
public Task TestAssignment()
=> new VerifyCS.Test
{
TestCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
static void Main(string[] args)
{
S? s = new S();
int i;
i = [|(int)s|];
}
}
""",
FixedCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
static void Main(string[] args)
{
S? s = new S();
int i;
i = (int)(decimal?)s;
}
}
""",
}.RunAsync();
[Fact]
public Task TestReturn()
=> new VerifyCS.Test
{
TestCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
static int Main(string[] args)
{
S? s = new S();
int i;
return [|(int)s|];
}
}
""",
FixedCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
static int Main(string[] args)
{
S? s = new S();
int i;
return (int)(decimal?)s;
}
}
""",
}.RunAsync();
[Fact]
public Task TestFieldInitializer()
=> new VerifyCS.Test
{
TestCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
int i = [|(int)new S()|];
}
""",
FixedCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
int i = (int)(decimal?)new S();
}
""",
}.RunAsync();
[Fact]
public Task TestPropertyInitializer()
=> new VerifyCS.Test
{
TestCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
int X => [|(int)new S()|];
}
""",
FixedCode = """
public struct S
{
public static explicit operator decimal?(S s) { return 1.0m; }
}
class C
{
int X => (int)(decimal?)new S();
}
""",
}.RunAsync();
[Fact]
public Task TestUserDefinedToDouble_ThenDoubleToFloat()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator double(Value v) => 1.0;
}
class C
{
void M()
{
var v = new Value();
float f = [|(float)v|];
}
}
""",
FixedCode = """
struct Value
{
public static explicit operator double(Value v) => 1.0;
}
class C
{
void M()
{
var v = new Value();
float f = (float)(double)v;
}
}
""",
}.RunAsync();
[Fact]
public Task TestUserDefinedToLong_ThenLongToShort()
=> new VerifyCS.Test
{
TestCode = """
struct BigNumber
{
public static explicit operator long(BigNumber b) => 100L;
}
class C
{
short M(BigNumber b) => [|(short)b|];
}
""",
FixedCode = """
struct BigNumber
{
public static explicit operator long(BigNumber b) => 100L;
}
class C
{
short M(BigNumber b) => (short)(long)b;
}
""",
}.RunAsync();
[Fact]
public Task TestUserDefinedToDecimal_ThenDecimalToInt()
=> new VerifyCS.Test
{
TestCode = """
struct Money
{
public static explicit operator decimal(Money m) => 100.50m;
}
class C
{
int M(Money m) => [|(int)m|];
}
""",
FixedCode = """
struct Money
{
public static explicit operator decimal(Money m) => 100.50m;
}
class C
{
int M(Money m) => (int)(decimal)m;
}
""",
}.RunAsync();
[Fact]
public Task TestUserDefinedToBaseClass_ThenBaseToDerived()
=> new VerifyCS.Test
{
TestCode = """
class Animal { }
class Dog : Animal { }
class AnimalFactory
{
public static explicit operator Animal(AnimalFactory f) => new Dog();
}
class C
{
Dog M(AnimalFactory f) => [|(Dog)f|];
}
""",
FixedCode = """
class Animal { }
class Dog : Animal { }
class AnimalFactory
{
public static explicit operator Animal(AnimalFactory f) => new Dog();
}
class C
{
Dog M(AnimalFactory f) => (Dog)(Animal)f;
}
""",
}.RunAsync();
[Fact]
public Task TestUserDefinedToGrandparent_ThenGrandparentToGrandchild()
=> new VerifyCS.Test
{
TestCode = """
class GrandParent { }
class Parent : GrandParent { }
class Child : Parent { }
struct Wrapper
{
public static explicit operator GrandParent(Wrapper w) => new Child();
}
class C
{
Child M(Wrapper w) => [|(Child)w|];
}
""",
FixedCode = """
class GrandParent { }
class Parent : GrandParent { }
class Child : Parent { }
struct Wrapper
{
public static explicit operator GrandParent(Wrapper w) => new Child();
}
class C
{
Child M(Wrapper w) => (Child)(GrandParent)w;
}
""",
}.RunAsync();
[Fact]
public Task TestUserDefinedToNullableInt_ThenNullableIntToInt()
=> new VerifyCS.Test
{
TestCode = """
struct OptionalNumber
{
public static explicit operator int?(OptionalNumber o) => 42;
}
class C
{
int M(OptionalNumber o) => [|(int)o|];
}
""",
FixedCode = """
struct OptionalNumber
{
public static explicit operator int?(OptionalNumber o) => 42;
}
class C
{
int M(OptionalNumber o) => (int)(int?)o;
}
""",
}.RunAsync();
[Fact]
public Task TestUserDefinedToNullableLong_ThenNullableLongToShort()
=> new VerifyCS.Test
{
TestCode = """
struct LargeOptional
{
public static explicit operator long?(LargeOptional l) => 1000L;
}
class C
{
short M(LargeOptional l) => [|(short)l|];
}
""",
FixedCode = """
struct LargeOptional
{
public static explicit operator long?(LargeOptional l) => 1000L;
}
class C
{
short M(LargeOptional l) => (short)(long?)l;
}
""",
}.RunAsync();
[Fact]
public Task TestNullableSourceToUserDefinedFromInt()
=> new VerifyCS.Test
{
TestCode = """
struct Target
{
public static explicit operator Target(int i) => default;
}
class C
{
Target M(long? l) => [|(Target)l|];
}
""",
FixedCode = """
struct Target
{
public static explicit operator Target(int i) => default;
}
class C
{
Target M(long? l) => (Target)(int)l;
}
""",
}.RunAsync();
[Fact]
public Task TestUserDefinedToNullableDouble_ThenToFloat()
=> new VerifyCS.Test
{
TestCode = """
struct PreciseValue
{
public static explicit operator double?(PreciseValue p) => 3.14159;
}
class C
{
float M(PreciseValue p) => [|(float)p|];
}
""",
FixedCode = """
struct PreciseValue
{
public static explicit operator double?(PreciseValue p) => 3.14159;
}
class C
{
float M(PreciseValue p) => (float)(double?)p;
}
""",
}.RunAsync();
[Fact]
public Task TestInArrayInitializer()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int[] M(Value v) => new int[] { [|(int)v|] };
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int[] M(Value v) => new int[] { (int)(long)v };
}
""",
}.RunAsync();
[Fact]
public Task TestInConditionalExpression()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int M(Value v, bool b) => b ? [|(int)v|] : 0;
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int M(Value v, bool b) => b ? (int)(long)v : 0;
}
""",
}.RunAsync();
[Fact]
public Task TestInInterpolatedString()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator double(Value v) => 3.14;
}
class C
{
string M(Value v) => $"Result: {[|(int)v|]}";
}
""",
FixedCode = """
struct Value
{
public static explicit operator double(Value v) => 3.14;
}
class C
{
string M(Value v) => $"Result: {(int)(double)v}";
}
""",
}.RunAsync();
[Fact]
public Task TestInLambdaExpression()
=> new VerifyCS.Test
{
TestCode = """
using System;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
Func<Value, int> M() => v => [|(int)v|];
}
""",
FixedCode = """
using System;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
Func<Value, int> M() => v => (int)(long)v;
}
""",
}.RunAsync();
[Fact]
public Task TestInObjectInitializer()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class Target
{
public int Number { get; set; }
}
class C
{
Target M(Value v) => new Target { Number = [|(int)v|] };
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class Target
{
public int Number { get; set; }
}
class C
{
Target M(Value v) => new Target { Number = (int)(long)v };
}
""",
}.RunAsync();
[Fact]
public Task TestInSwitchExpression()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
string M(Value v) => [|(int)v|] switch
{
0 => "zero",
_ => "other"
};
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
string M(Value v) => (int)(long)v switch
{
0 => "zero",
_ => "other"
};
}
""",
}.RunAsync();
[Fact]
public Task TestInCollectionInitializer()
=> new VerifyCS.Test
{
TestCode = """
using System.Collections.Generic;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
List<int> M(Value v) => new List<int> { [|(int)v|] };
}
""",
FixedCode = """
using System.Collections.Generic;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
List<int> M(Value v) => new List<int> { (int)(long)v };
}
""",
}.RunAsync();
[Fact]
public Task TestInLinqSelect()
=> new VerifyCS.Test
{
TestCode = """
using System.Collections.Generic;
using System.Linq;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
IEnumerable<int> M(IEnumerable<Value> values) => values.Select(v => [|(int)v|]);
}
""",
FixedCode = """
using System.Collections.Generic;
using System.Linq;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
IEnumerable<int> M(IEnumerable<Value> values) => values.Select(v => (int)(long)v);
}
""",
}.RunAsync();
[Fact]
public Task TestInTupleLiteral()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
(int, int) M(Value v) => ([|(int)v|], 0);
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
(int, int) M(Value v) => ((int)(long)v, 0);
}
""",
}.RunAsync();
[Fact]
public Task TestInForLoopInitializer()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v)
{
for (int i = [|(int)v|]; i < 10; i++) { }
}
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v)
{
for (int i = (int)(long)v; i < 10; i++) { }
}
}
""",
}.RunAsync();
[Fact]
public Task TestInYieldReturn()
=> new VerifyCS.Test
{
TestCode = """
using System.Collections.Generic;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
IEnumerable<int> M(Value v)
{
yield return [|(int)v|];
}
}
""",
FixedCode = """
using System.Collections.Generic;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
IEnumerable<int> M(Value v)
{
yield return (int)(long)v;
}
}
""",
}.RunAsync();
[Fact]
public Task TestInCheckedExpression()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int M(Value v) => checked([|(int)v|]);
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int M(Value v) => checked((int)(long)v);
}
""",
}.RunAsync();
[Fact]
public Task TestInUncheckedExpression()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int M(Value v) => unchecked([|(int)v|]);
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int M(Value v) => unchecked((int)(long)v);
}
""",
}.RunAsync();
[Fact]
public Task TestInBinaryExpression()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int M(Value v) => [|(int)v|] + 1;
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int M(Value v) => (int)(long)v + 1;
}
""",
}.RunAsync();
[Fact]
public Task TestInComparisonExpression()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
bool M(Value v) => [|(int)v|] > 5;
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
bool M(Value v) => (int)(long)v > 5;
}
""",
}.RunAsync();
[Fact]
public Task TestInArrayIndex()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 0L;
}
class C
{
int M(Value v, int[] arr) => arr[[|(int)v|]];
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 0L;
}
class C
{
int M(Value v, int[] arr) => arr[(int)(long)v];
}
""",
}.RunAsync();
[Fact]
public Task TestInNullCoalescingExpression()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long?(Value v) => 100L;
}
class C
{
int M(Value v) => [|(int?)v|] ?? 0;
}
""",
FixedCode = """
struct Value
{
public static explicit operator long?(Value v) => 100L;
}
class C
{
int M(Value v) => (int?)(long?)v ?? 0;
}
""",
}.RunAsync();
[Fact]
public Task TestInDiscard()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v)
{
_ = [|(int)v|];
}
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v)
{
_ = (int)(long)v;
}
}
""",
}.RunAsync();
[Fact]
public Task TestInConstructorArgument()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class Target
{
public Target(int x) { }
}
class C
{
Target M(Value v) => new Target([|(int)v|]);
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class Target
{
public Target(int x) { }
}
class C
{
Target M(Value v) => new Target((int)(long)v);
}
""",
}.RunAsync();
[Fact]
public Task TestInIndexerArgument()
=> new VerifyCS.Test
{
TestCode = """
using System.Collections.Generic;
struct Value
{
public static explicit operator long(Value v) => 0L;
}
class C
{
string M(Value v, Dictionary<int, string> dict) => dict[[|(int)v|]];
}
""",
FixedCode = """
using System.Collections.Generic;
struct Value
{
public static explicit operator long(Value v) => 0L;
}
class C
{
string M(Value v, Dictionary<int, string> dict) => dict[(int)(long)v];
}
""",
}.RunAsync();
[Fact]
public Task TestInStringConcatenation()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
string M(Value v) => "Value: " + [|(int)v|];
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
string M(Value v) => "Value: " + (int)(long)v;
}
""",
}.RunAsync();
[Fact]
public Task TestInRangeExpression()
=> new VerifyCS.Test
{
TestCode = """
using System;
struct Value
{
public static explicit operator long(Value v) => 0L;
}
class C
{
int[] M(Value v, int[] arr) => arr[[|(int)v|]..];
}
""",
FixedCode = """
using System;
struct Value
{
public static explicit operator long(Value v) => 0L;
}
class C
{
int[] M(Value v, int[] arr) => arr[(int)(long)v..];
}
""",
ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
}.RunAsync();
[Fact]
public Task TestInQueryExpression()
=> new VerifyCS.Test
{
TestCode = """
using System.Collections.Generic;
using System.Linq;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
IEnumerable<int> M(IEnumerable<Value> values) =>
from v in values
select [|(int)v|];
}
""",
FixedCode = """
using System.Collections.Generic;
using System.Linq;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
IEnumerable<int> M(IEnumerable<Value> values) =>
from v in values
select (int)(long)v;
}
""",
}.RunAsync();
[Fact]
public Task TestInParenthesizedExpression()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int M(Value v) => ([|(int)v|]);
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
int M(Value v) => ((int)(long)v);
}
""",
}.RunAsync();
[Fact]
public Task TestInThrowExpression()
=> new VerifyCS.Test
{
TestCode = """
using System;
class MyException : Exception
{
public MyException(int code) { }
}
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v) => throw new MyException([|(int)v|]);
}
""",
FixedCode = """
using System;
class MyException : Exception
{
public MyException(int code) { }
}
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v) => throw new MyException((int)(long)v);
}
""",
}.RunAsync();
[Fact]
public Task TestInAwaitExpression()
=> new VerifyCS.Test
{
TestCode = """
using System.Threading.Tasks;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
async Task<int> M(Value v) => await Task.FromResult([|(int)v|]);
}
""",
FixedCode = """
using System.Threading.Tasks;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
async Task<int> M(Value v) => await Task.FromResult((int)(long)v);
}
""",
}.RunAsync();
[Fact]
public Task TestInNestedCast()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
object M(Value v) => (object)[|(int)v|];
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
object M(Value v) => (object)(int)(long)v;
}
""",
}.RunAsync();
[Fact]
public Task TestInWhileCondition()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v)
{
while ([|(int)v|] > 0) { break; }
}
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v)
{
while ((int)(long)v > 0) { break; }
}
}
""",
}.RunAsync();
[Fact]
public Task TestInIfCondition()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v)
{
if ([|(int)v|] > 0) { }
}
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v)
{
if ((int)(long)v > 0) { }
}
}
""",
}.RunAsync();
[Fact]
public Task TestInSwitchStatement()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
string M(Value v)
{
switch ([|(int)v|])
{
case 0: return "zero";
default: return "other";
}
}
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
string M(Value v)
{
switch ((int)(long)v)
{
case 0: return "zero";
default: return "other";
}
}
}
""",
}.RunAsync();
[Fact]
public Task TestInLocalFunctionReturn()
=> new VerifyCS.Test
{
TestCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v)
{
int Local() => [|(int)v|];
}
}
""",
FixedCode = """
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v)
{
int Local() => (int)(long)v;
}
}
""",
}.RunAsync();
[Fact]
public Task TestInUsingDeclaration()
=> new VerifyCS.Test
{
TestCode = """
using System;
using System.IO;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v, MemoryStream[] streams)
{
using var s = streams[[|(int)v|]];
}
}
""",
FixedCode = """
using System;
using System.IO;
struct Value
{
public static explicit operator long(Value v) => 100L;
}
class C
{
void M(Value v, MemoryStream[] streams)
{
using var s = streams[(int)(long)v];
}
}
""",
}.RunAsync();
}
|