Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extensions #471

Open
Tracked by #462
ufcpp opened this issue Jun 12, 2024 · 2 comments
Open
Tracked by #462

Extensions #471

ufcpp opened this issue Jun 12, 2024 · 2 comments

Comments

@ufcpp
Copy link
Owner

ufcpp commented Jun 12, 2024

https://ufcpp.net/blog/2024/3/extensions/

@ufcpp ufcpp mentioned this issue Jun 12, 2024
13 tasks
@ufcpp
Copy link
Owner Author

ufcpp commented Jun 12, 2024

昔ちょこっと書いたの:

要求1: 静的メンバー

C# 3.0 の拡張メソッドはインスタンス メソッドでだけ「既存の型に追加したように見える書き方」ができます。
123.Extension() とはできても、int.Extension() とはできません。

既存の型に静的メソッドを足せなくて困る例としては、ポリフィル(古い環境向けに最新機能を移植して使えるようにするような用途)とかでしょうか。

例えば割かし最近(.NET 8、2023年11月正式リリース)、TimeProviderという型が入って以下のような書き方ができるようになりました。

TimeProvider tp = TimeProvider.System;

// 1秒待つ。
// TimeProvider を差し替えて、単体テストとかでは一瞬で終わるようにしたい。
await Task.Delay(TimeSpan.FromSeconds(1), tp);

TimeProvider クラス自体は、.NET 8 より前のランタイムでも使えるようにできます。
(実際、Microsoft.Bcl.TimeProvider という NuGet パッケージが公式提供されています。)
以下のような書き方で、「なければ追加、あれば type forward」みたいなことができます。

#if NET8_0_OR_GREATER

using System;
using System.Runtime.CompilerServices;

[assembly: TypeForwardedTo(typeof(TimeProvider))]

#else

namespace System;

public class TimeProvider
{
    // 互換実装
}

#endif

インスタンス メソッドの追加風のことも、拡張メソッドでできました。

using System.Runtime.CompilerServices;

namespace System.Threading.Tasks;

public static class TaskExtensions
{
    // GetAwaiter メソッドがあると C# 5.0 の await が使える。
    public static TaskAwaiter GetAwaiter(this Task task)
    {
        // 今はインスタンス メソッドで GetAwaiter があるけど、
        // .NET Framework 4.0 以前はなかったので自作が必要。
        return task.GetAwaiter();
    }
}

ですが、先ほどの例に出てきた Task.Delay(TimeSpan, TimeProvider) は既存の型への静的メソッドの追加なので、
これまでの C# ではどうやってもできませんでした。

@ufcpp
Copy link
Owner Author

ufcpp commented Jul 14, 2024

13から外れた。
Unsafe.As 路線は JIT を混乱させて文字通り安全じゃないらしく、急遽路線変更。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant