简体   繁体   中英

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

There are places where you can not declare new variables like in a base-constructor call ( Exclaimer: this is an example to show-case the problem ):

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

It would be nice to declare the instance of SportLicenseNames inline to avoid creating multiple instance. Sometimes it's just about optimizing performance, but often I do need the same instance a second and third time for another parameter of the base-constructor.

There are several similar scenarios where declaring a variable within an expression would be nice to avoid creating a method body ( Exclaimer: this is an example to show-case the problem ):

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}'");
}

If it wasn't for the variable e i could just use an expression-body. Sure I could have created another Instance of TEntity - every time I needed a value of it in the string - but that'd just be wasteful.

I solved this issue by creating a generic extension-method Var like this:

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

This allows me to solve the first issue with the base-constructor-call like this:

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

And the second scenario can be written much shorter without compromising on multiplying the number of instances:

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}'");

With that approach I can often optimize performance (reusing created property-values etc.) without having to write a lot of code with declaring variables first etc.

How about this:

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

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

Only one instance of SportLicenseNames is created and no need for extension methods, out variables etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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