c# - 为什么我无法实例化从匿名对象推断类型的泛型类?

标签 c# instantiation type-inference anonymous-objects

假设我有一些类(class) - 假设的例子:

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 并引用它们的公共(public)属性,没有任何问题...

foreach (var ExPat in BritishExpats)
{
    Console.WriteLine("{0}, {1}", Expat.LastName, Expat.FirstName);
}

当然,我必须在循环中使用“var”,因为我们真的不知道“BritishExpats”是什么类型。

所以我可以使用匿名对象推断的类型实例化某些类型的类,但不能实例化其他类型......

...对于匿名对象可以实例化、推断什么和不能推断什么有什么规律或原因吗?

最佳答案

您不能将泛型、匿名类型和类型推断放在构造函数中。编译器就是无法理解它。您可以通过辅助类创建解决方法,例如:

public static class InvalidResponseExceptionHelper
{
    public static InvalidResponseException<TReq, TResp> Create<TReq, TResp>
        (string message, TReq requestData, TResp responseData)
    {
        return new InvalidResponseException<TReq, TResp>(message, 
            requestData, responseData);
    }
}

另外,我没有提到它,但是除非进行大量修改,否则您的 InvalidResponseException 类将无法编译。然而,你的问题的概念已经被理解了。

关于c# - 为什么我无法实例化从匿名对象推断类型的泛型类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14271661/

相关文章:

c++ - 如何避免 "dynamic initialization in unreachable code"警告?

c++ - 检查 C++ 模板值零失败

java - Collections.emptyList() 返回一个 List<Object>?

c# - 使用 C# 创建缩略图

c# - 42883 : function does not exist - Calling Postgres Functions in Entity Framework C# Npgsql

c# - 如何在没有导航页面的情况下更改状态栏颜色

c# - 空的序列化 XML 文件

C++ unique_ptr 单独声明和实例化

c# - 为什么 List<T> 在协变接口(interface) MyInterface<out T> 上无效

java - Java 规范中的方法类型推断