سؤال

Let's say I have this class

public Holder<T> : IHolder
{
    private mystring;
    private myobj;

    public Holder(T obj, string str)
    {
        mystring = str;
        myobj = obj;
    }
}

Then I want to have Holder< T> extend T, so that I can use Holder< T> as I would a normal T. Is there any way of doing this?

So for exampler, I would like Holder< int> to be treated like an int.

Just adding the : T doesn't work, but I was curious if there was another way.

Implicit conversions wouldn't work, as I would like it to be able to go in, for example an IEnumerable< int>

هل كانت مفيدة؟

المحلول

The way generics are implemented in .NET requires that all Foo<T> must behave largely the same way regardless of T. Among other things, all Foo<T> must have the same members, save only for the fact that members may include T in their definitions. If Foo<T> could inherit from T, knowing what members Foo<T> exposed would require knowing what members T exposed, which could of course be completely different for a Foo<Automobile> and a Foo<Cat>. If one knows that Foo<T> will only be used for types that derive from e.g. Animal, one could define a class Foo<T> : Animal where T:Animal, but that would only allow a Foo<Cat> to be used as an Animal--not as a Cat.

In many cases, however, what is really needed is not a type Foo<T> which actually inherits T, but rather the ability to create an object which mostly behaves like T, but with some differences. The .NET Framework doesn't allow that to be done directly either, but there are some libraries which can auto-generate proxy objects for that purpose. Given an interface and one or more objects, each of which implements some interface members, and which collectively implement all of them, a proxy generator will create (at run time!) a new class which holds references to the supplied objects and implements that interface by creating for each interface method a class method that chains to the corresponding method on one of the passed-in objects.

Note that although the method which creates these new classes will be generic, the classes themselves will not be. It may be that myProxyMaker.Create<IFoo>(IFlyingMammal) returns a proxy8675309 and a myProxyMaker.Create<ISwimmingMammal> returns a proxy24601. Because they are completely different classes, the fact that IFlyingMammal has different members from ISwimmingMammal would pose no problem. The fact that the classes might have ugly machine-generated names wouldn't really matter because one wouldn't be declaring variables of type proxy8675309 or proxy24601, but instead types IFlyingMammal and ISwimmingMammal.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top