15

編集

この質問の最低限のバージョンは、もし私が持っているなら、oがリフレクションobject oで実装されるタイプのものであるかどうかをどのようにチェックするのでしょうか?元の質問ははるかに具体的ですが、上記の答えも同様に良いでしょう。この質問について詳しく説明しすぎたら申し訳ありませんIEnumerable<string>

編集終了

以下は、考案されたValueInjecterPOCです。isCollectionMapping一番下の方法を除いて、すべてがうまく機能します。ソースプロパティとターゲットプロパティの両方がを実装するオブジェクトである場合にのみ、trueを返そうとしていますIEnumerable<respectiveTypes>

私も試しましたが、どちらIsAssignableFromもうまくIsInstanceOfTypeいかないようです。

メソッドの2行目をコメント解除して、「Children」という名前のプロパティを明示的にチェックすると、正常に機能するため、他のすべてが機能します。

-この例には問題があることを私は知っています。つまり、私は古いものをチェックしようとしていますIEnumerable<>が、それでも常に戻るのに十分なことを知っていList<>ます。これは、現時点での概念実証にすぎません。

[TestClass]
public class UnitTest1 {

    [TestMethod]
    public void TestMethod1() {
        List<string> strings = new List<string>();

        Subject S = new Subject() {
            id = 1,
            SubjectName = "S1",
            Children = { new Subject() { id = 2, SubjectName = "S1a" },
                         new Subject() { id = 3, SubjectName = "S1b", Children = { new Subject() { id = 4} } } }
        };

        SubjectViewModel VM = (SubjectViewModel)new SubjectViewModel().InjectFrom<CollectionToCollection>(S); ;


        Assert.AreEqual(2, VM.Children.Count);
        Assert.AreEqual(1, VM.Children.Single(s => s.id == 3).Children.Count);
    }
}


public class Subject {
    public Subject() {
        Children = new List<Subject>();
    }

    public string SubjectName { get; set; }
    public int id { get; set; }

    public List<Subject> Children { get; set; }
}

public class SubjectViewModel {
    public SubjectViewModel() {
        Children = new List<SubjectViewModel>();
    }

    public string SubjectName { get; set; }
    public int id { get; set; }

    public List<SubjectViewModel> Children { get; set; }
}

public class CollectionToCollection : Omu.ValueInjecter.ConventionInjection {
    protected override bool Match(ConventionInfo c) {
        return c.TargetProp.Name == c.SourceProp.Name;
    }

    protected override object SetValue(ConventionInfo c) {
        if (isCollectionMapping(c))
            return (c.SourceProp.Value as IEnumerable<Subject>).Select(s => (SubjectViewModel)(new SubjectViewModel().InjectFrom<CollectionToCollection>(s))).ToList();
        else
            return c.SourceProp.Value;
    }

    private bool isCollectionMapping(ConventionInfo c) {
        return c.SourceProp.Value.GetType().IsInstanceOfType(typeof(IEnumerable<Subject>)) && c.TargetProp.Value.GetType().IsAssignableFrom(typeof(IEnumerable<SubjectViewModel>));

        //return c.SourceProp.Name == "Children" && c.TargetProp.Name == "Children";
    }
}
4

3 に答える 3

32

オブジェクトがある場合、それが実装されているタイプであるかoどうかを確認するにはどうすればよいですか?oIEnumerable<string>

単純な:

o is IEnumerable<string>

ちなみに、現在のコードは、割り当て可能性の関係のテストをにしているため(メソッドが呼び出されたかのようにIsAssignableTo)、機能していません。つまり、次のことを前提としています。

Bar bar = ...
Foo foo = bar

示す:

typeof(Bar).IsAssignableFrom(typeof(Foo)) // wrong

実際には、実際の意味は次のとおりです。

typeof(Foo).IsAssignableFrom(typeof(Bar))

つまり、私は古いものをチェックしようとしていますIEnumerable<>

この場合、型がジェネリックインターフェイスの構築バージョンを実装しているかどうかをテストする必要があります。

o.GetType()
 .GetInterfaces()
 .Any(t => t.IsGenericType 
        && t.GetGenericTypeDefinition() == typeof(IEnumerable<>))
于 2011-04-06T14:19:34.927 に答える
10

この質問の最低限のバージョンは、オブジェクトoがある場合、oが実装するタイプであるかどうかをどのように確認するのでしょうIEnumerable<string>か。

このような:

object o = whatever;
bool isSequenceOfStrings = o is IEnumerable<string>;
于 2011-04-06T14:17:59.997 に答える
5

私は何かを見逃した可能性があります(コードサンプル全体を読んでいませんでした)が、ここで熟考する必要はないようです。

使用するのはどうですか:

if (c.SourceProp.Value is IEnumerable<Subject>)
   return true;

特定のタイプがわからない場合は、ジェネリックを使用してください。

public bool MyFunction<T>(...)
{
   if (c.SourceProp.Value is IEnumerable<T>)
      return true;
}

または、インターフェイスを使用する必要がある場合は、次のようにします(キャストを保存します)。

var enumerable = c.SourceProp.Value as IEnumerable<string>;
if (enumerable != null)
{
   // Use IEnumerable<string>
   return true;
}

return false;
于 2011-04-06T14:19:51.160 に答える