问题描述
我想知道这样的事情是否可能。我希望创建一个可以调用而不是 List.Add 的方法。该方法将检查任何/所有字符串属性并确保它们不超过其特定给定的最大长度,如果是,则截断为适当的大小。理想情况下,我希望它是通用的,这样它不仅适用于 ObjectA,还适用于 ObjectB、ObjectC 等。
我愿意接受任何和所有建议。我知道这似乎是一件很奇怪的事情,但是我正在使用许多不同的对象,并且可能在我的所有列表中总共有数百万个这些对象实例。我主要只需要一种方法来确保任何属性超过其最大字符串限制的对象都被及时截断并通过 Worker 类记录。谢谢!
public class ObjectA {
public Guid aID {get; set;}
[MaxLength(128)]
public string aName {get; set;}
[MaxLegnth(30)]
public string aType {get; set;}
}
--
public class Worker {
private void Work() {
List<ObjectA> listofA = new List<ObjectA>();
listofA.CustomAddMethod(new ObjectA(new Guid,"Something","UnkNown"));
}
// ??????
private CustomAddMethod(T object) {
foreach property {
if (isstringProperty && isGreaterThanMaxLength) {
// truncate to proper size
// log for truncation message
}
// Then add to list
}
}
}
解决方法
您可以创建扩展方法。
这是一个代码片段。您可以通过实现缓存来提高性能,例如使用字典存储属性和基于对象类型的 MaxLengthAttribute。
public static class ListExtensions
{
public static void CustomAdd<T>(this List<T> list,T item,Action<string> logger = null)
{
var propertyInfos = typeof(T)
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(propertyInfo => propertyInfo.PropertyType == typeof(string))
.ToList();
foreach (var propInfo in propertyInfos)
{
var maxLengthAttr = propInfo
.GetCustomAttributes(typeof(MaxLengthAttribute))
.Cast<MaxLengthAttribute>()
.FirstOrDefault();
if (maxLengthAttr is null)
continue;
var currentString = (string)propInfo.GetValue(item);
if (!maxLengthAttr.IsValid(currentString))
{
var newValue = currentString.Substring(0,maxLengthAttr.Length);
logger?.Invoke(
$"Resolving error: {maxLengthAttr.FormatErrorMessage(propInfo.Name)}\n" +
$"Old Value: {currentString}\n" +
$"New Value: {newValue}"
);
propInfo.SetValue(item,newValue);
}
}
list.Add(item);
}
}
使用示例(为简洁起见删除了代码):
public class Person
{
[MaxLength(4)]
public string Name { get; set; }
}
...
var personList = new List<Person>();
personList.CustomAdd(
new Person {Name = "John Doe"},message => Debug.WriteLine(message)
);
...
因此 Jhon Doe
字符串将被修剪为 Jhon