假设我有一些课程 - 假设的例子:
public class InvalidResponseException<TReq, TResp> : Exception
{
public TReq RequestData { get; protected set; }
public TResp ResponseData { get; protected set; }
public InvalidResponseException(string message, TReq requestData, TResp responseData)
: this(message, null, requestData, responseData)
{
}
public InvalidResponseException(string message, Exception innerException, TReq requestData, TResp responseData)
: base(message, innerException)
{
RequestData = requestData;
ResponseData = responseData;
}
}
好的,类定义了......并且编译,没问题。
因此,可以说在我的代码正文中的其他地方,我想抛出此异常并将匿名对象传递到一种或多种类型的异常中。这应该使它足够通用,以便我可以在任何从代码库中的某些调用获得意外响应的地方使用它:
var reqData = new {
Context = SomeDataContext,
Username = SomeUserName,
ParentID = 54,
RequestValues = ListOfItemsToGet
}
var respData = results.ToList();
string exceptionMessage = string.Format("Invalid response data detected. Requested {0} items received {1}.", ListOfItemsToGet.Count(), results.Count());
throw new InvalidResponseException(exceptionMessage, reqData, respData);
对于大多数匿名调用,您可以使用类型推断,因此您不必在方法调用中定义类型...但是这段代码将无法编译。
如果我将鼠标悬停在 reqData 的“var”上,编译器会告诉我有一个为其定义的类型,尽管这是一个没有人可以手动分配的奇怪名称......所以理论上我认为可以从中推断出该类型。
我最初的结论是,您不能将匿名类型传递给泛型,但是您确实可以以某种方式将匿名对象传递给泛型:
var BritishExpats = from p in People
where p.CountryOfBirth == "United Kingdom" && p.CountryOfResidents != p.CountryOfBirth
select new { FirstName = p.FirstName, LastName = p.LastName }
这里“BritishPeople”是一个 IEnumerable,其中 T 被推断为 'a
...我可以迭代生成的匿名对象 IEnumerable 并引用它们的公共属性,没有任何问题...
foreach (var ExPat in BritishExpats)
{
Console.WriteLine("{0}, {1}", Expat.LastName, Expat.FirstName);
}
当然,我必须在循环中使用“var”,因为我们不really知道“BritishExpats”是什么类型。
因此,我可以使用匿名对象推断的类型实例化某些类型的类,但不能实例化其他类型的类......
...对于匿名对象可以和不能实例化、推断和推断什么有规律或理由吗?