How to call a method with a generic constraint using a type parameter without the constraint?












3















Let's say I have a method:



public void ExampleMethod<T>(T x) where T : struct // or new()
{
// example usage, similar to what's actually happening
var z = (T)Enum.Parse(typeof(T), privateFieldOfTypeString);

// do something depending on values of x and z
// possibly using other methods that require them being enums

// or in case of the new() constraint:
// var t = new T() and do something together with x
}


and I want to use it as follows:



public void CallerMethod<S>(S y)
{
if (typeof(S).IsEnum) // or some other invariant meaning that `S` is "new()able"
{
ExampleMethod(y); // won't compile
}
}


So, during run-time I know that S satisfies the constraint for ExampleMethod<T>. I know it's possible to call it using reflection, something along the lines of:



this
.GetType()
.GetMethod(nameof(ExampleMethod<object>))
.MakeGenericMethod(typeof(S))
.Invoke(this, new object { y });


Is it possible without reflection?



Note: this is a simplified code from a real-life example and obviously I have no control over the signatures of these methods, hence the answers "add the constraint to CallerMethod" and "remove the constraint from ExampleMethod" are invalid.



Yes, the whole thing should be redesigned so the whole problem wouldn't appear at all. But as often in real-life "the whole thing" is too big, too coupled and too risky to rewrite. Some requirements have changed in an unexpected way - hence the apparent code smell, which I'm trying to minimize by hiding it in a single nasty-looking place.










share|improve this question

























  • You know that S satisfies the constraint for ExampleMethod<T>, but the compiler does not. You would need to add the constraint to CallerMethod if possible. That is the nature of generic members.

    – Nkosi
    Nov 23 '18 at 9:41













  • @Nkosi Going along your formulation: the question is "how to inform the compiler about this fact". An analogy from outside of generics is casting - you tell the compiler that you know that a particular variable is of a particular type.

    – BartoszKP
    Nov 23 '18 at 9:43













  • casting is runtime

    – JohnB
    Nov 23 '18 at 9:44











  • @BartoszKP I am at a loss in the simplified example of how the two methods would come to interact with each other. Could some context be provided to get an idea of the intended goal so as to rule this out as an XY problem.

    – Nkosi
    Nov 23 '18 at 9:50











  • @Nkosi I don't think so. The details are irrelevant, and this is the fact that I'm stuck with such two methods and I need to call one from another. They are on different types and different assemblies, but these details are really irrelevant. I am fully aware that the whole thing should be redesigned so this problem wouldn't appear at all. IMHO the question is clear - is it possible, and if yes - how? The possible expected answers are easy to imagine: "no, it's not possible, by the language rules/compiler restrictions" or "yes, it's possible, this is how".

    – BartoszKP
    Nov 23 '18 at 9:55


















3















Let's say I have a method:



public void ExampleMethod<T>(T x) where T : struct // or new()
{
// example usage, similar to what's actually happening
var z = (T)Enum.Parse(typeof(T), privateFieldOfTypeString);

// do something depending on values of x and z
// possibly using other methods that require them being enums

// or in case of the new() constraint:
// var t = new T() and do something together with x
}


and I want to use it as follows:



public void CallerMethod<S>(S y)
{
if (typeof(S).IsEnum) // or some other invariant meaning that `S` is "new()able"
{
ExampleMethod(y); // won't compile
}
}


So, during run-time I know that S satisfies the constraint for ExampleMethod<T>. I know it's possible to call it using reflection, something along the lines of:



this
.GetType()
.GetMethod(nameof(ExampleMethod<object>))
.MakeGenericMethod(typeof(S))
.Invoke(this, new object { y });


Is it possible without reflection?



Note: this is a simplified code from a real-life example and obviously I have no control over the signatures of these methods, hence the answers "add the constraint to CallerMethod" and "remove the constraint from ExampleMethod" are invalid.



Yes, the whole thing should be redesigned so the whole problem wouldn't appear at all. But as often in real-life "the whole thing" is too big, too coupled and too risky to rewrite. Some requirements have changed in an unexpected way - hence the apparent code smell, which I'm trying to minimize by hiding it in a single nasty-looking place.










share|improve this question

























  • You know that S satisfies the constraint for ExampleMethod<T>, but the compiler does not. You would need to add the constraint to CallerMethod if possible. That is the nature of generic members.

    – Nkosi
    Nov 23 '18 at 9:41













  • @Nkosi Going along your formulation: the question is "how to inform the compiler about this fact". An analogy from outside of generics is casting - you tell the compiler that you know that a particular variable is of a particular type.

    – BartoszKP
    Nov 23 '18 at 9:43













  • casting is runtime

    – JohnB
    Nov 23 '18 at 9:44











  • @BartoszKP I am at a loss in the simplified example of how the two methods would come to interact with each other. Could some context be provided to get an idea of the intended goal so as to rule this out as an XY problem.

    – Nkosi
    Nov 23 '18 at 9:50











  • @Nkosi I don't think so. The details are irrelevant, and this is the fact that I'm stuck with such two methods and I need to call one from another. They are on different types and different assemblies, but these details are really irrelevant. I am fully aware that the whole thing should be redesigned so this problem wouldn't appear at all. IMHO the question is clear - is it possible, and if yes - how? The possible expected answers are easy to imagine: "no, it's not possible, by the language rules/compiler restrictions" or "yes, it's possible, this is how".

    – BartoszKP
    Nov 23 '18 at 9:55
















3












3








3


1






Let's say I have a method:



public void ExampleMethod<T>(T x) where T : struct // or new()
{
// example usage, similar to what's actually happening
var z = (T)Enum.Parse(typeof(T), privateFieldOfTypeString);

// do something depending on values of x and z
// possibly using other methods that require them being enums

// or in case of the new() constraint:
// var t = new T() and do something together with x
}


and I want to use it as follows:



public void CallerMethod<S>(S y)
{
if (typeof(S).IsEnum) // or some other invariant meaning that `S` is "new()able"
{
ExampleMethod(y); // won't compile
}
}


So, during run-time I know that S satisfies the constraint for ExampleMethod<T>. I know it's possible to call it using reflection, something along the lines of:



this
.GetType()
.GetMethod(nameof(ExampleMethod<object>))
.MakeGenericMethod(typeof(S))
.Invoke(this, new object { y });


Is it possible without reflection?



Note: this is a simplified code from a real-life example and obviously I have no control over the signatures of these methods, hence the answers "add the constraint to CallerMethod" and "remove the constraint from ExampleMethod" are invalid.



Yes, the whole thing should be redesigned so the whole problem wouldn't appear at all. But as often in real-life "the whole thing" is too big, too coupled and too risky to rewrite. Some requirements have changed in an unexpected way - hence the apparent code smell, which I'm trying to minimize by hiding it in a single nasty-looking place.










share|improve this question
















Let's say I have a method:



public void ExampleMethod<T>(T x) where T : struct // or new()
{
// example usage, similar to what's actually happening
var z = (T)Enum.Parse(typeof(T), privateFieldOfTypeString);

// do something depending on values of x and z
// possibly using other methods that require them being enums

// or in case of the new() constraint:
// var t = new T() and do something together with x
}


and I want to use it as follows:



public void CallerMethod<S>(S y)
{
if (typeof(S).IsEnum) // or some other invariant meaning that `S` is "new()able"
{
ExampleMethod(y); // won't compile
}
}


So, during run-time I know that S satisfies the constraint for ExampleMethod<T>. I know it's possible to call it using reflection, something along the lines of:



this
.GetType()
.GetMethod(nameof(ExampleMethod<object>))
.MakeGenericMethod(typeof(S))
.Invoke(this, new object { y });


Is it possible without reflection?



Note: this is a simplified code from a real-life example and obviously I have no control over the signatures of these methods, hence the answers "add the constraint to CallerMethod" and "remove the constraint from ExampleMethod" are invalid.



Yes, the whole thing should be redesigned so the whole problem wouldn't appear at all. But as often in real-life "the whole thing" is too big, too coupled and too risky to rewrite. Some requirements have changed in an unexpected way - hence the apparent code smell, which I'm trying to minimize by hiding it in a single nasty-looking place.







c# generics generic-constraints






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 12:46







BartoszKP

















asked Nov 23 '18 at 9:37









BartoszKPBartoszKP

27k1070107




27k1070107













  • You know that S satisfies the constraint for ExampleMethod<T>, but the compiler does not. You would need to add the constraint to CallerMethod if possible. That is the nature of generic members.

    – Nkosi
    Nov 23 '18 at 9:41













  • @Nkosi Going along your formulation: the question is "how to inform the compiler about this fact". An analogy from outside of generics is casting - you tell the compiler that you know that a particular variable is of a particular type.

    – BartoszKP
    Nov 23 '18 at 9:43













  • casting is runtime

    – JohnB
    Nov 23 '18 at 9:44











  • @BartoszKP I am at a loss in the simplified example of how the two methods would come to interact with each other. Could some context be provided to get an idea of the intended goal so as to rule this out as an XY problem.

    – Nkosi
    Nov 23 '18 at 9:50











  • @Nkosi I don't think so. The details are irrelevant, and this is the fact that I'm stuck with such two methods and I need to call one from another. They are on different types and different assemblies, but these details are really irrelevant. I am fully aware that the whole thing should be redesigned so this problem wouldn't appear at all. IMHO the question is clear - is it possible, and if yes - how? The possible expected answers are easy to imagine: "no, it's not possible, by the language rules/compiler restrictions" or "yes, it's possible, this is how".

    – BartoszKP
    Nov 23 '18 at 9:55





















  • You know that S satisfies the constraint for ExampleMethod<T>, but the compiler does not. You would need to add the constraint to CallerMethod if possible. That is the nature of generic members.

    – Nkosi
    Nov 23 '18 at 9:41













  • @Nkosi Going along your formulation: the question is "how to inform the compiler about this fact". An analogy from outside of generics is casting - you tell the compiler that you know that a particular variable is of a particular type.

    – BartoszKP
    Nov 23 '18 at 9:43













  • casting is runtime

    – JohnB
    Nov 23 '18 at 9:44











  • @BartoszKP I am at a loss in the simplified example of how the two methods would come to interact with each other. Could some context be provided to get an idea of the intended goal so as to rule this out as an XY problem.

    – Nkosi
    Nov 23 '18 at 9:50











  • @Nkosi I don't think so. The details are irrelevant, and this is the fact that I'm stuck with such two methods and I need to call one from another. They are on different types and different assemblies, but these details are really irrelevant. I am fully aware that the whole thing should be redesigned so this problem wouldn't appear at all. IMHO the question is clear - is it possible, and if yes - how? The possible expected answers are easy to imagine: "no, it's not possible, by the language rules/compiler restrictions" or "yes, it's possible, this is how".

    – BartoszKP
    Nov 23 '18 at 9:55



















You know that S satisfies the constraint for ExampleMethod<T>, but the compiler does not. You would need to add the constraint to CallerMethod if possible. That is the nature of generic members.

– Nkosi
Nov 23 '18 at 9:41







You know that S satisfies the constraint for ExampleMethod<T>, but the compiler does not. You would need to add the constraint to CallerMethod if possible. That is the nature of generic members.

– Nkosi
Nov 23 '18 at 9:41















@Nkosi Going along your formulation: the question is "how to inform the compiler about this fact". An analogy from outside of generics is casting - you tell the compiler that you know that a particular variable is of a particular type.

– BartoszKP
Nov 23 '18 at 9:43







@Nkosi Going along your formulation: the question is "how to inform the compiler about this fact". An analogy from outside of generics is casting - you tell the compiler that you know that a particular variable is of a particular type.

– BartoszKP
Nov 23 '18 at 9:43















casting is runtime

– JohnB
Nov 23 '18 at 9:44





casting is runtime

– JohnB
Nov 23 '18 at 9:44













@BartoszKP I am at a loss in the simplified example of how the two methods would come to interact with each other. Could some context be provided to get an idea of the intended goal so as to rule this out as an XY problem.

– Nkosi
Nov 23 '18 at 9:50





@BartoszKP I am at a loss in the simplified example of how the two methods would come to interact with each other. Could some context be provided to get an idea of the intended goal so as to rule this out as an XY problem.

– Nkosi
Nov 23 '18 at 9:50













@Nkosi I don't think so. The details are irrelevant, and this is the fact that I'm stuck with such two methods and I need to call one from another. They are on different types and different assemblies, but these details are really irrelevant. I am fully aware that the whole thing should be redesigned so this problem wouldn't appear at all. IMHO the question is clear - is it possible, and if yes - how? The possible expected answers are easy to imagine: "no, it's not possible, by the language rules/compiler restrictions" or "yes, it's possible, this is how".

– BartoszKP
Nov 23 '18 at 9:55







@Nkosi I don't think so. The details are irrelevant, and this is the fact that I'm stuck with such two methods and I need to call one from another. They are on different types and different assemblies, but these details are really irrelevant. I am fully aware that the whole thing should be redesigned so this problem wouldn't appear at all. IMHO the question is clear - is it possible, and if yes - how? The possible expected answers are easy to imagine: "no, it's not possible, by the language rules/compiler restrictions" or "yes, it's possible, this is how".

– BartoszKP
Nov 23 '18 at 9:55














4 Answers
4






active

oldest

votes


















3














You could use dynamic:



if (typeof(S).IsEnum)
{
ExampleMethod((dynamic)y);
}





share|improve this answer



















  • 1





    Which is of course just a nice way of hiding reflection-like activity

    – Damien_The_Unbeliever
    Nov 23 '18 at 9:46











  • Thanks, didn't think of that. Even though what @Damien_The_Unbeliever said :)

    – BartoszKP
    Nov 23 '18 at 9:51



















1














If the enum types are known, one possibility, though verbose, would be to convert to known types.



For example, as a starting point,



public void CallerMethod<S>(S y) {
if (typeof(S).IsEnum) {
if (y is KnownEnum) {
var z = (KnownEnum)Enum.Parse(typeof(S), y.ToString());
ExampleMethod(z);
}
if (y is KnownEnum2) {
var z = (KnownEnum2)Enum.Parse(typeof(S), y.ToString());
ExampleMethod(z);
}
//...
}
}





share|improve this answer
























  • Would work, thanks. However this approach is unmaintainable when the number of enums is big/unknown/subject to change.

    – BartoszKP
    Nov 23 '18 at 11:02











  • My thoughts as well. looking into alternatives

    – Nkosi
    Nov 23 '18 at 11:04





















1














You could utilise operator overloading; define multiple explicit versions of CallerMethod that can all successfully make a follow on call to ExampleMethod



CallerMethod(Enum1 value) { ExampleMethod(value); }
CallerMethod(Enum2 value) { ExampleMethod(value); }
CallerMethod(Enum3 value) { ExampleMethod(value); }


etc.



If there are a large number of growing types that need a version of CallerMethod you could write a T4 template to generate a partial class with all implementations.






share|improve this answer































    -2














    In your specific case you can just cast to an int.



    public void CallerMethod<S>(S y)
    {
    if (typeof(S).IsEnum)
    {
    ExampleMethod((int)y);
    }
    }





    share|improve this answer



















    • 1





      That wont compile either Cannot convert type 'S' to 'int'

      – Nkosi
      Nov 23 '18 at 10:08






    • 1





      Not every enum use int as its underlying type. Also what if ExampleMethod do thing based on actual enum type (for example calling ToString() on argument)? With casting to int you will lose this type information.

      – PetSerAl
      Nov 23 '18 at 10:11












    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',
    autoActivateHeartbeat: false,
    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%2f53444016%2fhow-to-call-a-method-with-a-generic-constraint-using-a-type-parameter-without-th%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    You could use dynamic:



    if (typeof(S).IsEnum)
    {
    ExampleMethod((dynamic)y);
    }





    share|improve this answer



















    • 1





      Which is of course just a nice way of hiding reflection-like activity

      – Damien_The_Unbeliever
      Nov 23 '18 at 9:46











    • Thanks, didn't think of that. Even though what @Damien_The_Unbeliever said :)

      – BartoszKP
      Nov 23 '18 at 9:51
















    3














    You could use dynamic:



    if (typeof(S).IsEnum)
    {
    ExampleMethod((dynamic)y);
    }





    share|improve this answer



















    • 1





      Which is of course just a nice way of hiding reflection-like activity

      – Damien_The_Unbeliever
      Nov 23 '18 at 9:46











    • Thanks, didn't think of that. Even though what @Damien_The_Unbeliever said :)

      – BartoszKP
      Nov 23 '18 at 9:51














    3












    3








    3







    You could use dynamic:



    if (typeof(S).IsEnum)
    {
    ExampleMethod((dynamic)y);
    }





    share|improve this answer













    You could use dynamic:



    if (typeof(S).IsEnum)
    {
    ExampleMethod((dynamic)y);
    }






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 23 '18 at 9:44









    DirkDirk

    8,93622442




    8,93622442








    • 1





      Which is of course just a nice way of hiding reflection-like activity

      – Damien_The_Unbeliever
      Nov 23 '18 at 9:46











    • Thanks, didn't think of that. Even though what @Damien_The_Unbeliever said :)

      – BartoszKP
      Nov 23 '18 at 9:51














    • 1





      Which is of course just a nice way of hiding reflection-like activity

      – Damien_The_Unbeliever
      Nov 23 '18 at 9:46











    • Thanks, didn't think of that. Even though what @Damien_The_Unbeliever said :)

      – BartoszKP
      Nov 23 '18 at 9:51








    1




    1





    Which is of course just a nice way of hiding reflection-like activity

    – Damien_The_Unbeliever
    Nov 23 '18 at 9:46





    Which is of course just a nice way of hiding reflection-like activity

    – Damien_The_Unbeliever
    Nov 23 '18 at 9:46













    Thanks, didn't think of that. Even though what @Damien_The_Unbeliever said :)

    – BartoszKP
    Nov 23 '18 at 9:51





    Thanks, didn't think of that. Even though what @Damien_The_Unbeliever said :)

    – BartoszKP
    Nov 23 '18 at 9:51













    1














    If the enum types are known, one possibility, though verbose, would be to convert to known types.



    For example, as a starting point,



    public void CallerMethod<S>(S y) {
    if (typeof(S).IsEnum) {
    if (y is KnownEnum) {
    var z = (KnownEnum)Enum.Parse(typeof(S), y.ToString());
    ExampleMethod(z);
    }
    if (y is KnownEnum2) {
    var z = (KnownEnum2)Enum.Parse(typeof(S), y.ToString());
    ExampleMethod(z);
    }
    //...
    }
    }





    share|improve this answer
























    • Would work, thanks. However this approach is unmaintainable when the number of enums is big/unknown/subject to change.

      – BartoszKP
      Nov 23 '18 at 11:02











    • My thoughts as well. looking into alternatives

      – Nkosi
      Nov 23 '18 at 11:04


















    1














    If the enum types are known, one possibility, though verbose, would be to convert to known types.



    For example, as a starting point,



    public void CallerMethod<S>(S y) {
    if (typeof(S).IsEnum) {
    if (y is KnownEnum) {
    var z = (KnownEnum)Enum.Parse(typeof(S), y.ToString());
    ExampleMethod(z);
    }
    if (y is KnownEnum2) {
    var z = (KnownEnum2)Enum.Parse(typeof(S), y.ToString());
    ExampleMethod(z);
    }
    //...
    }
    }





    share|improve this answer
























    • Would work, thanks. However this approach is unmaintainable when the number of enums is big/unknown/subject to change.

      – BartoszKP
      Nov 23 '18 at 11:02











    • My thoughts as well. looking into alternatives

      – Nkosi
      Nov 23 '18 at 11:04
















    1












    1








    1







    If the enum types are known, one possibility, though verbose, would be to convert to known types.



    For example, as a starting point,



    public void CallerMethod<S>(S y) {
    if (typeof(S).IsEnum) {
    if (y is KnownEnum) {
    var z = (KnownEnum)Enum.Parse(typeof(S), y.ToString());
    ExampleMethod(z);
    }
    if (y is KnownEnum2) {
    var z = (KnownEnum2)Enum.Parse(typeof(S), y.ToString());
    ExampleMethod(z);
    }
    //...
    }
    }





    share|improve this answer













    If the enum types are known, one possibility, though verbose, would be to convert to known types.



    For example, as a starting point,



    public void CallerMethod<S>(S y) {
    if (typeof(S).IsEnum) {
    if (y is KnownEnum) {
    var z = (KnownEnum)Enum.Parse(typeof(S), y.ToString());
    ExampleMethod(z);
    }
    if (y is KnownEnum2) {
    var z = (KnownEnum2)Enum.Parse(typeof(S), y.ToString());
    ExampleMethod(z);
    }
    //...
    }
    }






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 23 '18 at 10:55









    NkosiNkosi

    119k17139204




    119k17139204













    • Would work, thanks. However this approach is unmaintainable when the number of enums is big/unknown/subject to change.

      – BartoszKP
      Nov 23 '18 at 11:02











    • My thoughts as well. looking into alternatives

      – Nkosi
      Nov 23 '18 at 11:04





















    • Would work, thanks. However this approach is unmaintainable when the number of enums is big/unknown/subject to change.

      – BartoszKP
      Nov 23 '18 at 11:02











    • My thoughts as well. looking into alternatives

      – Nkosi
      Nov 23 '18 at 11:04



















    Would work, thanks. However this approach is unmaintainable when the number of enums is big/unknown/subject to change.

    – BartoszKP
    Nov 23 '18 at 11:02





    Would work, thanks. However this approach is unmaintainable when the number of enums is big/unknown/subject to change.

    – BartoszKP
    Nov 23 '18 at 11:02













    My thoughts as well. looking into alternatives

    – Nkosi
    Nov 23 '18 at 11:04







    My thoughts as well. looking into alternatives

    – Nkosi
    Nov 23 '18 at 11:04













    1














    You could utilise operator overloading; define multiple explicit versions of CallerMethod that can all successfully make a follow on call to ExampleMethod



    CallerMethod(Enum1 value) { ExampleMethod(value); }
    CallerMethod(Enum2 value) { ExampleMethod(value); }
    CallerMethod(Enum3 value) { ExampleMethod(value); }


    etc.



    If there are a large number of growing types that need a version of CallerMethod you could write a T4 template to generate a partial class with all implementations.






    share|improve this answer




























      1














      You could utilise operator overloading; define multiple explicit versions of CallerMethod that can all successfully make a follow on call to ExampleMethod



      CallerMethod(Enum1 value) { ExampleMethod(value); }
      CallerMethod(Enum2 value) { ExampleMethod(value); }
      CallerMethod(Enum3 value) { ExampleMethod(value); }


      etc.



      If there are a large number of growing types that need a version of CallerMethod you could write a T4 template to generate a partial class with all implementations.






      share|improve this answer


























        1












        1








        1







        You could utilise operator overloading; define multiple explicit versions of CallerMethod that can all successfully make a follow on call to ExampleMethod



        CallerMethod(Enum1 value) { ExampleMethod(value); }
        CallerMethod(Enum2 value) { ExampleMethod(value); }
        CallerMethod(Enum3 value) { ExampleMethod(value); }


        etc.



        If there are a large number of growing types that need a version of CallerMethod you could write a T4 template to generate a partial class with all implementations.






        share|improve this answer













        You could utilise operator overloading; define multiple explicit versions of CallerMethod that can all successfully make a follow on call to ExampleMethod



        CallerMethod(Enum1 value) { ExampleMethod(value); }
        CallerMethod(Enum2 value) { ExampleMethod(value); }
        CallerMethod(Enum3 value) { ExampleMethod(value); }


        etc.



        If there are a large number of growing types that need a version of CallerMethod you could write a T4 template to generate a partial class with all implementations.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 23 '18 at 14:50









        qujckqujck

        12k42964




        12k42964























            -2














            In your specific case you can just cast to an int.



            public void CallerMethod<S>(S y)
            {
            if (typeof(S).IsEnum)
            {
            ExampleMethod((int)y);
            }
            }





            share|improve this answer



















            • 1





              That wont compile either Cannot convert type 'S' to 'int'

              – Nkosi
              Nov 23 '18 at 10:08






            • 1





              Not every enum use int as its underlying type. Also what if ExampleMethod do thing based on actual enum type (for example calling ToString() on argument)? With casting to int you will lose this type information.

              – PetSerAl
              Nov 23 '18 at 10:11
















            -2














            In your specific case you can just cast to an int.



            public void CallerMethod<S>(S y)
            {
            if (typeof(S).IsEnum)
            {
            ExampleMethod((int)y);
            }
            }





            share|improve this answer



















            • 1





              That wont compile either Cannot convert type 'S' to 'int'

              – Nkosi
              Nov 23 '18 at 10:08






            • 1





              Not every enum use int as its underlying type. Also what if ExampleMethod do thing based on actual enum type (for example calling ToString() on argument)? With casting to int you will lose this type information.

              – PetSerAl
              Nov 23 '18 at 10:11














            -2












            -2








            -2







            In your specific case you can just cast to an int.



            public void CallerMethod<S>(S y)
            {
            if (typeof(S).IsEnum)
            {
            ExampleMethod((int)y);
            }
            }





            share|improve this answer













            In your specific case you can just cast to an int.



            public void CallerMethod<S>(S y)
            {
            if (typeof(S).IsEnum)
            {
            ExampleMethod((int)y);
            }
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 23 '18 at 10:05









            John WuJohn Wu

            31.3k42753




            31.3k42753








            • 1





              That wont compile either Cannot convert type 'S' to 'int'

              – Nkosi
              Nov 23 '18 at 10:08






            • 1





              Not every enum use int as its underlying type. Also what if ExampleMethod do thing based on actual enum type (for example calling ToString() on argument)? With casting to int you will lose this type information.

              – PetSerAl
              Nov 23 '18 at 10:11














            • 1





              That wont compile either Cannot convert type 'S' to 'int'

              – Nkosi
              Nov 23 '18 at 10:08






            • 1





              Not every enum use int as its underlying type. Also what if ExampleMethod do thing based on actual enum type (for example calling ToString() on argument)? With casting to int you will lose this type information.

              – PetSerAl
              Nov 23 '18 at 10:11








            1




            1





            That wont compile either Cannot convert type 'S' to 'int'

            – Nkosi
            Nov 23 '18 at 10:08





            That wont compile either Cannot convert type 'S' to 'int'

            – Nkosi
            Nov 23 '18 at 10:08




            1




            1





            Not every enum use int as its underlying type. Also what if ExampleMethod do thing based on actual enum type (for example calling ToString() on argument)? With casting to int you will lose this type information.

            – PetSerAl
            Nov 23 '18 at 10:11





            Not every enum use int as its underlying type. Also what if ExampleMethod do thing based on actual enum type (for example calling ToString() on argument)? With casting to int you will lose this type information.

            – PetSerAl
            Nov 23 '18 at 10:11


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53444016%2fhow-to-call-a-method-with-a-generic-constraint-using-a-type-parameter-without-th%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

            If I really need a card on my start hand, how many mulligans make sense? [duplicate]

            Alcedinidae

            Can an atomic nucleus contain both particles and antiparticles? [duplicate]