投射类型参数

时间:2011-06-30 13:36:33

标签: c# generics casting

标题可能有点模糊,但我想要的是实现这一点,但不使用create方法中的额外lambda:

public class Wrapper
{
    public static Wrapper Create<T>(Func<T, bool> someFunc) where T : Stream
    {
        return new Wrapper(a => someFunc(a as T)); // Works, but lambda
        return new Wrapper((Func<Stream, bool>)(object)someFunc); // Runtime error
        return new Wrapper((Func<Stream, bool>)someFunc); // Compile error
    }

    Func<Stream, bool> _someFunc;
    private Wrapper(Func<Stream, bool> someFunc)
    {
        _someFunc = someFunc;
    }
}

是否可以这样做,如果是这样,怎么办?

编辑:流类就是示例。

在我的代码中,我将不使用流类,以及为什么是type-parameter,因为它是从泛型方法返回的,这是一种扩展方法。

此外,调用将始终是类型安全的,我想让'Wrapper'类本身是通用的,但是它无法将它添加到泛型集合中,因为它们具有不同的类型参数。

2 个答案:

答案 0 :(得分:2)

没有lambda,没有办法做你想做的事。 Func<Stream, bool>必须接受任何类型的Stream作为参数,因此采用T(特定种类Stream)的方法与签名不兼容Func<Stream, bool>

无论如何,在您发布的代码中,泛型参数完全没用;所以只需删除它,并使该方法不通用。

答案 1 :(得分:1)

这不能投入(即使有逆转支持),因为它不是一个安全的演员。

如果我有一个作用于FileStream的函数,那么尝试将其传递给Wrapper,我已将其作为一个函数传递,声称它可以作用于任何 Stream。例如,如果我使用MemoryStream从Wrapper中调用该函数,那么委托绑定将失败。 Func<Stream, bool>根本不是Func<Stream, bool>


如果您想使Wrapper通用(Wrapper<T>),您可以考虑公开泛型实现的非泛型接口IWrapper。这样,您可以创建IWrapper个实例的集合,并公开在任何Wrapper<T>上执行的有效功能,同时仍保持每个实例内的类型安全。