最近,我有一个面试问题,显示的问题是传递参数作为其界面。现在,我一直认为你必须通过混凝土,因为没有办法知道实现哪个实例化。此外,我总是在你可以"可能"返回接口...但你应该返回混凝土(以及)。
问:参数化界面是个坏主意吗?
问:返回界面"好吗"?
问:如果存在多个派生,您如何知道实例化哪个派生?
更新 - 让它更清晰
对不起澄清...
如果我将其发送到服务器:
- 它如何知道实例化哪个派生? (这应该失败......对吗?)
var customer = { Name: 'Frank The Tank', Orders: [] }
$.get(url, customer, cb);
对比,如果我将其发送到服务器:
- 它如何知道实例化哪个派生?
- 具体类型是否遵循? (我从未真正检查过)
var customer = new InsideSalesCustomer('Frank The Tank', []);
$.get(url, customer, cb);
var customer = new ExternalCustomer('Bilbo Baggins', []);
$.get(url, customer, cb);
代码示例:
public interface ICustomer
{
string Name { get; }
IEnumerable<IOrder> Orders { get; }
}
public interface IOrder
{
IEnumerable<IOrderItem> OrderItems { get; }
}
public interface IOrderItem
{
IEnumerable<IProduct> Products { get; }
}
public interface IProduct
{
string Name { get; }
}
public class CustomersController : ApiController
{
// I was always told Customer & OrderItem should be a concretes
public IEnumerable<IOrderItem> ListOrderItems(ICustomer customer)
{
// Return All OrderItems for all orders
return customer.Orders.SelectMany(o => o.OrderItems);
}
}
答案 0 :(得分:2)
通过在此方案中使用接口,您可以允许更多代码重用。任何使用parts
接口的客户都可以传递给此方法。此外,任何使用ICustomer
的OrderItem都可以进行迭代。与仅使用IOrderItem
和USACustomers
相比,这为此方法提供了更多可能的用途,这将使您锁定这些具体类型。通过使用interfacses,您可以传递任何客户并遍历返回的OrderItem。
回答你的问题
问:参数化界面是个坏主意吗?
不,在你的场景中绝对不是一个坏主意。
问:回复界面&#34;好吗&#34;?
是的,返回一个接口只是返回实现该接口的任何类型。
问:如果存在多个派生,您如何知道要实例化哪个派生?
您可以收集对象的类型,它永远不会返回您的界面。
USOrderItem
然后,您可以根据需要投射对象。 ref
Type objectType = myObject.GetType();
答案 1 :(得分:0)
据发布,这在WebAPI中实际上根本不起作用,这可能是面试问题的目标。
为什么呢? WebAPI模型绑定器将无法确定给定ICustomer
的运行时类型,因此当您实际进入该方法时,您将看到ICustomer对象因为被跳过而简单为null在绑定期间。
我只是用一个非常简单的例子来尝试。如果我使用ICustomer
作为我的参数类型,它总是以null为单位。
如果我使用Customer
,一切正常。
你 能够通过使用自定义模型绑定器将接口用作参数,顺便说一句,它只是不能直接使用&#34;开箱即用&#34;。关于如何做到这一点有很多材料,我不会在这里进入。