1

Explain to me the logic why I get compilation error in case 3 ?

All of these types derive from Object. What is the problem then?

public delegate object DelegateType();
public static void Main()
{
    DelegateType case1 = Test;
    DelegateType case2 = Test2;
    DelegateType case3 = Test3;
}

public static string Test()
{
    return 1.ToString();
}
public static ValueType Test2()
{
    return 1;
}
public static int Test3()
{
    return 1;
}
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
ps1Xt
  • 33
  • 1
  • 5
  • 1
    Check out [this one](https://stackoverflow.com/a/74930505/2501279) - not direct answer but can give some insight also. – Guru Stron Apr 04 '23 at 10:59
  • @GuruStron from my perspective that is pretty much the same as Marc also mentioned in his answer. Apart from that, it seems your link completely hits the point. From my point of view a clear dupe. – MakePeaceGreatAgain Apr 04 '23 at 11:21
  • @MakePeaceGreatAgain - it is very related but addresses specifically generic arguments. I have originally closed the question as a duplicate one but then decided that they differ enough. – Guru Stron Apr 04 '23 at 11:22
  • Unboxed valuetypes do not inherit from `System.Object` – Charlieface Apr 04 '23 at 13:36
  • @Charlieface They do it. not directly, but through the ValueType class – ps1Xt Apr 05 '23 at 08:13
  • No they don't, unless boxed. If they are boxed then yes, but an unboxed valuetype is just a bare value, it does not have a base class. See that link, there are also other places this is noted, eg ECMA-335 specification Section 8.2.4 https://www.ecma-international.org/wp-content/uploads/ECMA-335_5th_edition_december_2010.pdf – Charlieface Apr 05 '23 at 10:06
  • There is no information in this section that unboxed value does not inherit from ValueType or Object. Here is just an information that if you need a boxed value, then you need to cast it to the ValueType or Object type. The documentation says Object -> ValueType -> Int32 [link](https://learn.microsoft.com/en-us/dotnet/api/system.int32?view=net-7.0) – ps1Xt Apr 05 '23 at 10:34
  • End of that section *"Interfaces and inheritance are defined only on reference types. Thus, while a value type definition (§8.9.7) can specify both interfaces that shall be implemented by the value type and the class (System.ValueType or System.Enum) from which it inherits, these apply only to boxed values"* – Charlieface Apr 05 '23 at 12:11

2 Answers2

4

Variance once works for reference-types, i.e. where there is a value-preserving (without any operations) conversion between types. Boxing/unboxing: does not count as value-preserving, so: no variance between value-types and objects, or value-types and interfaces that those value-types implement.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
-1

This is based on a misunderstanding.

Unboxed valuetypes do not inherit from anything, not even System.ValueType.

The .NET specification spells this out, ECMA-335 Section 8.2.4:

Interfaces and inheritance are defined only on reference types. Thus, while a value type definition (§8.9.7) can specify both interfaces that shall be implemented by the value type and the class (System.ValueType or System.Enum) from which it inherits, these apply only to boxed values

Therefore it is not possible to use inheritance or variance for value-types, because you cannot declare them as boxed, only unboxed.

Charlieface
  • 52,284
  • 6
  • 19
  • 43