开发者

Casting type parameter

开发者 https://www.devze.com 2023-03-16 22:56 出处:网络
The title might be a bit vague, but what I want is to achieve this, but then without using the extra lambda in the create method:

The title might be a bit vague, but what I want is to achieve this, but then without using the extra lambda in the create method:

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)
    {
        _someFun开发者_开发知识库c = someFunc;
    }
}

Is it possible to do this, if so, how?

EDIT: The stream class is just as example.

In my code I won't be using a stream class, and as for why the type-parameter, because it's returned from a generic method, which is an extension method.

Also, the call will always be type-safe, I wanted to make the 'Wrapper' class itself generic, but then it'd be unable to add it to generic collections, because they'd have different type-parameters.


There's no way to do what you want without a lambda. A Func<Stream, bool> must accept any type of Stream as a parameter, so a method that takes a T (which is a specific kind of Stream) is not compatible with the signature of Func<Stream, bool>

Anyway, in the code you posted the generic parameter is completely useless; so just remove it, and make the method non-generic.


This can't be casted (even with contravariance support) because it is not a safe cast.

If I have a function that acts on FileStream, then try to pass it into Wrapper, I've passed it in as a function that claims it can act on any Stream. If I then invoke that function from within Wrapper using a MemoryStream, for instance, then the delegate binding fails. The Func<Stream, bool> is not really a Func<Stream, bool> at all.


if you want to make Wrapper generic (Wrapper<T>), you might consider exposing a non-generic interface IWrapper implemented by the generic. This way you can create a collection of IWrapper instances and expose the functionality that is valid to perform on any Wrapper<T>, while still maintaining type-safety inside each instance.

0

精彩评论

暂无评论...
验证码 换一张
取 消