C
C#16mo ago
Hugh

❔ ✅ Lifetime of variable referenced in Func<>

In some of my tests, I'm creating tables as I go, and then dropping the tables at the end of the test fixture. I'm doing this by having a RegisterType function that looks like this:
private readonly List<Func<Task>> _dropTableFunctions = new();

private async Task<bool> RegisterType<T>(Database database) where T : EntityBase, new()
{
async Task DropTableFunction()
{
await database.DropTable<T>();
}

_dropTableFunctions.Add(DropTableFunction);

return await database.RegisterEntityType<T>();
}
private readonly List<Func<Task>> _dropTableFunctions = new();

private async Task<bool> RegisterType<T>(Database database) where T : EntityBase, new()
{
async Task DropTableFunction()
{
await database.DropTable<T>();
}

_dropTableFunctions.Add(DropTableFunction);

return await database.RegisterEntityType<T>();
}
And then in my TearDown function, I iterate over _dropTableFunctions and call each one. My question here is not related to the database side of this, but is to ask whether I'm risking the Database objects having been destroyed by the time these functions are called? Are references from a function like this considered proper references to the variable, or should I also be storing reference to each database instance elsewhere to ensure that it is kept alive?
6 Replies
sibber
sibber16mo ago
the compiler will capture the local vars that you use in this case database so yes, they are "proper references"
Hugh
Hugh16mo ago
Good stuff - thanks. I wanted the check that I wasn't potentially introducing an intermittent failure here! Appreciate the clarification
Tvde1
Tvde116mo ago
Action M() {
int abc = 1 + 2;

void SomeMethod() {
Console.WriteLine(abc);
}

return SomeMethod;
}
Action M() {
int abc = 1 + 2;

void SomeMethod() {
Console.WriteLine(abc);
}

return SomeMethod;
}
is converted into
static Action M()
{
DisplayClass displayClass = new DisplayClass();
displayClass.abc = 3;
return new Action(displayClass.SomeMethod);
}

sealed class DisplayClass
{
public int abc;

internal void SomeMethod()
{
Console.WriteLine(abc);
}
}
static Action M()
{
DisplayClass displayClass = new DisplayClass();
displayClass.abc = 3;
return new Action(displayClass.SomeMethod);
}

sealed class DisplayClass
{
public int abc;

internal void SomeMethod()
{
Console.WriteLine(abc);
}
}
Hugh
Hugh16mo ago
👍
Accord
Accord16mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.