0

現在、スペックフローのテストベースを構築中です。したがって、すべての値は文字列として入力されます。使用するContractオブジェクトのプロパティを更新するコードを作成しました。ただし、Contractオブジェクトには、カスタムオブジェクトの配列もいくつかあります。配列の「タイプ」、その配列内の要素のプロパティ、新しい値、および変更するオブジェクトのインデックスを渡したいと思います。私が直面している問題は、オブジェクトだけでなく、動的に型付けされたリストを取得することです。

Contract.cs

public class Contract
{
  public string Name { get; set; }
  public string Status { get; set; }

  public Asset[] Asset { get; set; }
  public Group[] Group { get; set; }

  public Contract( string name, string status ){
    Name = name;
    Status = status
    Asset = new Asset[ 10 ];
    Group = new Group[ 10 ];
  }
}


Asset.cs

public class Asset {
        public int ID { get;set;}
        public string Value {get;set;}
}


Group.cs

public class Group{
        public int ID { get;set;}
        public string Value {get;set;}
}


これが私の契約の基本構造です。クライアントコードは次のとおりです。

static void Main( string[] args )
{
  Contract c = new Contract( "TestContract", "Default" );
  for( int i = 0; i < 10; i++ )
  {
     c.Asset[ i ] = new Asset( i*10, "base" );
     c.Group[ i ] = new Group( i*100, "newGroup" );
  }

  Console.WriteLine( c );
  updateContract( c, "Asset", 0, "Value", ".666." );
  updateContract( c, "Group", 0, "Value", ".999." );
  updateContract( c, "Group", 2, "Value", ".999." );
  updateContract( c, "Status", "Awesome" );
  Console.WriteLine( c );    
}

public static void updateContract( Contract contract, string collection, int index, string property, string value )
{
    object collectionObject;
    if( collection == "Asset" )
    {
        collectionObject = contract.Assets[ index ];
    }
    else if( collection == "Group" )
    {
        collectionObject = contract.Group[ index ];
    }
    else
    {
        throw new Exception( "Couldn't parse " + collection + " properly" );
    }

    SetPropValue( collectionObject, property, value );

}


public static void updateContract( Contract contract, string Property, string value )
{
    SetPropValue( contract, Property, value );
}

private static void SetPropValue( object src, string propName, string value )
{
    PropertyInfo pi = src.GetType().GetProperty( propName );

    //Gets the type of the property passed in
    Type t = pi.PropertyType;

    //Converts the string to the property type
    object newVal = Convert.ChangeType( value, t );

    //Sets the newly typed object to the property
    pi.SetValue( src, newVal, BindingFlags.SetProperty, null, null, null );
    //pi.SetValue( src, newVal); // In .NET 4.5
}

基本的に私はそのif/elseブロックを削除し、このようなものを入れたいと思います

object[] objectCollections = (object[]) GetPropValue(contract, collection);
object curCollectionObject = objectCollections[index];
SetPropValue(ref curCollectionObject, property, value);

しかし、それは壊れています。任意のアイデアや助けをいただければ幸いです。長い投稿でごめんなさい

4

1 に答える 1

2

とにかく、本当にリフレクションを介してこれを行う必要がある場合は、次のようにします。

private static void SetPropValue(object src, string collection, int index, 
                                 string property, string value)
{
    PropertyInfo collectionProperty = src.GetType().GetProperty(collection);
    Array array = collectionProperty.GetValue(src, null) as Array;
    object item = array.GetValue(index);
    SetPropValue(item, property, value);
}

エラー処理はあなた次第です。使用法:

SetPropValue(c, "Asset", 2, "Value", ".777.");
于 2012-12-04T15:19:02.510 に答える