You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#类能否将自身类型作为泛型类型引用?

Can a C# class reference its own type as a generic type parameter?

Absolutely! This is not only allowed in C# but also an incredibly common pattern—especially useful for scenarios like your builder pattern, where you want to enable fluent, type-safe chaining of methods.

You’ve already got a working builder, but referencing the class itself as a generic parameter (often called the Curiously Recurring Template Pattern, or CRTP) solves a big pain point: if you ever create a subclass of your builder, you won’t lose access to subclass-specific methods when chaining calls.

Let’s adapt your existing builder to use this pattern:

public class MyBuilderClass<TBuilder> where TBuilder : MyBuilderClass<TBuilder>
{
    protected MyConcreteType entity;

    public MyBuilderClass()
    {
        entity = new MyConcreteType();
    }

    public TBuilder With<TProperty>(Expression<Func<MyConcreteType, TProperty>> propertyExpression, TProperty value)
    {
        // Extract the property from the expression and set its value
        var memberExpression = (MemberExpression)propertyExpression.Body;
        var propertyInfo = (PropertyInfo)memberExpression.Member;
        propertyInfo.SetValue(entity, value);

        // Return the current instance as the generic builder type
        return (TBuilder)this;
    }

    public MyConcreteType Build()
    {
        return entity;
    }
}

And if you need a specialized builder with extra methods, this pattern still works seamlessly:

public class MyEnhancedBuilder : MyBuilderClass<MyEnhancedBuilder>
{
    public MyEnhancedBuilder WithSpecialFlag(bool flagValue)
    {
        // Assume MyConcreteType has a SpecialFlag property
        entity.SpecialFlag = flagValue;
        return this;
    }
}

Now you can chain methods without losing type safety:

var myInstance = new MyEnhancedBuilder()
    .With(x => x.Name, "Test")
    .WithSpecialFlag(true) // No cast needed here!
    .Build();

Without this pattern, calling With() on your subclass builder would return the base MyBuilderClass type, forcing you to cast if you wanted to call subclass methods next—messy and error-prone.

This approach is used all over .NET libraries (like EF Core’s Fluent API configuration) because it keeps code clean and maintains type safety throughout the chain.

内容的提问来源于stack exchange,提问作者SeanKilleen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:31:42