How to call a method with a generic constraint using a type parameter without the constraint?
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
|
show 9 more comments
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
You know thatS
satisfies the constraint forExampleMethod<T>
, but the compiler does not. You would need to add the constraint toCallerMethod
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
|
show 9 more comments
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
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
c# generics generic-constraints
edited Nov 23 '18 at 12:46
BartoszKP
asked Nov 23 '18 at 9:37
BartoszKPBartoszKP
27k1070107
27k1070107
You know thatS
satisfies the constraint forExampleMethod<T>
, but the compiler does not. You would need to add the constraint toCallerMethod
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
|
show 9 more comments
You know thatS
satisfies the constraint forExampleMethod<T>
, but the compiler does not. You would need to add the constraint toCallerMethod
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
|
show 9 more comments
4 Answers
4
active
oldest
votes
You could use dynamic
:
if (typeof(S).IsEnum)
{
ExampleMethod((dynamic)y);
}
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
add a comment |
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);
}
//...
}
}
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
add a comment |
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.
add a comment |
In your specific case you can just cast to an int.
public void CallerMethod<S>(S y)
{
if (typeof(S).IsEnum)
{
ExampleMethod((int)y);
}
}
1
That wont compile eitherCannot convert type 'S' to 'int'
– Nkosi
Nov 23 '18 at 10:08
1
Not every enum useint
as its underlying type. Also what ifExampleMethod
do thing based on actual enum type (for example callingToString()
on argument)? With casting toint
you will lose this type information.
– PetSerAl
Nov 23 '18 at 10:11
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
You could use dynamic
:
if (typeof(S).IsEnum)
{
ExampleMethod((dynamic)y);
}
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
add a comment |
You could use dynamic
:
if (typeof(S).IsEnum)
{
ExampleMethod((dynamic)y);
}
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
add a comment |
You could use dynamic
:
if (typeof(S).IsEnum)
{
ExampleMethod((dynamic)y);
}
You could use dynamic
:
if (typeof(S).IsEnum)
{
ExampleMethod((dynamic)y);
}
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
add a comment |
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
add a comment |
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);
}
//...
}
}
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
add a comment |
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);
}
//...
}
}
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
add a comment |
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);
}
//...
}
}
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);
}
//...
}
}
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
add a comment |
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
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 23 '18 at 14:50
qujckqujck
12k42964
12k42964
add a comment |
add a comment |
In your specific case you can just cast to an int.
public void CallerMethod<S>(S y)
{
if (typeof(S).IsEnum)
{
ExampleMethod((int)y);
}
}
1
That wont compile eitherCannot convert type 'S' to 'int'
– Nkosi
Nov 23 '18 at 10:08
1
Not every enum useint
as its underlying type. Also what ifExampleMethod
do thing based on actual enum type (for example callingToString()
on argument)? With casting toint
you will lose this type information.
– PetSerAl
Nov 23 '18 at 10:11
add a comment |
In your specific case you can just cast to an int.
public void CallerMethod<S>(S y)
{
if (typeof(S).IsEnum)
{
ExampleMethod((int)y);
}
}
1
That wont compile eitherCannot convert type 'S' to 'int'
– Nkosi
Nov 23 '18 at 10:08
1
Not every enum useint
as its underlying type. Also what ifExampleMethod
do thing based on actual enum type (for example callingToString()
on argument)? With casting toint
you will lose this type information.
– PetSerAl
Nov 23 '18 at 10:11
add a comment |
In your specific case you can just cast to an int.
public void CallerMethod<S>(S y)
{
if (typeof(S).IsEnum)
{
ExampleMethod((int)y);
}
}
In your specific case you can just cast to an int.
public void CallerMethod<S>(S y)
{
if (typeof(S).IsEnum)
{
ExampleMethod((int)y);
}
}
answered Nov 23 '18 at 10:05
John WuJohn Wu
31.3k42753
31.3k42753
1
That wont compile eitherCannot convert type 'S' to 'int'
– Nkosi
Nov 23 '18 at 10:08
1
Not every enum useint
as its underlying type. Also what ifExampleMethod
do thing based on actual enum type (for example callingToString()
on argument)? With casting toint
you will lose this type information.
– PetSerAl
Nov 23 '18 at 10:11
add a comment |
1
That wont compile eitherCannot convert type 'S' to 'int'
– Nkosi
Nov 23 '18 at 10:08
1
Not every enum useint
as its underlying type. Also what ifExampleMethod
do thing based on actual enum type (for example callingToString()
on argument)? With casting toint
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
You know that
S
satisfies the constraint forExampleMethod<T>
, but the compiler does not. You would need to add the constraint toCallerMethod
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