Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving the unclosed type of a generic type closing a generic type

I’m having an issue (probably due to my lack of familiarity of C# generics) in getting the unclosed type of a generic. I have several methods that look rather similar to the following except for the explicit validator interface in use.

public IEnumerable<IDeleteValidator<T>> GetDeleteValidators<T>()
{
    var validatorList = new List<IDeleteValidator<T>>();
    foreach (var type in GetRecursiveBaseTypesAndInterfaces(typeof(T)))
    {
        var validatorType = typeof(IDeleteValidator<>).MakeGenericType(type);
        var validators = ObjectFactory
            .GetAllInstances(validatorType).Cast<IDeleteValidator<T>>();
        validatorList.AddRange(validators);
    }
    return validatorList;
}

The method GetRecursiveBaseTypesAndInterfaces does as it says and gathers all base types and interfaces of a given type. So what I'm eventually doing is getting the unclosed type of the explicit validator interface and getting it's type as closed on each of the original type T's base classes and interfaces. This works great, however I'd like to clean up my code and accomplish this in a more generic form than above

knowing that any validator of T will extend IValidator (as bellow)

public interface IDeleteValidator<in T> : IValidator<T> {}

My uncompleted attempt at a generic version of the above method looks like:

public IEnumerable<TValidator> GetValidators<T, TValidator>() 
    where TValidator : IValidator<T>
{
    var validatorList = new List<TValidator>();
    foreach (var type in GetRecursiveBaseTypesAndInterfaces(typeof(T)))
    {
        var unclosedType = ???
        var validatorType = typeof(unclosedType).MakeGenericType(type);
        var validators = ObjectFactory
            .GetAllInstances(validatorType).Cast<TValidator>();
        validatorList.AddRange(validators);
    }
    return validatorList;
}

How do I define unclosedType (or restructure the method) to do the same work as the original method with a call to

GetValidators<Whatever, IDeleteValidator<Whatever>>();

Or would it be possible to refine my method more so as a call like the following would be sufficient?

GetValidators<IDeleteValidator<Whatever>>();
like image 945
rheone Avatar asked Nov 07 '12 23:11

rheone


People also ask

What are closed generics?

By “Closed Generics” I mean the situation in which the gTLD registry controls registration of all second level domains of the “generic name” of its business or industry. As an example, the new gTLD . book is an open generic gTLD, and anyone should be able to apply for a second level domain name registration under it.

Is it possible to inherit from a generic type?

An attribute cannot inherit from a generic class, nor can a generic class inherit from an attribute.

What does generic <> mean in C#?

Generic means the general form, not specific. In C#, generic means not specific to a particular data type. C# allows you to define generic classes, interfaces, abstract classes, fields, methods, static methods, properties, events, delegates, and operators using the type parameter and without the specific data type.

What is open generic C#?

The C# language defines an open type to be a type that's either a type argument or a generic type defined with unknown type arguments: All types can be classified as either open types or closed types. An open type is a type that involves type parameters. More specifically: A type parameter defines an open type.


1 Answers

I didn't quite follow the question (more due to my sleepiness than anything else), but are you after:

var unclosedTyped = type.GetGenericTypeDefinition();

? (See the docs for details.)

like image 144
Jon Skeet Avatar answered Oct 26 '22 18:10

Jon Skeet