在 C# 中的任何地方声明内联变量(比如在声明不可行的基础构造函数调用中)

Declare inline variables everywhere in C# (like in a base-constructor-call where declaring is not feasible)

有些地方你不能像在基础构造函数调用中那样声明新变量(惊呼:这是一个展示问题的例子):

public class SportLicense : BaseEntity<SportLicense>
{
    public SportLicense() : base(
        tableName: new SportLicenseNames().EntityName,
        recordIdFieldName: new SportLicenseNames().RecordIdFieldName)
        { } 
}

最好将 SportLicenseNames 的实例声明为内联以避免创建多个实例。有时它只是为了优化性能,但我经常需要同一个实例第二次和第三次用于基本构造函数的另一个参数。

有几个类似的场景,在表达式中声明一个变量会很好地避免创建方法体(Exclaimer:这是一个展示问题的例子) :

public static TEntity ThrowIfNull<TEntity, TId>(this TEntity entity, TId recordId)
where TEntity : Entity, new()
{
    if (entity != null) return entity;
    var e = new TEntity();
    throw new($"Record not found in table '{e.EntityName}' with id '{recordId}'\r\nSELECT * FROM {e.EntityName} WHERE {e.GetPrimaryKeyColumn().Name} = '{recordId}'");
}

如果不是变量 e 我可以只使用表达式主体。当然,我可以创建另一个 TEntity 的实例 - 每次我需要它在字符串中的值时 - 但那只是浪费。

我通过创建一个通用的 extension-method Var 解决了这个问题,如下所示:

public static TObject Var<TObject>(this TObject obj, out TObject varName) => varName = obj;

这让我可以像这样解决 base-constructor-call 的第一个问题:

public class SportLicense : BaseEntity<SportLicense>
{
    public SportLicense() : base(
        tableName: new SportLicenseNames().Var(out var sportLicenseNames).EntityName,
        recordIdFieldName: sportLicenseNames.RecordIdFieldName)
        { } 
}

第二个场景可以写得更短而不影响实例数量的增加:

public static TEntity ThrowIfNull<TEntity, TId>(this TEntity entity, TId recordId)
    where TEntity : Entity, new()
    =>
        entity ??
        throw new(
            $"Record not found in table '{new TEntity().Var(out var e).EntityName.Var(out var eName)}' with id '{recordId}'\r\nSELECT * FROM {eName} WHERE {e.GetPrimaryKeyColumn().Name} = '{recordId}'");

通过这种方法,我通常可以优化性能(重用创建的 property-values 等),而不必先编写大量代码来声明变量等。

这个怎么样:

public class SportLicense : BaseEntity<SportLicense>
{
    public SportLicense() : this(new SportLicenseNames()) { }

    private SportLicense(SportLicenseNames licenseNames) : base(
        tableName: licenseNames.EntityName,
        recordIdFieldName: licenseNames.RecordIdFieldName)
    { }
}

只创建了一个SportLicenseNames实例,不需要扩展方法、out变量等