C#隐式运算符不使用反射

时间:2017-01-10 07:52:51

标签: c# asp.net-web-api reflection

我正在处理一个要求,我需要在我的ASP.NET模型属性中检查值000000.如果值为000000,则应显示为空字符串。 我想过使用隐式运算符实现这一点。 这是我的模型类

public class OrgName
        {
            private string Value { get; set; }

            public static implicit operator string(OrgName org)
            {
                return org.Value;
            }

            public static implicit operator OrgName(string value)
            {
                bool isAllZeros = value.Where(x => char.IsDigit(x)).All(x => x == '0');
                if (isAllZeros)
                    value = string.Empty;
                return new OrgName() { Value = value };
            }

        }

问题是我们使用反射来设置属性值。上面的代码不起作用,属性总是显示为空白。

这是反射代码

var prName = (String.IsNullOrWhiteSpace(parentPrefix) ? objKey : parentPrefix + '.' + objKey);
                    var pi = modelMap[prName.ToLowerInvariant()].Property;

                var value = (collectionProperties.ContainsKey(objKey)) ? collectionProperties[objKey] : pi.GetValue(parentObj);

                if (value == null || pi.PropertyType.IsSimpleType())
                {
                    value = (prName == fieldToSet && pi.PropertyType.IsSimpleType())
                        ? (Convert.IsDBNull(valueToSet)) ? null : valueToSet
                        : createObject(pi.PropertyType);

                    var type = Nullable.GetUnderlyingType(pi.PropertyType);

                    //check to see if we need to convert the type when assigning

                    if (type == typeof(Guid))
                        value = Guid.Parse(value.ToString());

                    pi.SetValue(parentObj, type != null ? Convert.ChangeType(value, type) : value);

                    if (pi.PropertyType != typeof(string) && IsContainerProperty(pi.PropertyType))
                        continue;
                    if (pi.PropertyType == typeToReturn)
                        objToLoad = value;

                }
                else if (!collectionProperties.ContainsKey(objKey) && IsContainerProperty(pi.PropertyType))
                {
                    var innerType = pi.PropertyType.GetGenericArguments()[0];
                    var add = pi.PropertyType.GetMethod("Add",
                            BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public);


                    if (innerType.IsSimpleType())
                    {
                        collectionProperties[objKey] = valueToSet;
                        add.Invoke(value, new[] { valueToSet });

                    }
                    else
                    {
                        // Since we can't access the property 
                        var innerObj = createObject(innerType);
                        collectionProperties[objKey] = innerObj;
                        add.Invoke(value, new[] { innerObj });
                        if (innerType == typeToReturn)
                            objToLoad = innerObj;
                        continue;
                    }
                }

有人可以帮我解决这个问题吗? 我也愿意接受其他建议来实现这一目标。

由于

2 个答案:

答案 0 :(得分:1)

你可以把代码放在setter中吗?

public class OrgName
{
    private string _value;
    private string Value
    {
        get { return _value; }
        set
        {
            bool isAllZeros = value?.All(x => x == '0') ?? false;
            if(isAllZeros)
            {
                _value = string.Empty;
            }
            else
            {
                _value = value;
            }
        }
    }

}

答案 1 :(得分:1)

这可能是您问题的间接解决方案,因为您的代码现在存在缺陷。

实施例。 a0000a0b0将被检测为isAllZeros

进一步解释代码中的问题究竟是什么。

首先让我们来看看这一行:

bool isAllZeros = value.Where(x => char.IsDigit(x)).All(x => x == '0');

您要做的第一件事就是value并在其上执行Wherewhere传递的条件是每个值(x)都是一个数字。这意味着将跳过任何非数字字符,例如abc

与您解释Where的内容相反,它只是过滤掉与条件不匹配的任何值。

这意味着您的案例中不是数字的值将不会通过,因此当枚举点击All时,它只会枚举数字字符。

您的代码基本上与英语口语相同:

  1. 取值
  2. 跳过所有非数字字符
  3. 检查所有数字字符是否为0
  4. 您希望代码实际执行的操作是:

    1. 取值
    2. 检查所有字符是否为数字和0.在这种情况下,您实际上只需要检查字符是否为'0'char.IsDigit检查是多余的。
    3. 这可以通过这样解决:

      bool isAllZeros = value.All(x => x == '0');
      

      您可能希望在value为空的情况下进行空检查。

      bool isAllZeros = value?.All(x => x == '0') ?? false;
      

      如果您不使用C#6

      bool isAllZeros = string.IsNullOrEmpty(value) ? false : value.All(x => x == '0');