C# 在AutoMoq中将泛型类的属性作为参数传递

C# 在AutoMoq中将泛型类的属性作为参数传递,c#,generics,moq,autofixture,automoq,C#,Generics,Moq,Autofixture,Automoq,我想做的是推广使用AutoFixture和Moq创建存储库。我有一个名为“add”的方法,可以将假记录添加到列表中。该列表称为记录,是类的全局列表。通用M是一个要模拟的模型。该方法返回“this”,因此可以链接该方法 public Repo<M> add(string prop, string val) { var a = fixture.Build<M>().With(m => m.GetProperty(prop), val).Create();

我想做的是推广使用AutoFixture和Moq创建存储库。我有一个名为“add”的方法,可以将假记录添加到列表中。该列表称为记录,是类的全局列表。通用M是一个要模拟的模型。该方法返回“this”,因此可以链接该方法

public Repo<M> add(string prop, string val) {
    var a = fixture.Build<M>().With(m => m.GetProperty(prop), val).Create();
    records.Add(a);
    return this;
}
公共回购添加(字符串属性、字符串值){
var a=fixture.Build().With(m=>m.GetProperty(prop),val.Create();
记录。添加(a);
归还这个;
}
对于扩展类(我发现这个搜索是这样的):

公共静态类MyExtensions
{
公共静态对象GetProperty(此T对象,字符串名称),其中T:class
{
类型t=类型(t);
返回t.GetProperty(name).GetValue(obj,null);
}
}
我得到的错误是“Ploeh.AutoFixture.dll中发生ArgumentException”


我的问题是:当模型在编译时未知时,如何将泛型对象的属性作为参数传递到方法中?

With
方法要求
表达式
参数而不是
属性info

您可以将
add
方法更改为采用
Expression
而不是字符串:

public Repo<M> add<T>(Expression<Func<M, T>> propertyPicker, T val) 
{
   var a = fixture.Build<M>().With(propertyPicker, val).Create();
   records.Add(a);
   return this;
}

With
方法需要
表达式
参数非
PropertyInfo

您可以将
add
方法更改为采用
Expression
而不是字符串:

public Repo<M> add<T>(Expression<Func<M, T>> propertyPicker, T val) 
{
   var a = fixture.Build<M>().With(propertyPicker, val).Create();
   records.Add(a);
   return this;
}

非常感谢Arkadiusz给出的正确答案。我只想添加我添加的这个方法(受几篇SO文章的启发)来创建表达式,以便使用:
添加(“用户名”、“我”)

私有表达式makeExpression(字符串prop,T val)
{
var m=表达式参数(typeof(m),“m”);
Expression columnExpr=Expression.Property(m,typeof(m).GetProperty(prop));
返回表达式.Lambda(columnExpr,m);
}

然后,在add方法中,我将
propertypecker
更改为
makeExpression(property,val)
property
是属性的字符串名称。

非常感谢Arkadiusz给出了正确的答案。我只想添加我添加的这个方法(受几篇SO文章的启发)来创建表达式,以便使用:
添加(“用户名”、“我”)

私有表达式makeExpression(字符串prop,T val)
{
var m=表达式参数(typeof(m),“m”);
Expression columnExpr=Expression.Property(m,typeof(m).GetProperty(prop));
返回表达式.Lambda(columnExpr,m);
}

然后,在add方法中,我将
propertypecker
更改为
makeExpression(property,val)
property
作为字符串作为属性的名称。

作为旁注,您的
add
方法应该命名为
add
,根据。作为旁注,根据。
makeExpression
应该是
makeExpression
,您的
add
方法应该命名为
add
。您必须知道,若
M
类中存在属性,那个么您将丢失编译时检查。这意味着,如果您的示例使用重构工具更改属性名称,该工具将不会更改属性名称文字,除非它们支持在字符串文字中搜索。
makeExpression
应为
makeExpression
。您必须知道,若
M
类中存在属性,那个么您将丢失编译时检查。这意味着,如果您的示例使用重构工具更改属性名称,该工具将不会更改属性名称文字,除非它们支持在字符串文字中搜索。
add(foo => foo.Name, "abc");
private Expression<Func<M,T>> makeExpression<T>(string prop, T val)
{
    var m = Expression.Parameter(typeof(M), "m");
    Expression columnExpr = Expression.Property(m,typeof(M).GetProperty(prop));

    return Expression.Lambda<Func<M, T>>(columnExpr, m);
}