遍历对象自己的字符串和字符串修剪每个

发布于 2024-09-09 03:27:53 字数 227 浏览 10 评论 0原文

我有多个大对象,每个对象都有大约 60 个字符串。我必须修剪所有这些字符串,并且我想这样做而不必去 this.mystring = this.mystring.Trim()。相反,我正在寻找一种方法来自动让每个对象发现自己的字符串,然后执行操作。

我对反射了解一点,但还不够,但我认为这可能吗?

另外,我不确定这是否重要,但某些字符串属性是只读的(只有吸气剂),因此必须跳过这些属性。

帮助?

I have multiple large objects which each have about 60 strings. I have to trim all those strings, and I'd like to do so without having to go this.mystring = this.mystring.Trim(). Instead, I'm looking for a way to automatically have each object discover its own strings and then perform the operation.

I know a little bit about reflection, but not enough, but I think this is possible?

Also, I'm not sure if this matters, but some string properties are read-only (only have a getter), so those properties would have to be skipped.

Help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

久随 2024-09-16 03:27:53

嗯,获取所有属性并找出哪些是字符串且可写是很容易的。 LINQ 使其变得更加容易。

var props = instance.GetType()
                    .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                    // Ignore non-string properties
                    .Where(prop => prop.PropertyType == typeof(string))
                    // Ignore indexers
                    .Where(prop => prop.GetIndexParameters().Length == 0)
                    // Must be both readable and writable
                    .Where(prop => prop.CanWrite && prop.CanRead);

foreach (PropertyInfo prop in props)
{
    string value = (string) prop.GetValue(instance, null);
    if (value != null)
    {
        value = value.Trim();
        prop.SetValue(instance, value, null);
    }
}

您可能只想在修剪确实产生影响的情况下设置属性,以避免复杂属性的冗余计算 - 或者这对您来说可能不是问题。

如果需要,有多种方法可以提高性能 - 例如:

  • 简单地缓存每种类型的相关属性
  • 使用 Delegate.CreateDelegate 为 getter 和 setter 构建委托
  • 可能使用表达式树,尽管我是不确定他们是否会在这里提供帮助,

除非性能实际上是一个问题,否则我不会采取任何这些步骤。

Well, it's easy enough to get all the properties, and find out which ones are strings and writable. LINQ makes it even easier.

var props = instance.GetType()
                    .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                    // Ignore non-string properties
                    .Where(prop => prop.PropertyType == typeof(string))
                    // Ignore indexers
                    .Where(prop => prop.GetIndexParameters().Length == 0)
                    // Must be both readable and writable
                    .Where(prop => prop.CanWrite && prop.CanRead);

foreach (PropertyInfo prop in props)
{
    string value = (string) prop.GetValue(instance, null);
    if (value != null)
    {
        value = value.Trim();
        prop.SetValue(instance, value, null);
    }
}

You may want to only set the property if trimming actually makes a difference, to avoid redundant computations for complex properties - or it may not be an issue for you.

There are various ways of improving the performance if necessary - things like:

  • Simply caching the relevant properties for each type
  • Using Delegate.CreateDelegate to build delegates for the getters and setters
  • Possibly using expression trees, although I'm not sure whether they'd help here

I wouldn't take any of those steps unless performance is actually a problem though.

清晨说晚安 2024-09-16 03:27:53

像这样的东西:

    foreach (PropertyInfo prop in obj.GetType().GetProperties(
        BindingFlags.Instance | BindingFlags.Public))
    {
        if (prop.CanRead && prop.CanWrite && prop.PropertyType == typeof(string)
            && (prop.GetIndexParameters().Length == 0)) // watch for indexers!
        {
            var s = (string)prop.GetValue(obj, null);
            if (!string.IsNullOrEmpty(s)) s = s.Trim();
            prop.SetValue(obj, s, null);
        }
    }

Something like:

    foreach (PropertyInfo prop in obj.GetType().GetProperties(
        BindingFlags.Instance | BindingFlags.Public))
    {
        if (prop.CanRead && prop.CanWrite && prop.PropertyType == typeof(string)
            && (prop.GetIndexParameters().Length == 0)) // watch for indexers!
        {
            var s = (string)prop.GetValue(obj, null);
            if (!string.IsNullOrEmpty(s)) s = s.Trim();
            prop.SetValue(obj, s, null);
        }
    }
小镇女孩 2024-09-16 03:27:53

无需在 props-loop 中进行 IEnumerable 检查,如果实际实例是 IEnumerable,则忽略 props。修复 IEnumerable 部分:

private void TrimWhitespace(object instance)
{
    if (instance != null)
    {
        if (instance is IEnumerable)
        {
            foreach (var item in (IEnumerable)instance)
            {
                TrimWhitespace(item);
            }
        }

        var props = instance.GetType()
                .GetProperties(BindingFlags.Instance | BindingFlags.Public)
            // Ignore indexers
                .Where(prop => prop.GetIndexParameters().Length == 0)
            // Must be both readable and writable
                .Where(prop => prop.CanWrite && prop.CanRead);

        foreach (PropertyInfo prop in props)
        {
            if (prop.GetValue(instance, null) is string)
            {
                string value = (string)prop.GetValue(instance, null);
                if (value != null)
                {
                    value = value.Trim();
                    prop.SetValue(instance, value, null);
                }
            }
            else 
                TrimWhitespace(prop.GetValue(instance, null));
        }
    }
}

Not necessary to make IEnumerable check in the props-loop and if actual instance is a IEnumerable, props are ignored. Fix for IEnumerable part:

private void TrimWhitespace(object instance)
{
    if (instance != null)
    {
        if (instance is IEnumerable)
        {
            foreach (var item in (IEnumerable)instance)
            {
                TrimWhitespace(item);
            }
        }

        var props = instance.GetType()
                .GetProperties(BindingFlags.Instance | BindingFlags.Public)
            // Ignore indexers
                .Where(prop => prop.GetIndexParameters().Length == 0)
            // Must be both readable and writable
                .Where(prop => prop.CanWrite && prop.CanRead);

        foreach (PropertyInfo prop in props)
        {
            if (prop.GetValue(instance, null) is string)
            {
                string value = (string)prop.GetValue(instance, null);
                if (value != null)
                {
                    value = value.Trim();
                    prop.SetValue(instance, value, null);
                }
            }
            else 
                TrimWhitespace(prop.GetValue(instance, null));
        }
    }
}
何处潇湘 2024-09-16 03:27:53

因此,为了稍微扩展一下,我有一个带有列表列表的复杂对象,我想遍历它并修剪所有子字符串对象。我正在发布我在 @Jon 在他的回答中所做的事情。我很好奇是否有更好的方法,或者我是否错过了一些明显的事情。

我拥有的对象比这更复杂,但它应该说明我正在尝试的内容。

public class Customer
{
  public string Name { get; set; }
  public List<Contact> Contacts { get; set; }
}

public class Contact
{
  public string Name { get; set; }
  public List<Email> EmailAddresses {get; set;}
}

public class Email
{
  public string EmailAddress {get; set;}
}


    private void TrimWhitespace(object instance)
    {
        if (instance != null)
        {
            var props = instance.GetType()
                    .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                // Ignore indexers
                    .Where(prop => prop.GetIndexParameters().Length == 0)
                // Must be both readable and writable
                    .Where(prop => prop.CanWrite && prop.CanRead);

            foreach (PropertyInfo prop in props)
            {
                if (instance is IEnumerable)
                {
                    foreach (var item in (IEnumerable)instance)
                    {
                        TrimWhitespace(item);
                    }
                }
                else if (prop.GetValue(instance, null) is string)
                {
                    string value = (string)prop.GetValue(instance, null);
                    if (value != null)
                    {
                        value = value.Trim();
                        prop.SetValue(instance, value, null);
                    }
                }
                else 
                    TrimWhitespace(prop.GetValue(instance, null));
            }
        }
    }

想法?

So to expand on this a little, I have a complex object with Lists of Lists and I wanted to traverse that and trim all of the child string objects as well. I'm posting what I did as of what I built on from @Jon did in his answer. I'm curious if there was a better way to do it or if I missed something obvious.

The objects I have are more complex than this but it should illustrate what I was trying.

public class Customer
{
  public string Name { get; set; }
  public List<Contact> Contacts { get; set; }
}

public class Contact
{
  public string Name { get; set; }
  public List<Email> EmailAddresses {get; set;}
}

public class Email
{
  public string EmailAddress {get; set;}
}


    private void TrimWhitespace(object instance)
    {
        if (instance != null)
        {
            var props = instance.GetType()
                    .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                // Ignore indexers
                    .Where(prop => prop.GetIndexParameters().Length == 0)
                // Must be both readable and writable
                    .Where(prop => prop.CanWrite && prop.CanRead);

            foreach (PropertyInfo prop in props)
            {
                if (instance is IEnumerable)
                {
                    foreach (var item in (IEnumerable)instance)
                    {
                        TrimWhitespace(item);
                    }
                }
                else if (prop.GetValue(instance, null) is string)
                {
                    string value = (string)prop.GetValue(instance, null);
                    if (value != null)
                    {
                        value = value.Trim();
                        prop.SetValue(instance, value, null);
                    }
                }
                else 
                    TrimWhitespace(prop.GetValue(instance, null));
            }
        }
    }

Thoughts?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文