我对我正在编写的通用帮助程序类进行了简单的类型检查。如果你看一下源代码,这个想法就会很清楚。它适用于普通的东西,比如DateTime和bool,但我遇到了泛型问题。
如何查看例如ObservableCollection< 某事>并计算它。我不希望能够渲染所有东西(毕竟它是一个调试控件),但是如果有一个集合,我想知道它是否有元素。
尝试了一些变化,但都没有奏效。不能那么难,搜索词只是吮吸(通用,列表,收藏) - 所有不是很友好的谷歌: - )
[编辑]
好吧,我玩了一下,我靠近了。但是GetValue()函数存在一个奇怪的问题。如果你看一下示例类,一个字符串属性工作正常,构造函数中设置的那个显示“NULL” - 怎么会这样。哦,顺便问一下。我在Windows Phone 7中工作 - 但这应该不会影响这些基本的东西,是吗?
[结束编辑]
我的功能的更新版本:
private static FrameworkElement CreateContent(System.Reflection.PropertyInfo propertyInfo, object parent)
{
var propValue = propertyInfo.GetValue(parent, null);
// NULL
if (propValue == null) return new TextBlock() { Text = "NULL" };
// Simple cases
if (propertyInfo.PropertyType == typeof(int))
return new TextBlock() { Text = propValue.ToString() };
if (propertyInfo.PropertyType == typeof(DateTime))
return new TextBlock() { Text = ((DateTime)propValue).ToShortTimeString() };
if (propertyInfo.PropertyType == typeof(string))
return new TextBlock() { Text = propValue.ToString() };
// More exotic cases
if (typeof(IList).IsAssignableFrom(propValue.GetType()))
return new TextBlock() {Text = ((IList) propValue).Count.ToString()};
if (typeof(ICollection).IsAssignableFrom(propValue.GetType()))
return new TextBlock() { Text = ((ICollection)propValue).Count.ToString() };
if (typeof(IEnumerable).IsAssignableFrom(propValue.GetType()))
return new TextBlock() { Text = ((IEnumerable)propValue).Cast<object>().Count().ToString() };
// If all fails, at least tell me the type
return new TextBlock() {Text = propertyInfo.PropertyType.Name};
}
非常奇怪的测试用例(查找StringPropertyA和B)
public class DebugService : ServiceBase, IDebugService
{
public DebugService(IUnityContainerPhone container) : base(container)
{
DateTimeProperty = DateTime.Now;
StringEmptyProperty = "";
StringObsColl = new ObservableCollection<string>() {"A", "B", "C"};
StringList = new List<string>(){"X", "Y", "Z"};
StringPropertyB = "Will not show up";
}
public override string Description
{
get { return "Does nothing, for debug purposes"; }
}
public DateTime DateTimeProperty { get; private set; }
public int IntProperty { get { return 23; } }
public string StringPropertyA { get {return "Is OK";} }
public string StringPropertyB { get; private set; }
public string StringEmptyProperty { get; private set; }
public string StringNullProperty { get; private set; }
public ObservableCollection<string> StringObsColl { get; private set; }
public IList<string> StringList { get; private set; }
}
答案 0 :(得分:1)
是否有必要走这条路?
if (parent is DateTime)
return new TextBlock() { Text = ((DateTime)parent).ToShortTimeString() };
if (parent is ICollection)
return new TextBlock() { Text = ((ICollection)parent).Count };
if (parent is IEnumerable)
return new TextBlock() { Text = ((IEnumerable)parent).Count() }; //assumes System.Linq
...
return new TextBlock() { Text = parent.ToString() };
答案 1 :(得分:1)
propertyInfo.PropertyType.IsAssignableFrom(typeof(IList))
这是一个经典错误(我认为它因value is IList
语法而很常见)。你真正想要的是:
typeof(IList).IsAssignableFrom(propertyInfo.PropertyType)
还有其他问题需要考虑,例如是否要支持其他类型的集合(并非所有集合都将实现IList。)如果您特别想要将值作为泛型集合访问,那么这是一个有用的提示是你可以使用typeof(IList<>)
获取非专业泛型类型。
答案 2 :(得分:0)
我认为你的IsAssignable从方法调用了。我想你需要说typeof(IList).IsAssignableFrom(propertyInfo.PropertyType)
无论如何,我会直接检索对象并对其进行反思,而不是反映属性的类型。这样,如果你有一个object类型的属性,它返回一个列表,它将在你的调试控件中正确显示。
private static FrameworkElement CreateContent(System.Reflection.PropertyInfo propertyInfo, object parent)
{
object propValue = propertyInfo.GetValue(parent, null);
if (propValue is ICollection)
return new TextBlock() { Text = ((ICollection)propValue).Count.ToString() };
else if (propValue is ...)
return new TextBlock() { Text = ... };
else
return new TextBlock() { Text = propValue.ToString() };
}