Relation between List and IEnumerable open type











up vote
15
down vote

favorite
5












Is there any relationship between the open types List<> and IEnumerable<>?



Example:



var type1 = typeof(List<>);
var type2 = typeof(IEnumerable<>);

//return false
type2.IsAssignableFrom(type1);


Is there any method to check the relationship between two open type, or the relationship only exist on closed type?










share|improve this question
























  • Relevant: When does Type.FullName return null?
    – John Wu
    Nov 20 at 7:16






  • 1




    Note that each generic parameter is unique. That means List<T(from List<T>)> implement IEnumerable<T(from List<T>)> but not IEnumerable<T(from IEnumerable<T>)>.
    – PetSerAl
    Nov 20 at 7:22






  • 3




    What are you actually trying to accomplish here? If we knew what the initial problem you were trying to solve was, we may be able to offer other solutions that don't rely on comparing open generic types.
    – Damien_The_Unbeliever
    Nov 20 at 7:59










  • Sorry for the drastic edit, but I think only the problem expressed in the first 3 lines is the actually interesting part here. What you were trying to do with the rest of the code was very unclear and you would have had to explain that further as @Damien_The_Unbeliever stated.
    – marsze
    Nov 20 at 9:34










  • @PetSerAl How to understand each generic parameter is unique? Do you mean type int in List<int> and IEnumerable<int> is "diffierent"?
    – YonF
    Nov 21 at 3:12















up vote
15
down vote

favorite
5












Is there any relationship between the open types List<> and IEnumerable<>?



Example:



var type1 = typeof(List<>);
var type2 = typeof(IEnumerable<>);

//return false
type2.IsAssignableFrom(type1);


Is there any method to check the relationship between two open type, or the relationship only exist on closed type?










share|improve this question
























  • Relevant: When does Type.FullName return null?
    – John Wu
    Nov 20 at 7:16






  • 1




    Note that each generic parameter is unique. That means List<T(from List<T>)> implement IEnumerable<T(from List<T>)> but not IEnumerable<T(from IEnumerable<T>)>.
    – PetSerAl
    Nov 20 at 7:22






  • 3




    What are you actually trying to accomplish here? If we knew what the initial problem you were trying to solve was, we may be able to offer other solutions that don't rely on comparing open generic types.
    – Damien_The_Unbeliever
    Nov 20 at 7:59










  • Sorry for the drastic edit, but I think only the problem expressed in the first 3 lines is the actually interesting part here. What you were trying to do with the rest of the code was very unclear and you would have had to explain that further as @Damien_The_Unbeliever stated.
    – marsze
    Nov 20 at 9:34










  • @PetSerAl How to understand each generic parameter is unique? Do you mean type int in List<int> and IEnumerable<int> is "diffierent"?
    – YonF
    Nov 21 at 3:12













up vote
15
down vote

favorite
5









up vote
15
down vote

favorite
5






5





Is there any relationship between the open types List<> and IEnumerable<>?



Example:



var type1 = typeof(List<>);
var type2 = typeof(IEnumerable<>);

//return false
type2.IsAssignableFrom(type1);


Is there any method to check the relationship between two open type, or the relationship only exist on closed type?










share|improve this question















Is there any relationship between the open types List<> and IEnumerable<>?



Example:



var type1 = typeof(List<>);
var type2 = typeof(IEnumerable<>);

//return false
type2.IsAssignableFrom(type1);


Is there any method to check the relationship between two open type, or the relationship only exist on closed type?







c# .net






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 at 9:31









marsze

4,14131640




4,14131640










asked Nov 20 at 7:04









YonF

18610




18610












  • Relevant: When does Type.FullName return null?
    – John Wu
    Nov 20 at 7:16






  • 1




    Note that each generic parameter is unique. That means List<T(from List<T>)> implement IEnumerable<T(from List<T>)> but not IEnumerable<T(from IEnumerable<T>)>.
    – PetSerAl
    Nov 20 at 7:22






  • 3




    What are you actually trying to accomplish here? If we knew what the initial problem you were trying to solve was, we may be able to offer other solutions that don't rely on comparing open generic types.
    – Damien_The_Unbeliever
    Nov 20 at 7:59










  • Sorry for the drastic edit, but I think only the problem expressed in the first 3 lines is the actually interesting part here. What you were trying to do with the rest of the code was very unclear and you would have had to explain that further as @Damien_The_Unbeliever stated.
    – marsze
    Nov 20 at 9:34










  • @PetSerAl How to understand each generic parameter is unique? Do you mean type int in List<int> and IEnumerable<int> is "diffierent"?
    – YonF
    Nov 21 at 3:12


















  • Relevant: When does Type.FullName return null?
    – John Wu
    Nov 20 at 7:16






  • 1




    Note that each generic parameter is unique. That means List<T(from List<T>)> implement IEnumerable<T(from List<T>)> but not IEnumerable<T(from IEnumerable<T>)>.
    – PetSerAl
    Nov 20 at 7:22






  • 3




    What are you actually trying to accomplish here? If we knew what the initial problem you were trying to solve was, we may be able to offer other solutions that don't rely on comparing open generic types.
    – Damien_The_Unbeliever
    Nov 20 at 7:59










  • Sorry for the drastic edit, but I think only the problem expressed in the first 3 lines is the actually interesting part here. What you were trying to do with the rest of the code was very unclear and you would have had to explain that further as @Damien_The_Unbeliever stated.
    – marsze
    Nov 20 at 9:34










  • @PetSerAl How to understand each generic parameter is unique? Do you mean type int in List<int> and IEnumerable<int> is "diffierent"?
    – YonF
    Nov 21 at 3:12
















Relevant: When does Type.FullName return null?
– John Wu
Nov 20 at 7:16




Relevant: When does Type.FullName return null?
– John Wu
Nov 20 at 7:16




1




1




Note that each generic parameter is unique. That means List<T(from List<T>)> implement IEnumerable<T(from List<T>)> but not IEnumerable<T(from IEnumerable<T>)>.
– PetSerAl
Nov 20 at 7:22




Note that each generic parameter is unique. That means List<T(from List<T>)> implement IEnumerable<T(from List<T>)> but not IEnumerable<T(from IEnumerable<T>)>.
– PetSerAl
Nov 20 at 7:22




3




3




What are you actually trying to accomplish here? If we knew what the initial problem you were trying to solve was, we may be able to offer other solutions that don't rely on comparing open generic types.
– Damien_The_Unbeliever
Nov 20 at 7:59




What are you actually trying to accomplish here? If we knew what the initial problem you were trying to solve was, we may be able to offer other solutions that don't rely on comparing open generic types.
– Damien_The_Unbeliever
Nov 20 at 7:59












Sorry for the drastic edit, but I think only the problem expressed in the first 3 lines is the actually interesting part here. What you were trying to do with the rest of the code was very unclear and you would have had to explain that further as @Damien_The_Unbeliever stated.
– marsze
Nov 20 at 9:34




Sorry for the drastic edit, but I think only the problem expressed in the first 3 lines is the actually interesting part here. What you were trying to do with the rest of the code was very unclear and you would have had to explain that further as @Damien_The_Unbeliever stated.
– marsze
Nov 20 at 9:34












@PetSerAl How to understand each generic parameter is unique? Do you mean type int in List<int> and IEnumerable<int> is "diffierent"?
– YonF
Nov 21 at 3:12




@PetSerAl How to understand each generic parameter is unique? Do you mean type int in List<int> and IEnumerable<int> is "diffierent"?
– YonF
Nov 21 at 3:12












2 Answers
2






active

oldest

votes

















up vote
16
down vote













List<> and IEnumerable<> are not types; they are type definitions. As such it doesn't really make sense to ask if one is assignable to the other. Neither can be assigned to. You can't declare a variable List<> a = null, for example-- you will get a compilation error "Unexpected use of an unbound generic name."



A type definition becomes a generic type when you specify the type parameter. At that point, it is a type and can be assigned to. So for example List<string> can be assigned to IEnumerable<string>.



If you have a type definition in mind and you want to do a type-compatibility check, just use <object> (or a suitable type if there is a type constraint) instead of <>:



var type1 = typeof(List<object>);
var type2 = typeof(IEnumerable<object>);

//returns true
type2.IsAssignableFrom(type1);





share|improve this answer























  • Thanks for your answer. It is a brief check method. I can understand type2.IsAssignableFrom(type1) behavior. But do you mean two open generic type are independent or no relationship between them before they become closed type or bounded?
    – YonF
    Nov 21 at 5:32










  • Can you be specific about what you mean when you say "related?" Of course they have certain relationships, and not others.
    – John Wu
    Nov 21 at 6:38










  • A relationship such as inheritance, implimentation but not inheritance and implimentation. But I am not sure whether any kind relatioinship exist between open generic type themselves. @Jevgeni Geurtsen think the special relationship list AssignableFrom exist.
    – YonF
    Nov 21 at 7:07










  • Believe it or not, generic type definitions do not have any implementation. The implementation is compiled only when you specify the type parameter, and only for that type (although implementations for reference types can be re-used because all pointers are the same size, but that is just an implementation detail). So you see to ask whether List<> implements IEnumerable<> doesn't make much sense because it has no implementation to begin with.
    – John Wu
    Nov 21 at 7:15










  • @Jevgeni Geurtsen think the special relationship list AssignableFrom exist. Oh but it is most definitely there in the framework code, so the relation exists, but as long as it doesn't have a concrete implementation, its useless, as John Wu pointed out.
    – Jevgeni Geurtsen
    Nov 21 at 8:16


















up vote
13
down vote













Although John Wu wrote up a nice answer about the differences between a type definition and actual types I don't think it fully answers the problem/question asked in the OP.




Is there any method to check the relationship between two open type,
or the relationship only exist on closed type?




First of all, the relationship always exists; every List<> is always an IEnumerable<>, as you can see in the definition of the List<T> type:



public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, ...



But this doesn't answer your second question, if there is a way to check if such a relationship exists between two types. You would think that the IsAssignableFrom method can be used to check for existence of a relationship between the type open types, but you can't. Why? Lets find out in the documentation of the IsAssignableFrom function:




Type.IsAssignableFrom (Type c) Returns true if any of the following conditions is true:




  1. c and the current instance represent the same type.

  2. c is derived either directly or indirectly from the current
    instance. c is derived directly from the current instance if it
    inherits from the current instance; c is derived indirectly from the
    current instance if it inherits from a succession of one or more
    classes that inherit from the current instance.


  3. The current instance is an interface that c implements.


  4. c is a generic type parameter, and the current instance represents
    one of the constraints of c.



and false if none of these conditions are true, or if c is null.




In your case, none of the above mentioned conditions will result in true as: (1) they are not the same type. (2) They cannot be derived from each other as they are open types: their generic type parameters are unknown (unknown != unknown). The List<> implements the closed IEnumerable<T> type and not the open IEnumerable<> type (3). They aren't generic type parameters (4).



To find out if two generic types have a relationship, you would need to inspect their type definitions (and their nested interfaces/base types) and validate that they have a relationship:



public static bool IsAssignableToOpenGenericType(Type givenType, Type genericType)
{
var interfaceTypes = givenType.GetInterfaces();

foreach (var it in interfaceTypes)
{
if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
return true;
}

if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
return true;

Type baseType = givenType.BaseType;
if (baseType == null) return false;

return IsAssignableToGenericType(baseType, genericType);
}


(source)



Will result in:



    var typ1 = typeof(List<>);
var typ2 = typeof(IEnumerable<>);

// true, List<>'s type definition contains an IEnumerable<>
Console.WriteLine(IsAssignableToOpenGenericType(typ1, typ2));
// false, IEnumerable<>'s type definition does not contain List<>
Console.WriteLine(IsAssignableToOpenGenericType(typ2, typ1));





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53387828%2frelation-between-list-and-ienumerable-open-type%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    16
    down vote













    List<> and IEnumerable<> are not types; they are type definitions. As such it doesn't really make sense to ask if one is assignable to the other. Neither can be assigned to. You can't declare a variable List<> a = null, for example-- you will get a compilation error "Unexpected use of an unbound generic name."



    A type definition becomes a generic type when you specify the type parameter. At that point, it is a type and can be assigned to. So for example List<string> can be assigned to IEnumerable<string>.



    If you have a type definition in mind and you want to do a type-compatibility check, just use <object> (or a suitable type if there is a type constraint) instead of <>:



    var type1 = typeof(List<object>);
    var type2 = typeof(IEnumerable<object>);

    //returns true
    type2.IsAssignableFrom(type1);





    share|improve this answer























    • Thanks for your answer. It is a brief check method. I can understand type2.IsAssignableFrom(type1) behavior. But do you mean two open generic type are independent or no relationship between them before they become closed type or bounded?
      – YonF
      Nov 21 at 5:32










    • Can you be specific about what you mean when you say "related?" Of course they have certain relationships, and not others.
      – John Wu
      Nov 21 at 6:38










    • A relationship such as inheritance, implimentation but not inheritance and implimentation. But I am not sure whether any kind relatioinship exist between open generic type themselves. @Jevgeni Geurtsen think the special relationship list AssignableFrom exist.
      – YonF
      Nov 21 at 7:07










    • Believe it or not, generic type definitions do not have any implementation. The implementation is compiled only when you specify the type parameter, and only for that type (although implementations for reference types can be re-used because all pointers are the same size, but that is just an implementation detail). So you see to ask whether List<> implements IEnumerable<> doesn't make much sense because it has no implementation to begin with.
      – John Wu
      Nov 21 at 7:15










    • @Jevgeni Geurtsen think the special relationship list AssignableFrom exist. Oh but it is most definitely there in the framework code, so the relation exists, but as long as it doesn't have a concrete implementation, its useless, as John Wu pointed out.
      – Jevgeni Geurtsen
      Nov 21 at 8:16















    up vote
    16
    down vote













    List<> and IEnumerable<> are not types; they are type definitions. As such it doesn't really make sense to ask if one is assignable to the other. Neither can be assigned to. You can't declare a variable List<> a = null, for example-- you will get a compilation error "Unexpected use of an unbound generic name."



    A type definition becomes a generic type when you specify the type parameter. At that point, it is a type and can be assigned to. So for example List<string> can be assigned to IEnumerable<string>.



    If you have a type definition in mind and you want to do a type-compatibility check, just use <object> (or a suitable type if there is a type constraint) instead of <>:



    var type1 = typeof(List<object>);
    var type2 = typeof(IEnumerable<object>);

    //returns true
    type2.IsAssignableFrom(type1);





    share|improve this answer























    • Thanks for your answer. It is a brief check method. I can understand type2.IsAssignableFrom(type1) behavior. But do you mean two open generic type are independent or no relationship between them before they become closed type or bounded?
      – YonF
      Nov 21 at 5:32










    • Can you be specific about what you mean when you say "related?" Of course they have certain relationships, and not others.
      – John Wu
      Nov 21 at 6:38










    • A relationship such as inheritance, implimentation but not inheritance and implimentation. But I am not sure whether any kind relatioinship exist between open generic type themselves. @Jevgeni Geurtsen think the special relationship list AssignableFrom exist.
      – YonF
      Nov 21 at 7:07










    • Believe it or not, generic type definitions do not have any implementation. The implementation is compiled only when you specify the type parameter, and only for that type (although implementations for reference types can be re-used because all pointers are the same size, but that is just an implementation detail). So you see to ask whether List<> implements IEnumerable<> doesn't make much sense because it has no implementation to begin with.
      – John Wu
      Nov 21 at 7:15










    • @Jevgeni Geurtsen think the special relationship list AssignableFrom exist. Oh but it is most definitely there in the framework code, so the relation exists, but as long as it doesn't have a concrete implementation, its useless, as John Wu pointed out.
      – Jevgeni Geurtsen
      Nov 21 at 8:16













    up vote
    16
    down vote










    up vote
    16
    down vote









    List<> and IEnumerable<> are not types; they are type definitions. As such it doesn't really make sense to ask if one is assignable to the other. Neither can be assigned to. You can't declare a variable List<> a = null, for example-- you will get a compilation error "Unexpected use of an unbound generic name."



    A type definition becomes a generic type when you specify the type parameter. At that point, it is a type and can be assigned to. So for example List<string> can be assigned to IEnumerable<string>.



    If you have a type definition in mind and you want to do a type-compatibility check, just use <object> (or a suitable type if there is a type constraint) instead of <>:



    var type1 = typeof(List<object>);
    var type2 = typeof(IEnumerable<object>);

    //returns true
    type2.IsAssignableFrom(type1);





    share|improve this answer














    List<> and IEnumerable<> are not types; they are type definitions. As such it doesn't really make sense to ask if one is assignable to the other. Neither can be assigned to. You can't declare a variable List<> a = null, for example-- you will get a compilation error "Unexpected use of an unbound generic name."



    A type definition becomes a generic type when you specify the type parameter. At that point, it is a type and can be assigned to. So for example List<string> can be assigned to IEnumerable<string>.



    If you have a type definition in mind and you want to do a type-compatibility check, just use <object> (or a suitable type if there is a type constraint) instead of <>:



    var type1 = typeof(List<object>);
    var type2 = typeof(IEnumerable<object>);

    //returns true
    type2.IsAssignableFrom(type1);






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 20 at 11:46









    vaxquis

    7,37653656




    7,37653656










    answered Nov 20 at 8:42









    John Wu

    28.9k42652




    28.9k42652












    • Thanks for your answer. It is a brief check method. I can understand type2.IsAssignableFrom(type1) behavior. But do you mean two open generic type are independent or no relationship between them before they become closed type or bounded?
      – YonF
      Nov 21 at 5:32










    • Can you be specific about what you mean when you say "related?" Of course they have certain relationships, and not others.
      – John Wu
      Nov 21 at 6:38










    • A relationship such as inheritance, implimentation but not inheritance and implimentation. But I am not sure whether any kind relatioinship exist between open generic type themselves. @Jevgeni Geurtsen think the special relationship list AssignableFrom exist.
      – YonF
      Nov 21 at 7:07










    • Believe it or not, generic type definitions do not have any implementation. The implementation is compiled only when you specify the type parameter, and only for that type (although implementations for reference types can be re-used because all pointers are the same size, but that is just an implementation detail). So you see to ask whether List<> implements IEnumerable<> doesn't make much sense because it has no implementation to begin with.
      – John Wu
      Nov 21 at 7:15










    • @Jevgeni Geurtsen think the special relationship list AssignableFrom exist. Oh but it is most definitely there in the framework code, so the relation exists, but as long as it doesn't have a concrete implementation, its useless, as John Wu pointed out.
      – Jevgeni Geurtsen
      Nov 21 at 8:16


















    • Thanks for your answer. It is a brief check method. I can understand type2.IsAssignableFrom(type1) behavior. But do you mean two open generic type are independent or no relationship between them before they become closed type or bounded?
      – YonF
      Nov 21 at 5:32










    • Can you be specific about what you mean when you say "related?" Of course they have certain relationships, and not others.
      – John Wu
      Nov 21 at 6:38










    • A relationship such as inheritance, implimentation but not inheritance and implimentation. But I am not sure whether any kind relatioinship exist between open generic type themselves. @Jevgeni Geurtsen think the special relationship list AssignableFrom exist.
      – YonF
      Nov 21 at 7:07










    • Believe it or not, generic type definitions do not have any implementation. The implementation is compiled only when you specify the type parameter, and only for that type (although implementations for reference types can be re-used because all pointers are the same size, but that is just an implementation detail). So you see to ask whether List<> implements IEnumerable<> doesn't make much sense because it has no implementation to begin with.
      – John Wu
      Nov 21 at 7:15










    • @Jevgeni Geurtsen think the special relationship list AssignableFrom exist. Oh but it is most definitely there in the framework code, so the relation exists, but as long as it doesn't have a concrete implementation, its useless, as John Wu pointed out.
      – Jevgeni Geurtsen
      Nov 21 at 8:16
















    Thanks for your answer. It is a brief check method. I can understand type2.IsAssignableFrom(type1) behavior. But do you mean two open generic type are independent or no relationship between them before they become closed type or bounded?
    – YonF
    Nov 21 at 5:32




    Thanks for your answer. It is a brief check method. I can understand type2.IsAssignableFrom(type1) behavior. But do you mean two open generic type are independent or no relationship between them before they become closed type or bounded?
    – YonF
    Nov 21 at 5:32












    Can you be specific about what you mean when you say "related?" Of course they have certain relationships, and not others.
    – John Wu
    Nov 21 at 6:38




    Can you be specific about what you mean when you say "related?" Of course they have certain relationships, and not others.
    – John Wu
    Nov 21 at 6:38












    A relationship such as inheritance, implimentation but not inheritance and implimentation. But I am not sure whether any kind relatioinship exist between open generic type themselves. @Jevgeni Geurtsen think the special relationship list AssignableFrom exist.
    – YonF
    Nov 21 at 7:07




    A relationship such as inheritance, implimentation but not inheritance and implimentation. But I am not sure whether any kind relatioinship exist between open generic type themselves. @Jevgeni Geurtsen think the special relationship list AssignableFrom exist.
    – YonF
    Nov 21 at 7:07












    Believe it or not, generic type definitions do not have any implementation. The implementation is compiled only when you specify the type parameter, and only for that type (although implementations for reference types can be re-used because all pointers are the same size, but that is just an implementation detail). So you see to ask whether List<> implements IEnumerable<> doesn't make much sense because it has no implementation to begin with.
    – John Wu
    Nov 21 at 7:15




    Believe it or not, generic type definitions do not have any implementation. The implementation is compiled only when you specify the type parameter, and only for that type (although implementations for reference types can be re-used because all pointers are the same size, but that is just an implementation detail). So you see to ask whether List<> implements IEnumerable<> doesn't make much sense because it has no implementation to begin with.
    – John Wu
    Nov 21 at 7:15












    @Jevgeni Geurtsen think the special relationship list AssignableFrom exist. Oh but it is most definitely there in the framework code, so the relation exists, but as long as it doesn't have a concrete implementation, its useless, as John Wu pointed out.
    – Jevgeni Geurtsen
    Nov 21 at 8:16




    @Jevgeni Geurtsen think the special relationship list AssignableFrom exist. Oh but it is most definitely there in the framework code, so the relation exists, but as long as it doesn't have a concrete implementation, its useless, as John Wu pointed out.
    – Jevgeni Geurtsen
    Nov 21 at 8:16












    up vote
    13
    down vote













    Although John Wu wrote up a nice answer about the differences between a type definition and actual types I don't think it fully answers the problem/question asked in the OP.




    Is there any method to check the relationship between two open type,
    or the relationship only exist on closed type?




    First of all, the relationship always exists; every List<> is always an IEnumerable<>, as you can see in the definition of the List<T> type:



    public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, ...



    But this doesn't answer your second question, if there is a way to check if such a relationship exists between two types. You would think that the IsAssignableFrom method can be used to check for existence of a relationship between the type open types, but you can't. Why? Lets find out in the documentation of the IsAssignableFrom function:




    Type.IsAssignableFrom (Type c) Returns true if any of the following conditions is true:




    1. c and the current instance represent the same type.

    2. c is derived either directly or indirectly from the current
      instance. c is derived directly from the current instance if it
      inherits from the current instance; c is derived indirectly from the
      current instance if it inherits from a succession of one or more
      classes that inherit from the current instance.


    3. The current instance is an interface that c implements.


    4. c is a generic type parameter, and the current instance represents
      one of the constraints of c.



    and false if none of these conditions are true, or if c is null.




    In your case, none of the above mentioned conditions will result in true as: (1) they are not the same type. (2) They cannot be derived from each other as they are open types: their generic type parameters are unknown (unknown != unknown). The List<> implements the closed IEnumerable<T> type and not the open IEnumerable<> type (3). They aren't generic type parameters (4).



    To find out if two generic types have a relationship, you would need to inspect their type definitions (and their nested interfaces/base types) and validate that they have a relationship:



    public static bool IsAssignableToOpenGenericType(Type givenType, Type genericType)
    {
    var interfaceTypes = givenType.GetInterfaces();

    foreach (var it in interfaceTypes)
    {
    if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
    return true;
    }

    if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
    return true;

    Type baseType = givenType.BaseType;
    if (baseType == null) return false;

    return IsAssignableToGenericType(baseType, genericType);
    }


    (source)



    Will result in:



        var typ1 = typeof(List<>);
    var typ2 = typeof(IEnumerable<>);

    // true, List<>'s type definition contains an IEnumerable<>
    Console.WriteLine(IsAssignableToOpenGenericType(typ1, typ2));
    // false, IEnumerable<>'s type definition does not contain List<>
    Console.WriteLine(IsAssignableToOpenGenericType(typ2, typ1));





    share|improve this answer



























      up vote
      13
      down vote













      Although John Wu wrote up a nice answer about the differences between a type definition and actual types I don't think it fully answers the problem/question asked in the OP.




      Is there any method to check the relationship between two open type,
      or the relationship only exist on closed type?




      First of all, the relationship always exists; every List<> is always an IEnumerable<>, as you can see in the definition of the List<T> type:



      public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, ...



      But this doesn't answer your second question, if there is a way to check if such a relationship exists between two types. You would think that the IsAssignableFrom method can be used to check for existence of a relationship between the type open types, but you can't. Why? Lets find out in the documentation of the IsAssignableFrom function:




      Type.IsAssignableFrom (Type c) Returns true if any of the following conditions is true:




      1. c and the current instance represent the same type.

      2. c is derived either directly or indirectly from the current
        instance. c is derived directly from the current instance if it
        inherits from the current instance; c is derived indirectly from the
        current instance if it inherits from a succession of one or more
        classes that inherit from the current instance.


      3. The current instance is an interface that c implements.


      4. c is a generic type parameter, and the current instance represents
        one of the constraints of c.



      and false if none of these conditions are true, or if c is null.




      In your case, none of the above mentioned conditions will result in true as: (1) they are not the same type. (2) They cannot be derived from each other as they are open types: their generic type parameters are unknown (unknown != unknown). The List<> implements the closed IEnumerable<T> type and not the open IEnumerable<> type (3). They aren't generic type parameters (4).



      To find out if two generic types have a relationship, you would need to inspect their type definitions (and their nested interfaces/base types) and validate that they have a relationship:



      public static bool IsAssignableToOpenGenericType(Type givenType, Type genericType)
      {
      var interfaceTypes = givenType.GetInterfaces();

      foreach (var it in interfaceTypes)
      {
      if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
      return true;
      }

      if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
      return true;

      Type baseType = givenType.BaseType;
      if (baseType == null) return false;

      return IsAssignableToGenericType(baseType, genericType);
      }


      (source)



      Will result in:



          var typ1 = typeof(List<>);
      var typ2 = typeof(IEnumerable<>);

      // true, List<>'s type definition contains an IEnumerable<>
      Console.WriteLine(IsAssignableToOpenGenericType(typ1, typ2));
      // false, IEnumerable<>'s type definition does not contain List<>
      Console.WriteLine(IsAssignableToOpenGenericType(typ2, typ1));





      share|improve this answer

























        up vote
        13
        down vote










        up vote
        13
        down vote









        Although John Wu wrote up a nice answer about the differences between a type definition and actual types I don't think it fully answers the problem/question asked in the OP.




        Is there any method to check the relationship between two open type,
        or the relationship only exist on closed type?




        First of all, the relationship always exists; every List<> is always an IEnumerable<>, as you can see in the definition of the List<T> type:



        public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, ...



        But this doesn't answer your second question, if there is a way to check if such a relationship exists between two types. You would think that the IsAssignableFrom method can be used to check for existence of a relationship between the type open types, but you can't. Why? Lets find out in the documentation of the IsAssignableFrom function:




        Type.IsAssignableFrom (Type c) Returns true if any of the following conditions is true:




        1. c and the current instance represent the same type.

        2. c is derived either directly or indirectly from the current
          instance. c is derived directly from the current instance if it
          inherits from the current instance; c is derived indirectly from the
          current instance if it inherits from a succession of one or more
          classes that inherit from the current instance.


        3. The current instance is an interface that c implements.


        4. c is a generic type parameter, and the current instance represents
          one of the constraints of c.



        and false if none of these conditions are true, or if c is null.




        In your case, none of the above mentioned conditions will result in true as: (1) they are not the same type. (2) They cannot be derived from each other as they are open types: their generic type parameters are unknown (unknown != unknown). The List<> implements the closed IEnumerable<T> type and not the open IEnumerable<> type (3). They aren't generic type parameters (4).



        To find out if two generic types have a relationship, you would need to inspect their type definitions (and their nested interfaces/base types) and validate that they have a relationship:



        public static bool IsAssignableToOpenGenericType(Type givenType, Type genericType)
        {
        var interfaceTypes = givenType.GetInterfaces();

        foreach (var it in interfaceTypes)
        {
        if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
        return true;
        }

        if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
        return true;

        Type baseType = givenType.BaseType;
        if (baseType == null) return false;

        return IsAssignableToGenericType(baseType, genericType);
        }


        (source)



        Will result in:



            var typ1 = typeof(List<>);
        var typ2 = typeof(IEnumerable<>);

        // true, List<>'s type definition contains an IEnumerable<>
        Console.WriteLine(IsAssignableToOpenGenericType(typ1, typ2));
        // false, IEnumerable<>'s type definition does not contain List<>
        Console.WriteLine(IsAssignableToOpenGenericType(typ2, typ1));





        share|improve this answer














        Although John Wu wrote up a nice answer about the differences between a type definition and actual types I don't think it fully answers the problem/question asked in the OP.




        Is there any method to check the relationship between two open type,
        or the relationship only exist on closed type?




        First of all, the relationship always exists; every List<> is always an IEnumerable<>, as you can see in the definition of the List<T> type:



        public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, ...



        But this doesn't answer your second question, if there is a way to check if such a relationship exists between two types. You would think that the IsAssignableFrom method can be used to check for existence of a relationship between the type open types, but you can't. Why? Lets find out in the documentation of the IsAssignableFrom function:




        Type.IsAssignableFrom (Type c) Returns true if any of the following conditions is true:




        1. c and the current instance represent the same type.

        2. c is derived either directly or indirectly from the current
          instance. c is derived directly from the current instance if it
          inherits from the current instance; c is derived indirectly from the
          current instance if it inherits from a succession of one or more
          classes that inherit from the current instance.


        3. The current instance is an interface that c implements.


        4. c is a generic type parameter, and the current instance represents
          one of the constraints of c.



        and false if none of these conditions are true, or if c is null.




        In your case, none of the above mentioned conditions will result in true as: (1) they are not the same type. (2) They cannot be derived from each other as they are open types: their generic type parameters are unknown (unknown != unknown). The List<> implements the closed IEnumerable<T> type and not the open IEnumerable<> type (3). They aren't generic type parameters (4).



        To find out if two generic types have a relationship, you would need to inspect their type definitions (and their nested interfaces/base types) and validate that they have a relationship:



        public static bool IsAssignableToOpenGenericType(Type givenType, Type genericType)
        {
        var interfaceTypes = givenType.GetInterfaces();

        foreach (var it in interfaceTypes)
        {
        if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
        return true;
        }

        if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
        return true;

        Type baseType = givenType.BaseType;
        if (baseType == null) return false;

        return IsAssignableToGenericType(baseType, genericType);
        }


        (source)



        Will result in:



            var typ1 = typeof(List<>);
        var typ2 = typeof(IEnumerable<>);

        // true, List<>'s type definition contains an IEnumerable<>
        Console.WriteLine(IsAssignableToOpenGenericType(typ1, typ2));
        // false, IEnumerable<>'s type definition does not contain List<>
        Console.WriteLine(IsAssignableToOpenGenericType(typ2, typ1));






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 20 at 10:39

























        answered Nov 20 at 9:11









        Jevgeni Geurtsen

        2,54641231




        2,54641231






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53387828%2frelation-between-list-and-ienumerable-open-type%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Сан-Квентин

            8-я гвардейская общевойсковая армия

            Алькесар