C# func<> 应用于左边的对象
C# func<> applied to the object on left
我想弄清楚是否有办法使用应用于左侧对象的 func(或类似方法)。
例如:
member1.MyFunction()
这是一个简化的用法上下文。我们得到了 ClassA,它包含一个 ClassB 的列表和一个总结 classB 的元素的方法。而classB拥有两个double类型的属性memberX和memberY。 func 用于选择我们要求和的 ClassB 的哪个成员。
我写的那一行有错误
theSum += TheList[i].TheFunction();
错误是:
CS1061 C# does not contain a definition for and no extension method accepting a first argument of type could be found (are you missing a using directive or an assembly reference?)
有人知道解决方法吗?我的研究无法将我引导到适用于通用函数左侧的任何内容。
public class ClassA
{
public List<ClassB> TheList;
public ClassA()
{
ClassB m1 = new ClassB(1, 2);
ClassB m2 = new ClassB(1, 2);
ClassB m3 = new ClassB(1, 2);
TheList= new List<ClassB>() { m1, m2, m3 };
}
private double CalculateSum(Func<double> TheFunction)
{
double theSum = 0;
for (int i = 0; i < TheList.Count(); i++)
{
theSum += TheList[i].TheFunction();
// I'd like to use the previous line instead of having to write
// a function for both of the following.
// theSum += TheList[i].GetMember1();
// theSum += TheList[i].GetMember2();
}
return theSum;
}
}
public class ClassB
{
private double memberX;
private double memberY;
public ClassB(double x, double y)
{
memberX = x;
memberY = y;
}
public double GetMember1() { return memberX; }
public double GetMember2() { return memberY; }
}
嗯,不是那种语法,但你可以使用:
theSum += aFunction(aList[i]);
我想你可以为此写一个扩展方法,但上面的方法更惯用。
事实上,使用 LINQ 开始会更惯用 - 您的 calculateSum
方法已经作为 Sum
存在于 LINQ 中,因此您可以调用:
double sum = aList.Sum(x => x.getMember1());
当然,更惯用的是,您将使用属性而不是方法:
double sum = aList.Sum(x => Member1);
同样对于习语,您要确保您执行的任何方法都遵循 .NET 命名约定,以大写字母开头。我强烈建议您立即开始遵循命名约定(即使是一次性演示代码)。
您可以尝试这样的操作:
private double calculateSum(Func<ClassB, double> aFunction)
{
double theSum = 0;
for (int i = 0; i < aList.Count(); i++)
{
theSum += aFunction(aList[i]);
}
return theSum;
}
更新
如果你真的想把函数应用到它左边的对象上,那么你可以定义一个扩展方法。
public static class ClassBExtensions
{
public static double Sum(this ClassB arg, Func<ClassB, double> func)
{
return func(arg);
}
}
然后这样称呼它
Func<ClassB, double> func = null; // define your func here
for (int i = 0; i < aList.Count(); i++)
{
theSum += aList[i].Sum(func);
}
return theSum;
如果我没理解错的话,您需要一种方法 "on" ClassB
returns 其中一个值。 (ClassB
是否应该有这样的方法 - 它可能只是计算的一部分,因此实际上属于 ClassA
- 是一个不同的问题。)
如果您可以更改 ClassB
,只需在此处添加:
public class ClassB
{
private double memberX;
private double memberY;
public ClassB(double x, double y)
{
memberX = x;
memberY = y;
}
public double GetMember1() { return memberX; }
public double GetMember2() { return memberY; }
public double AFunction()
{
bool condition = ...
return condition ? memberX : memberY;
}
}
我在这里使用三元运算符 ?:
来节省 if/else
上的一些空间。
现在,如果您可以 不 更改 ClassB
,extension methods(如 CS1061
错误消息中所暗示)可能会帮助您:
public static class ClassBExtensions
{
public double AFunction(this ClassB b)
{
bool condition = ...
return condition ? b.GetMember1() : b.GetMember2();
}
}
您现在可以简单地在类型 ClassB
的任何实例上调用 .AFunction()
,就好像该方法最初是在那里声明的一样。请注意,扩展方法只能访问可公开访问的字段。
您可能还想查看 properties,它可以将您的 ClassB
定义减少为:
public class ClassB
{
public ClassB(double x, double y)
{
MemberX = x;
MemberY = y;
}
public double Member1 { get; }
public double Member2 { get; }
/*
public double AFunction()
{
bool condition = ...
return condition ? Member1 : Member2;
}
*/
}
我想弄清楚是否有办法使用应用于左侧对象的 func(或类似方法)。 例如:
member1.MyFunction()
这是一个简化的用法上下文。我们得到了 ClassA,它包含一个 ClassB 的列表和一个总结 classB 的元素的方法。而classB拥有两个double类型的属性memberX和memberY。 func 用于选择我们要求和的 ClassB 的哪个成员。
我写的那一行有错误
theSum += TheList[i].TheFunction();
错误是:
CS1061 C# does not contain a definition for and no extension method accepting a first argument of type could be found (are you missing a using directive or an assembly reference?)
有人知道解决方法吗?我的研究无法将我引导到适用于通用函数左侧的任何内容。
public class ClassA
{
public List<ClassB> TheList;
public ClassA()
{
ClassB m1 = new ClassB(1, 2);
ClassB m2 = new ClassB(1, 2);
ClassB m3 = new ClassB(1, 2);
TheList= new List<ClassB>() { m1, m2, m3 };
}
private double CalculateSum(Func<double> TheFunction)
{
double theSum = 0;
for (int i = 0; i < TheList.Count(); i++)
{
theSum += TheList[i].TheFunction();
// I'd like to use the previous line instead of having to write
// a function for both of the following.
// theSum += TheList[i].GetMember1();
// theSum += TheList[i].GetMember2();
}
return theSum;
}
}
public class ClassB
{
private double memberX;
private double memberY;
public ClassB(double x, double y)
{
memberX = x;
memberY = y;
}
public double GetMember1() { return memberX; }
public double GetMember2() { return memberY; }
}
嗯,不是那种语法,但你可以使用:
theSum += aFunction(aList[i]);
我想你可以为此写一个扩展方法,但上面的方法更惯用。
事实上,使用 LINQ 开始会更惯用 - 您的 calculateSum
方法已经作为 Sum
存在于 LINQ 中,因此您可以调用:
double sum = aList.Sum(x => x.getMember1());
当然,更惯用的是,您将使用属性而不是方法:
double sum = aList.Sum(x => Member1);
同样对于习语,您要确保您执行的任何方法都遵循 .NET 命名约定,以大写字母开头。我强烈建议您立即开始遵循命名约定(即使是一次性演示代码)。
您可以尝试这样的操作:
private double calculateSum(Func<ClassB, double> aFunction)
{
double theSum = 0;
for (int i = 0; i < aList.Count(); i++)
{
theSum += aFunction(aList[i]);
}
return theSum;
}
更新
如果你真的想把函数应用到它左边的对象上,那么你可以定义一个扩展方法。
public static class ClassBExtensions
{
public static double Sum(this ClassB arg, Func<ClassB, double> func)
{
return func(arg);
}
}
然后这样称呼它
Func<ClassB, double> func = null; // define your func here
for (int i = 0; i < aList.Count(); i++)
{
theSum += aList[i].Sum(func);
}
return theSum;
如果我没理解错的话,您需要一种方法 "on" ClassB
returns 其中一个值。 (ClassB
是否应该有这样的方法 - 它可能只是计算的一部分,因此实际上属于 ClassA
- 是一个不同的问题。)
如果您可以更改 ClassB
,只需在此处添加:
public class ClassB
{
private double memberX;
private double memberY;
public ClassB(double x, double y)
{
memberX = x;
memberY = y;
}
public double GetMember1() { return memberX; }
public double GetMember2() { return memberY; }
public double AFunction()
{
bool condition = ...
return condition ? memberX : memberY;
}
}
我在这里使用三元运算符 ?:
来节省 if/else
上的一些空间。
现在,如果您可以 不 更改 ClassB
,extension methods(如 CS1061
错误消息中所暗示)可能会帮助您:
public static class ClassBExtensions
{
public double AFunction(this ClassB b)
{
bool condition = ...
return condition ? b.GetMember1() : b.GetMember2();
}
}
您现在可以简单地在类型 ClassB
的任何实例上调用 .AFunction()
,就好像该方法最初是在那里声明的一样。请注意,扩展方法只能访问可公开访问的字段。
您可能还想查看 properties,它可以将您的 ClassB
定义减少为:
public class ClassB
{
public ClassB(double x, double y)
{
MemberX = x;
MemberY = y;
}
public double Member1 { get; }
public double Member2 { get; }
/*
public double AFunction()
{
bool condition = ...
return condition ? Member1 : Member2;
}
*/
}