LoginSignup
1
0

More than 3 years have passed since last update.

ちょっと不思議なC#クイズ

Last updated at Posted at 2020-02-08

Q1

struct A
{
    int sum;

    public int Sum(Action<int, int> log)
    {
        sum = 0;
        for (var i = 0; i < 10; i++)
        {
            sum += i;
            log(i, sum);
        }

        return sum;
    }
}

上記のクラスのSumメソッドは常に45を返してきそうな感じがしますね。
実はSumメソッドに渡す引数次第では他の値が返ってくる可能性があります。
どのような引数を与えれば他の値を返すことができるでしょうか。

答え(リフレクションあり)
var temp = new[]{(object)(new A())};
var sumMethod = typeof(A).GetMethod("Sum");
var sumField = typeof(A).GetField("sum", BindingFlags.NonPublic | BindingFlags.Instance);
var result = sumMethod.Invoke(temp[0], new object[]
{
    new Action<int, int>((i, sum) =>
    {
        sumField.SetValue(temp[0], 999);
        Console.WriteLine($"i:{i} sum:{sum}");
    }),
});
Console.WriteLine(result);
/*
i:0 sum:0
i:1 sum:1000
i:2 sum:1001
i:3 sum:1002
i:4 sum:1003
i:5 sum:1004
i:6 sum:1005
i:7 sum:1006
i:8 sum:1007
i:9 sum:1008
999
*/

答え(リフレクションなし)
var a = new A();
var result = a.Sum((i, sum) =>
{
    a = new A();
    Console.WriteLine($"i:{i} sum:{sum}");
});
Console.WriteLine(result);
/*
i:0 sum:0
i:1 sum:1
i:2 sum:2
i:3 sum:3
i:4 sum:4
i:5 sum:5
i:6 sum:6
i:7 sum:7
i:8 sum:8
i:9 sum:9
0
*/

Q2

interface ITest
{
}

struct A
{
    int elemCount;

    public int Init<T>(Span<T> s)
        where T : ITest
    {
        elemCount = 0;
        foreach (ref var i in s)
        {
            elemCount++;
            i = default;
        }
        return elemCount;
    }
}

似たような問題です。
Initメソッドに要素数1以上のSpanを渡した場合、必ず1以上の値が返ってきそうな感じがします。
これも引数次第では1以上の値が返ってこない可能性があります。
どのような引数を与えればいいでしょうか。

答え
struct AA : ITest
{
    public A a;
}

static void Do()
{
    Span<AA> s = stackalloc AA[1];
    var result = s[0].a.Init(s);
    Console.WriteLine(result);
}
/*
0
*/

最後に

どちらの解答も思いついた方は相当C#に詳しい方だと思います。
こんなこと知ってなくてもC#を書くことはできますがもしかしたら役に立つときが来るかもしれません。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0