Reputation: 8792
I'm building a user management system, with a domain host to which I am sending commands. The commands are record
s both because of the init
-only properties and because of the generated helper methods. However, I quickly ran into a problem with this approach for e.g. the LoginUserCommand
.
command.ToString()
returns something like this (formatting added):
LoginUserCommand {
Identity = 10000000-1111-2222-3333-444444444444,
CorrelationId = 20000000-1111-2222-3333-444444444444,
Timestamp = 2013-07-26T16:45:20Z,
IssuingUserId = 30000000-1111-2222-3333-444444444444,
EntityId = a80c081c-cf91-4304-9baa-20fb20c8d9f7,
IPAddress = 127.0.0.1,
Password = ThisIsAPr0blem
}
Obviously I can work around this by e.g. overriding ToString()
on the classes where it matters. Naïvely, I might do something like
public override string ToString()
{
return base.ToString()
.Replace(Password, "********");
}
But I'm wondering whether I've overlooked some built-in way to have the generated ToString()
method mask the value of the Password
property.
Upvotes: 13
Views: 1939
Reputation: 2299
You can isolate sensitive properties in derived class and override PrintMembers
.
var s = new Entity("ss11", 99, "supersecret");
Console.WriteLine(s);
Console.WriteLine(s.secret);
// Output:
// EntityWithSecret { s1 = ss11, i2 = 99 }
// supersecret
public record EntityNoSecret(string s1, int i2);
public record Entity(string s1, int i2, string secret) : EntityNoSecret(s1, i2)
{
protected override bool PrintMembers(StringBuilder builder)
=> base.PrintMembers(builder);
};
Upvotes: 2
Reputation: 1625
You can remap your record with the with
syntax and use PrintMembers
instead, which I think is cleaner:
public override string ToString()
{
var builder = new StringBuilder();
(this with { Password = null }).PrintMembers(builder);
return builder.ToString();
}
There have also been proposals for introducing an attribute such as [PrintMembersIgnore]
for records, but nothing like it has been implemented. It can however be solved with code generation, which was the method suggested by the dotnet team (see comment in the thread), a project for this has been started.
Upvotes: 18