繁体   English   中英

在 C# 中到处声明内联变量(就像在声明不可行的基础构造函数调用中一样)

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

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

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实例——每次我需要在字符串中使用它的值时——但这只是浪费。

我通过创建一个通用的扩展方法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}'");

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

这个怎么样:

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM