C#隐式运算符不处理反射
我正在处理一个需要检查ASP.NET模型属性值000000的需求。如果该值为000000,则应显示为空白字符串。 我想用隐式操作符来实现这一点。 这是我的模型课C#隐式运算符不处理反射,c#,asp.net-web-api,reflection,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) {
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;
}
}
有人能帮我解决这个问题吗?
我也愿意接受其他实现这一目标的建议
谢谢你可以把代码放在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;
}
}
}
}
这可能是对您的问题的间接解决方案,因为现在您的代码有一个缺陷 例如,
a0000a0b0
将被检测为isAllZeros
进一步解释代码中的问题到底是什么
首先让我们看一看这行:
bool isAllZeros = value.Where(x => char.IsDigit(x)).All(x => x == '0');
您要做的第一件事是获取值
并在其上执行Where
。其中
要传递的条件是每个值(x
)都是一个数字。这意味着将跳过任何非数字字符,例如a
、b
、c
与您可能对Where
的解释相反,它只是过滤掉任何与条件不匹配的值
这意味着在您的案例中不是数字的值将不会通过,因此当枚举命中All
时,它将只枚举数字字符
您的代码基本上等同于说英语的人:
'0'
。char.IsDigit
检查是多余的bool isAllZeros = value.All(x => x == '0');
如果值
为空,您可能需要进行空检查
bool isAllZeros = value?.All(x => x == '0') ?? false;
以防你不使用C#6
我看不到这里有任何倒影。你能添加那个代码吗?顺便说一句,你的代码有一个缺陷。字符串
a0000a0b0
将被检测为isAllZeros
。我不明白为什么这个问题被否决。我的意思是,Priyank做了一些研究,提供了代码等等。目标也被清楚地描述了,尽管代码和问题有点矛盾,但我不明白为什么会投反对票。@HenkHolterman用我对缺陷的解释给出了一个答案:)您试图在反射代码中调用转换运算符的确切位置?我在这里没有提到“op_Implicit”或“op_Explicit”。甚至可能在getter中也没有提到。如果目标是找到一个值
都是零,那么这也可以做到:设置{u value=value.Trim(“0”).Length>0?value:string.Empty;}
@Heki yes目标是检查值是否全部为零,然后应将其显示为空白字符串。
bool isAllZeros = string.IsNullOrEmpty(value) ? false : value.All(x => x == '0');