无论如何要删除 C# class 属性的重复?
Anyway to remove repetition for C# class properties?
我有一个 class 这样的:
public class DbSettingsValues : Dictionary<string, string>
{
public DbSettingsValues() { }
public DbSettingsValues(Dictionary<string, string> values) : base(values) { }
public string EmailApiServer
{
get => this.GetValueOrDefault(DbSettingsKeys.EmailApiServer, "");
set => this[DbSettingsKeys.EmailApiServer] = value;
}
public string EmailApiKey
{
get => this.GetValueOrDefault(DbSettingsKeys.EmailApiKey, "");
set => this[DbSettingsKeys.EmailApiKey] = value;
}
// about 15 more...
// There is also a few difference, like this one:
public int RegisterFirstEmailDelay
{
get => int.Parse(this.GetValueOrDefault(DbSettingsKeys.RegisterFirstEmailDelay, "24"));
set => this[DbSettingsKeys.RegisterFirstEmailDelay] = value.ToString();
}
}
所以对于每个 属性 我需要输入准确的名字 3 次。我知道这对以后的维护不利,并且当我通过复制创建更多属性时容易出错(即忘记替换 3 个位置中的 1 个名称)。
有没有更好的方法来处理这个问题?我想到了一些解决方案:
有点像旧的 T4,我在 VS2022 中看不到 T4 菜单了,所以我认为它在 .NET Core 上不起作用?
代码生成器似乎需要外部项目。我假设这就是 EF Core 脚手架的工作原理?有人可以建议 keyword/link 我应该寻找什么吗? IE。读取 C# 项目,在 class 中查找属性并相应地生成 .cs
文件?
就目前的规格而言,关键文本是一样的:
public const string EmailApiServer = nameof(EmailApiServer);
public const string EmailApiKey = nameof(EmailApiKey);
// ...
所以从技术上讲,我可以将 DbSettingsKeys.EmailApiServer
替换为 nameof(EmailApiServer)
,但我不确定它以后会保持不变。现在就着手进行,等规格发生变化后再考虑是否是个好主意?
更新:我刚刚意识到即使使用 nameof(PropertyName)
,它仍然容易出现复制问题,因为如果我忘记更改名称也不会出错:
// No error here because the name is valid
public string EmailApiKey
{
get => this.GetValueOrDefault(nameof(EmailApiServer), "");
set => this[nameof(EmailApiServer)] = value;
}
我认为 CallerMemberNameAttribute
之类的东西可能有用,但实际上我不知道它是如何工作的。
如果键确实与属性同名,您确实可以使用 [CallerMemberName]
属性来减少必须键入 属性 名称的次数。
例如:
public class DbSettingsValues : Dictionary<string, string>
{
public string EmailApiServer
{
get => getProperty();
set => setProperty(value);
}
public string EmailApiKey
{
get => getProperty();
set => setProperty(value);
}
public int RegisterFirstEmailDelay
{
get => getProperty(24);
set => setProperty(value);
}
string getProperty(string defaultValue = "", [CallerMemberName] string? propName = default)
{
return this!.GetValueOrDefault(propName, defaultValue);
}
T getProperty<T>(T defaultValue, [CallerMemberName] string? propName = default)
{
var result = this!.GetValueOrDefault(propName, defaultValue!.ToString());
return (T) Convert.ChangeType(result, typeof(T))!;
}
void setProperty(string value, [CallerMemberName] string? propName = default)
{
this[propName!] = value;
}
void setProperty<T>(T value, [CallerMemberName] string? propName = default)
{
this[propName!] = value!.ToString()!;
}
}
它并不完美,但确实显着降低了打字错误的几率。
我有一个 class 这样的:
public class DbSettingsValues : Dictionary<string, string>
{
public DbSettingsValues() { }
public DbSettingsValues(Dictionary<string, string> values) : base(values) { }
public string EmailApiServer
{
get => this.GetValueOrDefault(DbSettingsKeys.EmailApiServer, "");
set => this[DbSettingsKeys.EmailApiServer] = value;
}
public string EmailApiKey
{
get => this.GetValueOrDefault(DbSettingsKeys.EmailApiKey, "");
set => this[DbSettingsKeys.EmailApiKey] = value;
}
// about 15 more...
// There is also a few difference, like this one:
public int RegisterFirstEmailDelay
{
get => int.Parse(this.GetValueOrDefault(DbSettingsKeys.RegisterFirstEmailDelay, "24"));
set => this[DbSettingsKeys.RegisterFirstEmailDelay] = value.ToString();
}
}
所以对于每个 属性 我需要输入准确的名字 3 次。我知道这对以后的维护不利,并且当我通过复制创建更多属性时容易出错(即忘记替换 3 个位置中的 1 个名称)。
有没有更好的方法来处理这个问题?我想到了一些解决方案:
有点像旧的 T4,我在 VS2022 中看不到 T4 菜单了,所以我认为它在 .NET Core 上不起作用?
代码生成器似乎需要外部项目。我假设这就是 EF Core 脚手架的工作原理?有人可以建议 keyword/link 我应该寻找什么吗? IE。读取 C# 项目,在 class 中查找属性并相应地生成
.cs
文件?
就目前的规格而言,关键文本是一样的:
public const string EmailApiServer = nameof(EmailApiServer);
public const string EmailApiKey = nameof(EmailApiKey);
// ...
所以从技术上讲,我可以将 DbSettingsKeys.EmailApiServer
替换为 nameof(EmailApiServer)
,但我不确定它以后会保持不变。现在就着手进行,等规格发生变化后再考虑是否是个好主意?
更新:我刚刚意识到即使使用 nameof(PropertyName)
,它仍然容易出现复制问题,因为如果我忘记更改名称也不会出错:
// No error here because the name is valid
public string EmailApiKey
{
get => this.GetValueOrDefault(nameof(EmailApiServer), "");
set => this[nameof(EmailApiServer)] = value;
}
我认为 CallerMemberNameAttribute
之类的东西可能有用,但实际上我不知道它是如何工作的。
如果键确实与属性同名,您确实可以使用 [CallerMemberName]
属性来减少必须键入 属性 名称的次数。
例如:
public class DbSettingsValues : Dictionary<string, string>
{
public string EmailApiServer
{
get => getProperty();
set => setProperty(value);
}
public string EmailApiKey
{
get => getProperty();
set => setProperty(value);
}
public int RegisterFirstEmailDelay
{
get => getProperty(24);
set => setProperty(value);
}
string getProperty(string defaultValue = "", [CallerMemberName] string? propName = default)
{
return this!.GetValueOrDefault(propName, defaultValue);
}
T getProperty<T>(T defaultValue, [CallerMemberName] string? propName = default)
{
var result = this!.GetValueOrDefault(propName, defaultValue!.ToString());
return (T) Convert.ChangeType(result, typeof(T))!;
}
void setProperty(string value, [CallerMemberName] string? propName = default)
{
this[propName!] = value;
}
void setProperty<T>(T value, [CallerMemberName] string? propName = default)
{
this[propName!] = value!.ToString()!;
}
}
它并不完美,但确实显着降低了打字错误的几率。