C# 迭代索引属性(反射)
我想对一个只有通过反射才能访问的索引属性进行排序 但是(我这么说是因为我完全知道可能有一个令人尴尬的简单答案,MSDN/Google fail=/)在抛出C# 迭代索引属性(反射),c#,.net,reflection,C#,.net,Reflection,我想对一个只有通过反射才能访问的索引属性进行排序 但是(我这么说是因为我完全知道可能有一个令人尴尬的简单答案,MSDN/Google fail=/)在抛出TargetInvocationException之前,除了在PropertyInfo.GetValue(prop,counter)上增加计数器外,我找不到/想不出其他方法 阿拉: foreach(obj.GetType().GetProperties()中的PropertyInfo属性) { if(prop.GetIndexParameter
TargetInvocationException
之前,除了在PropertyInfo.GetValue(prop,counter)
上增加计数器外,我找不到/想不出其他方法
阿拉:
foreach(obj.GetType().GetProperties()中的PropertyInfo属性)
{
if(prop.GetIndexParameters().Length>0)
{
//通过递增计数器直到引发异常,获取整数计数值
整数计数=0;
while(true)
{
尝试
{
prop.GetValue(obj,新对象[]{count});
计数++;
}
catch(targetingException){break;}
}
for(int i=0;i
现在,这有一些问题。。。非常难看。。解决方案
如果它是多维的,或者不是由整数索引的,例如
这是我用来尝试的测试代码,如果有人需要它,我会让它工作。如果有人感兴趣的话,我正在制作一个定制的缓存系统,而.Equals并没有解决这个问题
static void Main()
{
object str = new String( ( "Hello, World" ).ToArray() );
process( str );
Console.ReadKey();
}
static void process( object obj )
{
Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();
// if this obj has sub properties, apply this process to those rather than this.
if ( properties.Length > 0 )
{
foreach ( PropertyInfo prop in properties )
{
// if it's an indexed type, run for each
if ( prop.GetIndexParameters().Length > 0 )
{
// get an integer count value
// issues, what if it's not an integer index (Dictionary?), what if it's multi-dimensional?
// just need to be able to iterate through each value in the indexed property
int count = 0;
while ( true )
{
try
{
prop.GetValue( obj, new object[] { count } );
count++;
}
catch ( TargetInvocationException ) { break; }
}
for ( int i = 0; i < count; i++ )
{
process( prop.GetValue( obj, new object[] { i } ) );
}
}
else
{
// is normal type so.
process( prop.GetValue( obj, null ) );
}
}
}
else
{
// process to be applied to each property
Console.WriteLine( "Property Value: {0}", obj.ToString() );
}
}
static void Main()
{
object str=新字符串((“你好,世界”).ToArray();
过程(str);
Console.ReadKey();
}
静态无效过程(对象obj)
{
Type Type=obj.GetType();
PropertyInfo[]properties=type.GetProperties();
//如果此obj具有子属性,请将此过程应用于这些属性,而不是此属性。
如果(properties.Length>0)
{
foreach(PropertyInfo属性中的属性)
{
//如果是索引类型,则为每个
if(prop.GetIndexParameters().Length>0)
{
//获取整数计数值
//问题,如果它不是一个整数索引(字典?),如果它是多维的呢?
//只需要能够遍历索引属性中的每个值
整数计数=0;
while(true)
{
尝试
{
prop.GetValue(obj,新对象[]{count});
计数++;
}
catch(targetingException){break;}
}
for(int i=0;i
您可以使用查找索引属性参数的数量和类型
我认为要找到这些参数的“合法”值是什么,你无能为力,除非你“欺骗”并使用你可能拥有的关于该属性的内部信息。索引器的getter与普通方法一样,只是它使用方括号,而不是圆括号。您不希望能够自动确定方法的可接受值范围,因此对于索引器来说是不可行的。在索引属性中具有顺序索引号是不可能的。
索引属性不是数组。
反例:
Dictionary<int, bool> dictionary = new Dictionary<int, bool>();
dictionary[1] = true;
dictionary[5] = false;
Dictionary Dictionary=newdictionary();
字典[1]=真;
字典[5]=假;
根据类型,您通常有其他方法来获取可能的索引值,在本例中是dictionary.Keys
。如果可能的话,我会按这个顺序试一下
IEnumerable
属性如果您没有有效值的规范,也没有询问有效值是什么的方法,那么您就很倒霉。索引器将被编译为方法。以下是一个例子:
class IndexedData
{
public double this[int index]
{
get { return (double)index; }
}
}
它将被编译成如下内容:
public double get_Item(int index)
{
return (double)index;
}
无法编译以下代码,因为类中有两个double get\u Item(int)
方法。索引器是编译器的魔力
class IndexedData
{
public double this[int index]
{
get { return (double)index; }
}
public double get_Item(int index)
{
return 1d;
}
}
mind设法进行了改进,还发现该测试代码自身引用存在无限循环(例如Array.Syncroot) 简而言之,它现在发现了从IEnumerable继承的东西(这是索引最多的东西),并在这些东西上使用foreach循环,再加上现有(丑陋的)代码对字符串有效的知识,它现在的分配比以前更彻底了 很高兴,但很失望,似乎没有一个好的答案 谢谢大家的帮助
如果有人发现自己处于类似的位置,则更新测试代码
static void process( object obj )
{
Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();
// if this obj has sub properties, apply this process to those rather than this.
if ( properties.Length > 0 )
{
foreach ( PropertyInfo prop in obj.GetType().GetProperties() )
{
if ( prop.PropertyType.FindInterfaces( ( t, c ) => t == typeof( IEnumerable ), null ).Length > 0 )
{
MethodInfo accessor = prop.GetGetMethod();
MethodInfo[] accessors = prop.GetAccessors();
foreach ( object item in (IEnumerable)obj )
{
process( item );
}
}
else if ( prop.GetIndexParameters().Length > 0 )
{
// get an integer count value, by incrementing a counter until the exception is thrown
int count = 0;
while ( true )
{
try
{
prop.GetValue( obj, new object[] { count } );
count++;
}
catch ( TargetInvocationException ) { break; }
}
for ( int i = 0; i < count; i++ )
{
// process the items value
process( prop.GetValue( obj, new object[] { i } ) );
}
}
else
{
// is normal type so.
process( prop.GetValue( obj, null ) );
}
}
}
else
{
// process to be applied to each property
Console.WriteLine( "Property Value: {0}", obj.ToString() );
}
}
静态无效处理(对象obj)
{
Type Type=obj.GetType();
PropertyInfo[]properties=type.GetProperties();
//如果此obj具有子属性,请将此过程应用于这些属性,而不是此属性。
如果(properties.Length>0)
{
foreach(obj.GetType().GetProperties()中的PropertyInfo属性)
{
if(prop.PropertyType.FindInterfaces((t,c)=>t==typeof(IEnumerable),null).Length>0)
{
MethodInfo访问器=prop.G
static void process( object obj )
{
Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();
// if this obj has sub properties, apply this process to those rather than this.
if ( properties.Length > 0 )
{
foreach ( PropertyInfo prop in obj.GetType().GetProperties() )
{
if ( prop.PropertyType.FindInterfaces( ( t, c ) => t == typeof( IEnumerable ), null ).Length > 0 )
{
MethodInfo accessor = prop.GetGetMethod();
MethodInfo[] accessors = prop.GetAccessors();
foreach ( object item in (IEnumerable)obj )
{
process( item );
}
}
else if ( prop.GetIndexParameters().Length > 0 )
{
// get an integer count value, by incrementing a counter until the exception is thrown
int count = 0;
while ( true )
{
try
{
prop.GetValue( obj, new object[] { count } );
count++;
}
catch ( TargetInvocationException ) { break; }
}
for ( int i = 0; i < count; i++ )
{
// process the items value
process( prop.GetValue( obj, new object[] { i } ) );
}
}
else
{
// is normal type so.
process( prop.GetValue( obj, null ) );
}
}
}
else
{
// process to be applied to each property
Console.WriteLine( "Property Value: {0}", obj.ToString() );
}
}
return View(surveyCollection);
}
private static IList<T> ExtractNestedObjects<T>(object baseObject, T findObject, IList<T> resultCollection)
{
if (baseObject != null && findObject != null)
{
Type typeDestination = findObject.GetType();
Type typeSource = baseObject.GetType();
PropertyInfo[] propertyInfoCollection = typeSource.GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfoCollection)
{
if (propertyInfo.PropertyType.FindInterfaces((t, c) => t == typeof(IEnumerable), null).Length > 0)
{
if(propertyInfo.GetValue(baseObject, null) != null)
{
if(propertyInfo.GetValue(baseObject, null).GetType().IsPrimitive)
{
ExtractNestedObjects<T>(propertyInfo.GetValue(baseObject, null), findObject, resultCollection);
}
else if (propertyInfo.GetValue(baseObject, null).GetType().IsGenericType)
{
foreach (var item in (IList)propertyInfo.GetValue(baseObject, null))
{
ExtractNestedObjects<T>(item, findObject, resultCollection);
}
}
}
}
else
{
if (propertyInfo.Name == typeDestination.Name)
{
if (propertyInfo.GetValue(baseObject, null) != null)
{
resultCollection.Add((T)propertyInfo.GetValue(baseObject, null));
}
}
ExtractNestedObjects<T>(propertyInfo.GetValue(baseObject, null), findObject, resultCollection);
}
}
}
return resultCollection;
}