Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以通过传入lambda表达式来获取参数来检查泛型对象上的属性吗?_C#_Linq - Fatal编程技术网

C# 我可以通过传入lambda表达式来获取参数来检查泛型对象上的属性吗?

C# 我可以通过传入lambda表达式来获取参数来检查泛型对象上的属性吗?,c#,linq,C#,Linq,举个简单的例子,我有一个Cat对象,它有一个Name属性 我有一个名为PrintName(T objectToPrint) 我不能执行Console.WriteLine(objectToPrint.Name),因为它是t类型 那么,我可以将参数作为获取名称的linq表达式传入吗?有点像 Cat c = new Cat("Bernard the Cat"); PrintName(cat, parameter: c => c.Name); 那么PrintName就可以了 Console.W

举个简单的例子,我有一个
Cat
对象,它有一个
Name
属性

我有一个名为
PrintName(T objectToPrint)

我不能执行
Console.WriteLine(objectToPrint.Name)
,因为它是
t
类型

那么,我可以将参数作为获取名称的linq表达式传入吗?有点像

Cat c = new Cat("Bernard the Cat");

PrintName(cat, parameter: c => c.Name);
那么PrintName就可以了


Console.WriteLine(cat.RunLinq(参数))

嗯,您可以使用接口,但是如果属性可以更改,您可以这样做

第一种解决方案:如果需要属性名称

PrintName<T>(T objectToPrint, Expression<Func<T, object>> property)
然后获取属性的“名称”,类似的东西

var name = (property.Body as MemberExpression).Member.Name
第二种解决方案:如果需要属性的值

PrintName<T>(T objectToPrint, Expression<Func<T, object>> property)
如果需要属性值,请使用
Func Func
参数

// object if you don't know the type of the property, 
// you can limit it to string if needed, of course
PrintName<T>(T objectToPrint, Func<T, object> func)
然后


通常的方法是使用泛型传递
cat
的类型:

void PrintName<T>(T cat, Func<T, string> parameter) {
 Console.WriteLine(parameter(cat));
}
void打印名(T cat,Func参数){
控制台写入线(参数(cat));
}

代理可以使用确切类型的
T
,因此可以访问
Name
。LINQ经常以这种方式工作(
OrderBy
,…)。如果我们将
T
替换为
object
,则此模式将不起作用,因为类型不会被传递。

您可以定义一个接口,并在应支持打印的每个对象上实现它

interface IPrintable
{
  string Name{get;}
}

class Cat : IPrintable
{
  string Name{get{retrun "Dog";}}
}

void PrintName(IPrintable objectToPrint)
{
  Console.WriteLine(objectToPrint.Name);
}

var cat = new Cat();
PrintName(cat);
您可以使用反射或动态来实现它,而无需接口实现

void PrintName<T>(T objectToPrint)
{
  dynamic o = (dynamic)objectToPrint;
  Console.Writeline(o.Name);
}
void PrintName(T objectToPrint)
{
动态o=(动态)objectToPrint;
控制台写入线(o.Name);
}

您可以引入接口
IName
,其中包含属性名称的定义,并写入
PrintName(T objectToPrint),其中T:IName
。然后你可以写“代码> ObjeTutopRun.Name < /Cord>。谢谢,我会考虑如果没有使用接口就没有办法。我不知道为什么你需要<代码> Primy.Boad作为成员表达式…<代码>行,你能解释一下吗?另一个答案只是使用
参数(cat)
,这似乎更简单,也更有意义。但我想理解你答案背后的理论。我不确定是否理解,这就是为什么我给你两个解决方案:第一个(编辑前)给你属性的名称,第二个(编辑后)给你属性的值。选择你需要的。啊,对不起,我现在明白了。谢谢
interface IPrintable
{
  string Name{get;}
}

class Cat : IPrintable
{
  string Name{get{retrun "Dog";}}
}

void PrintName(IPrintable objectToPrint)
{
  Console.WriteLine(objectToPrint.Name);
}

var cat = new Cat();
PrintName(cat);
void PrintName<T>(T objectToPrint)
{
  dynamic o = (dynamic)objectToPrint;
  Console.Writeline(o.Name);
}