C# will not allow to write non-member functions and every method should be part of a class. I was thinking this as a restriction in all CLI languages. But I was wrong and I found that C++/CLI supports non-member functions. When it is compiled, compiler will make the method as member of some unnamed class.
Here is what C++/CLI standard says,
[Note: Non-member functions are treated by the CLI as members of some unnamed class; however, in C++/CLI source code, such functions cannot be qualified explicitly with that class name. end note]
The encoding of non-member functions in metadata is unspecified. [Note: This does not cause interop problems because such functions cannot have public visibility. end note]
So my question is why don’t C# implement something like this? Or do you think there should not be non-member functions and every method should belong to some class?
My opinion is to have non-member function support and it helps to avoid polluting class’s interface.
See this blog posting:
I am asked “why doesn’t C# implement feature X?” all the time. The answer is always the same: because no one ever designed, specified, implemented, tested, documented and shipped that feature. All six of those things are necessary to make a feature happen. All of them cost huge amounts of time, effort and money. Features are not cheap, and we try very hard to make sure that we are only shipping those features which give the best possible benefits to our users given our constrained time, effort and money budgets.
I understand that such a general answer probably does not address the specific question.
In this particular case, the clear user benefit was in the past not large enough to justify the complications to the language which would ensue. By stricting how different language entities nest inside each other we (1) restrict legal programs to be in a common, easily understood style, and (2) make it possible to define “identifier lookup” rules which are comprehensible, specifiable, implementable, testable and documentable.
By restricting method bodies to always be inside a struct or class, we make it easier to reason about the meaning of an unqualified identifier used in an invocation context; such a thing is always an invocable member of the current type (or a base type).
and this follow-up posting:
Like all design decisions, when we’re faced with a number of competing, compelling, valuable and noncompossible ideas, we’ve got to find a workable compromise. We don’t do that except by considering all the possibilites, which is what we’re doing in this case.
(emphasis from original text)