admin管理员组文章数量:1320772
can anyone explain why this is allowed:
class A1
{
public virtual T? F1<T>(T? t) where T : struct { throw new NotImplementedException(); }
public virtual T? F1<T>(T? t) where T : class { throw new NotImplementedException(); }
}
while this is not:
class A1
{
public virtual T? F1<T>(T t) where T : struct { throw new NotImplementedException(); }
public virtual T? F1<T>(T t) where T : class { throw new NotImplementedException(); }
}
"Type 'A1' already defines a member called 'F1' with the same parameter types"
the difference is that in the second case the arguments are not nullable.
how comes that the signatures are same if in one case it's for value types and in another case for reference types?
can anyone explain why this is allowed:
class A1
{
public virtual T? F1<T>(T? t) where T : struct { throw new NotImplementedException(); }
public virtual T? F1<T>(T? t) where T : class { throw new NotImplementedException(); }
}
while this is not:
class A1
{
public virtual T? F1<T>(T t) where T : struct { throw new NotImplementedException(); }
public virtual T? F1<T>(T t) where T : class { throw new NotImplementedException(); }
}
"Type 'A1' already defines a member called 'F1' with the same parameter types"
the difference is that in the second case the arguments are not nullable.
how comes that the signatures are same if in one case it's for value types and in another case for reference types?
Share Improve this question edited Jan 25 at 13:17 Aliq Qim asked Jan 18 at 13:33 Aliq QimAliq Qim 1369 bronze badges 2 |3 Answers
Reset to default 1T?
means different things, depending on whether T
is a value type or reference type.
When T
is a value type, T?
is syntactic sugar for System.Nullable<T>
. When T
is a reference type, T?
is still T
, as far as the runtime is concerned. Nullable reference types is purely a feature of the compiler. It boils down to the compiler doing some compile-time checks to prevent NullReferenceException
s at runtime.
So really you have just declared two methods taking completely different parameter types. One takes a System.Nullable<T>
, and the other takes a reference type T
that is annotated at compile-time to be nullable.
If both methods take a parameter of type T
, then obviously they are exactly the same except they have different type constraints. Method overloads that differ only in type constraints are not allowed.
You are getting the following compiler error pointing at the second F1
overload:
CS0111: Type 'A1' already defines a member called 'F1' with the same parameter types
This is because the signature is given by the method name and parameter types only. The return type is not part of the signature when it comes to overload resolution. You cannot overload a method only differing in the return type.
In the case of the T? t
parameters, the two mean different things for classes and structs.
- in
T? t
,where T : struct
:T?
meansNullable<T>
. - in
T? t
,where T : class
:T?
meansT
where the compiler allowsnull
to be passed as an argument. ButT?
is not another type thanT
. I.e.,typeof(T?)
(which does not compile) is the same astypeof(T)
(this is the very reason the first one does not compile).
See also:
- Method signatures (C# Programming Guide)
- C# in Depth / Overloading see "Return types" (Jon Skeet)
I guess my example can be boiled down to this:
class A1
{
public void F1<T>(T t) where T : struct { throw new NotImplementedException(); }
public void F1<T>(T t) where T : class { throw new NotImplementedException(); }
}
and the core question would be why doesn't compiler treat generic for structs and generic for class as different param types. I guess there is no logical explanation, it just doesn't. or am I missing something?
本文标签: cNullable generics in methodsneeds explanationStack Overflow
版权声明:本文标题:c# - Nullable generics in methods - needs explanation - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742071063a2419126.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
`1
) and everything else (including the nameT
, and any constraints) is secondary details – Marc Gravell Commented Jan 18 at 13:47