我试图实现OfType的替代方法,您可以在其中指定所需类型作为Type实例参数,而不是使用类型参数化,但我不确定'正确的方法'实现它是。这就是我到目前为止所做的:
public static IEnumerable<T> OfType<T>(this IEnumerable<T> enumerable, Type type)
{
return enumerable.Where(element => type.IsInstanceOfType(element));
}
我最初开始使用下面的代码,但意识到它不支持继承......
public static IEnumerable<T> OfType<T>(this IEnumerable<T> enumerable, Type type)
{
return enumerable.Where(element => element.GetType() == type);
}
然后我想到比较基础类型几秒钟,然后才认为这可能是一个坏主意。
所以我的问题是,由于提供的类型相同,顶部的代码总是会返回与OfType相同的结果吗?换句话说,下面代码示例中的集合parametrizedFiltered
和typeInstanceFiltered
是否包含相同的元素,还是我要离开?
IEnumerable<InterfaceType> someCollection = BlackBox.GetCollection();
IEnumerable<DerivedType> parametrizedFiltered = someCollection.OfType<DerivedType>();
IEnumerable<InterfaceType> typeInstanceFiltered = someCollection.OfType(typeof(DerivedType));
答案 0 :(得分:2)
如果您想知道您的实施是否会提供与Enumerable.OfType<>
相同的结果,那么它会。
Enumerable.OfType<>
使用is
作为其实施,而is
显示,Type.IsAssignableFrom()
关键字将为IsInstanceOfType()
提供相同的结果。
您需要的另一条信息是IsAssignableFrom
是使用public virtual bool IsInstanceOfType(Object o)
{
if (o == null)
return false;
// No need for transparent proxy casting check here
// because it never returns true for a non-rutnime type.
return IsAssignableFrom(o.GetType());
}
实现的:
Demo.Base
Demo.Derived
下面的测试代码将打印
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
public class Base {}
public class Derived : Base {}
class Program
{
static void Main()
{
object[] array = {"String", new Base(), new Derived(), 12345};
foreach (var item in OfType(array, typeof(Base)))
Console.WriteLine(item);
}
public static IEnumerable<T> OfType<T>(IEnumerable<T> enumerable, Type type)
{
return enumerable.Where(element => type.IsInstanceOfType(element));
}
}
}
表明您的原始代码确实可以使用继承:
IsInstanceOfType()
请注意,因为IsAssignableFrom
是使用public static IEnumerable<T> OfType<T>(this IEnumerable<T> enumerable, Type type)
{
return enumerable.Where(element => type.IsAssignableFrom(element.GetType()));
}
实现的,所以您可以像这样编写您的方法:
class Customer::CartsController < ApplicationController
before_action :authenticate_user!
def show
if current_user
if current_user.cart.purchased_at
session[:cart_id] = nil
else
@cart = current_user.cart ||= Cart.find_by(session[:cart_id])
end
end
if session[:cart_id].nil?
current_user.cart = Cart.create!(user_id: params[:id])
session[:cart_id] = current_user.cart.id
end
@cart = current_user.cart
end