0

私はこれを持っています:

public void AssertReadWorks<T>(
    IRepository<T> repository, 
    T entity, 
    Expression<Func<T, T, bool>> keyComparer) where T : class
{
    entity = repository.GetAll().Single(x => x.Id == entity.Id);
}

[TestMethod]
public void ReadTest_DataFieldGroup()
{
    AssertReadWorks(
            _unitOfWork.DataFieldSetRepository, 
            new DataFieldSet { Label = "test", Title = "test" }, 
            (a, b) => a.Id == b.Id);
}

T に Id プロパティがあることがわかっていないため、これはコンパイルされません。keyComparerパラメータは現在使用されていないことに注意してください。keyComparer パラメーター (または別の適切なパラメーター) を使用して、次の述語を動的に生成したいと考えていますSingle()

Expression<Func<T, bool>> keyComparingPredicate = 
    x => a predicate that compares the key of x with the key of `entity`;
entity = repository.GetAll().Single(keyComparingPredicate);

ポイントは、すべての T が Id プロパティを持つわけではなく、異なる名前を持つものもあれば、複合キーを持つものもあるということです。AssertReadWorks()ジェネリックでない場合、オリジナルは正常に機能します。問題は、一般的なケースで述語を動的に構築することです。keyComparer パラメーターとは異なる何かで実行できる場合は、問題ありません。

何か案は?:)

4

2 に答える 2

1

これがあなたに合っているかどうかを確認してください

public T AssertReadWorks<T>(
    IRepository<T> repository,
    Func<T, bool> keyComparer)
{
    return repository.GetAll().Single(keyComparer);
}

使用する

[TestMethod]
public void TestInt()
{
    var repository = new Repository<int>( new[] {1, 2, 3} );
    var intEntity = 3;
    AssertReadWorks(repository, e => e == intEntity);
}

[TestMethod]
public void TestString()
{
    var repository = new Repository<string>(new[] { "a", "b", "c" });
    var stringEntity = "A";
    AssertReadWorks(repository, e => string.Equals(e, stringEntity, StringComparison.OrdinalIgnoreCase));
}

[TestMethod]
public void TestThread()
{
    var threadEntity = new Thread(() => { });
    var repository = new Repository<Thread>(new[] { threadEntity, new Thread(() => { }), new Thread(() => { }) });
    AssertReadWorks(repository, e => e.ManagedThreadId == threadEntity.ManagedThreadId);
}

編集: コメントへの応答:

public void AssertReadWorks<T>(
    IRepository<T> repository,
    ref T entity,
    Func<T, T, bool> keyComparer)
{
    var localEntity = entity;
    entity = repository.GetAll().Single(e => keyComparer(e, localEntity));
}
于 2013-06-07T10:09:08.200 に答える
0

私が間違っている場合は修正してください。しかし、この関数の全体的なポイントは等価性をチェックすることですか? これを一般的な意味で行うには、IEquatable Interfaceを使用できます。このようにして、オブジェクトは自分自身を同じオブジェクトと比較する方法を知っています。これにより、コードの再利用が削減され、複数の場所で同じ式を作成するのを避けることができます。

したがって、クラスは次のようになります。

public class DataFieldSet : IEquatable<DataFieldSet>
{
    public int Id { get; set; }

    public bool Equals(DataFieldSet other)
    {
        return other != null && this.Id == other.Id;
    }
}

そして、あなたのアサート関数

public void AssertReadWorks<T>(
    IRepository<T> repository, 
    T entity) where T : IEquatable<T>
{
    entity = repository.GetAll().Single(x => entity.Equals(x);
}
于 2013-06-07T09:00:40.983 に答える