我有一个名为 Part
的基类和 Wire
或 Connector
等派生类,还有许多继承自 Part
.
现在我想实现一个搜索功能,在派生类的所有属性中搜索一个字符串。
如有必要,应尝试将该字符串转换为属性的类型。 Properties也可以是List,应该在第一层搜索。
class Part
{
public int Id { get; set; }
public string Name { get; set; }
}
class Wire : Part
{
public NumberWithUnit Diameter { get; set; }
public Weight Weight { get; set; }
}
class Connector : Part
{
public List<Part> ConnectedParts { get; set; }
}
我知道如何像这样使用反射来搜索基本类型的属性
private bool SearchProperties<T>(T part, string searchString) where T : Part
{
var props = typeof(T).GetProperties();
foreach (var prop in props)
{
var value = prop.GetValue(part);
if (value is string)
{
if (string.Equals(value, searchString))
return true;
}
else if (value is int)
{
int v;
if (int.TryParse(searchString, out v))
{
if(v == (int) value)
return true;
}
}
}
return false;
}
但这会是一个很长的类型列表,我有 Weight
类型的属性,例如等等。是否有某种通用的搜索方式而无需强制转换所有类型?
最佳答案
考虑向相反的方向进行转化。无需将搜索字符串转换为每个可能的值,只需将值转换为字符串即可:
private bool SearchProperties<T>(T part, string searchString) where T : Part
{
var props = typeof(T).GetProperties();
foreach (var prop in props)
{
var value = prop.GetValue(part);
if (value is IEnumerable)
{
// special handling for collections
}
else if(value != null)
{
string valueString = value.ToString();
if (string.Equals(valueString, searchString))
return true;
}
}
return false;
}
除了对大多数内置类型工作得很好之外,要让它对 Weight
等工作,你唯一需要做的就是确保它们实现了 ToString()
.
另一种解决方案是使用 TypeDescriptor:
private bool SearchProperties<T>(T part, string searchString) where T : Part
{
var props = typeof(T).GetProperties();
foreach (var prop in props)
{
var value = prop.GetValue(part);
if (value is IEnumerable)
{
// special handling for collections
}
else if(value != null)
{
object searchValue = null;
try
{
searchValue = TypeDescriptor.GetConverter(value).ConvertFromString(searchString);
} catch {}
if (searchValue != null && object.Equals(value, searchValue))
return true;
}
}
return false;
}
TypeDescriptor 适用于大多数内置类型,但 requires extra work如果您正在处理自定义类型。
关于c# - 如何搜索各种类型的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32974496/