我正在尝试重构我的一些代码以使用Func 我创建了一个示例,试图了解它是如何工作的,但我收到了编译错误。在例如下面当我尝试访问参数属性或返回编译器抱怨的返回值时。
请澄清。
using System;
namespace chsarp
{
class Program
{
static void Main(string[] args)
{
ParamInput input = new ParamInput();
input.ReservationID = 10;
Test testMethod = new Test();
Func<ParamInput, ReservationResult> methodToInvoke = testMethod.GetStatus;
ReservationResult result = TestFn(methodToInvoke, input);
}
static Result TestFn<Param, Result>(Func<Param, Result> methodToInvoke, Param parameter) where Result : new()
{
Result result = new Result();
try
{
result = methodToInvoke(parameter);
}
catch (Exception exception)
{
result.status = string.Format("Error-{0} during reserving {1}",
parameter.ReservationID,
exception.Message);
}
return result;
}
}
class Test
{
public ReservationResult GetStatus(ParamInput msg)
{
ReservationResult result = new ReservationResult();
result.status = string.Format("The ReservationID-{0}", msg.ReservationID);
return result;
}
}
class ParamInput
{
public int ReservationID { get; set; }
}
class ReservationResult
{
public string status { get; set; }
}
}
答案 0 :(得分:4)
带注释的编译错误:
error CS1061: 'Result' does not contain a definition for 'status'
error CS1061: 'Param' does not contain a definition for 'ReservationID'
使用泛型类型参数的代码只能在编译器知道泛型类型的成员时才能编译。它不知道Result类型参数具有“status”成员。如果你调用TestFn<object, object>()
,肯定不会。
您需要使用约束才能使其正常工作。你已经这样做了,但是new()还不够强大。例如“where Result:IResult”之类的东西,其中IResult是具有status属性的接口类型。或基类。编译器现在可以100%确定泛型方法的任何允许的具体实例将在不引起运行时错误的情况下执行。因为只有在使用具有“status”属性的类型调用它时才能编译它。
所有这些都适用于Param类型参数。当你这样做时,泛型方法的有用性很快消失,这不是正确的用法。除非你可以利用IResult,就像IEnumerable一样。
答案 1 :(得分:1)
...编译
你应该在你的问题中描述你的目标。
请参阅Hans的回答,了解可能有助于您理解错误的详细信息。
你的问题是你说该函数应该采用可实例化的结果,但你并不是说它必须有一个名为“status”的属性。
namespace chsarp
{
class Program
{
static void Main(string[] args)
{
Func<int, string> m = Test.GetStatus;
var t = TestFn(m, 10);
}
static string TestFn<TParam>(Func<TParam, string> m, TParam p)
{
try { return m(p); }
catch (Exception exception)
{
return string.Format("Reserving \"{0}\" failure exception: {1}", p, exception);
}
}
}
static class Test
{
public static string GetStatus(int inp)
{
return string.Format("The ReservationID-{0}", inp);
}
}
}