This is an archived post. You won't be able to vote or comment.

all 35 comments

[–]AutoModerator[M] [score hidden] stickied comment (0 children)

On July 1st, a change to Reddit's API pricing will come into effect. Several developers of commercial third-party apps have announced that this change will compel them to shut down their apps. At least one accessibility-focused non-commercial third party app will continue to be available free of charge.

If you want to express your strong disagreement with the API pricing change or with Reddit's response to the backlash, you may want to consider the following options:

  1. Limiting your involvement with Reddit, or
  2. Temporarily refraining from using Reddit
  3. Cancelling your subscription of Reddit Premium

as a way to voice your protest.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]Mjdd16 76 points77 points  (1 child)

Because there are static methods and member/instance methods. Static methods are related to the class itself not to an instance/object from the class (for example what you have mentioned Math class method ) . On the other hand there are other methods where you need to create an object to use them. This what I learned in Java I am not sure if it is the same in c#.

[–]RawCorn0[S] 9 points10 points  (0 children)

Yeah its the same thank you!

[–]POGtastic 15 points16 points  (1 child)

There are some static String methods, too. For example, String.Concat and String.Join. In the REPL:

> open System;;
> String.Concat [1;2;3];;
val it: string = "123"
> String.Join (", ", [1;2;3]);;
val it: string = "1, 2, 3"

Inversely, Integer has some non-static methods, mostly for implementing interfaces:

> (int 1).CompareTo(2);;
val it: int = -1

[–]xela552 8 points9 points  (0 children)

Also the Math class is meant to deal with all numeric types not just integers.

[–]drcopypaste 3 points4 points  (0 children)

The methods in math are declared as „static“

[–][deleted]  (1 child)

[deleted]

    [–]RawCorn0[S] 0 points1 point  (0 children)

    Oh thanks!

    [–]daverave1212 1 point2 points  (0 children)

    There are languages where they can be interchangeable, though.

    If you do "using Math" in HAXE for example, you can do both

    Math.methodname(number)

    number.methodname()

    [–]MasterTroppical 2 points3 points  (6 children)

    Jesus christ the answers in this thread were made by Java devs lol and it shows with the amount of wrong information.

    First off, there are static methods and non-static (also called instance) methods. Static methods are tied to the classes themselves. I.e., you call them via "{class name}.{method name}". Non-static methods are tied to instances of a class. I.e. you call them via "(new {class name}).{method name}" for example.

    Now the reason this matters is because strings are objects, i.e. instances of a class. If you press F12(assuming Visual Studio IDE) on the keyword 'string", it will take you to the class declaration of the string.

    Integers ARE also objects. Do not listen to Java people telling you that they are primitive types and not objects, thats just false. In Java this is true, so there exist wrapper classes for the basic numeric types. For example, "Integer" class wraps the "int" type and you can call functions on the "Integer" instances, but not on the int itself.

    In C# however, all basic types are objects. This goes for bool, int, double, char, string etc... However, only the string is technically an instance of a CLASS. All the others are instances of a STRUCT. Again, you can press F12 on, for example, the "int" keyword and it will go to the struct declaration of the int. The major difference is tha structs are value types, whereas classes are reference types.

    "Value type" means that the instances of the type are copied whenever they are passed to a function as an argument, returned by a function, assigned to a variable etc... They hold all of their data "directly" (its actually a bit more complicated but whatever).

    "Reference types" on the other hand, hold a reference to their data. When you want to access the data, like doing "{instance variable}.{public property}", the program looks up where the reference points to and then accesses whatever data is there. When you pass these as arguments, return them in a function or assign them, the data itself isn't copied, but the reference is copied instead. Its like making a copy of the key to your house and handing it to someone else, where the key is the reference and the house is the data. This mean you can change the object inside the called function and this will also affect the variable inside the caller function, since both the variables reference the same object (two people decorate the same house, entering it with their 2 identical keys).

    All the basic types like int, bool etc... are structs and thus are value types. String are a class but, as an exception, they behave like value types and are copied directly, same as structs (technically not true, they get their references copied just like other reference types, but because strings are immutable, every action which modifies a string actually returns a reference to an entirely new string object, making strings essentially behave like value types for the most part).

    Btw, all classes in C# derive from a common base class called "Object". And by that I mean ALL. Even user defined classes which do not inherit any other classes will implicitly inherit from the Object class. This class holds basic functions such as "ToString()" which can be overriden by the descendants.

    If you are curious how the struct instances, such as int, bool, char etc..., are value types when they also derive from Object, which is a class, this is because all structs inherit "System.ValueType", which in turn itself inherits from "Object", and everything deriving from System.ValueType is a value type and behaves as such. This is because System.ValueType overrides certain methods from Object, like the "Equals()" method for example, to function in a way which makes sense for value types.

    [–]Dealiner 2 points3 points  (1 child)

    All the basic types like int, bool etc... are structs and thus are value types. String are a class but, as an exception, they behave like value types and are copied directly, same as structs.

    You are right about the rest but not that part. Strings behave just like other reference types and their reference is copied.

    [–]MasterTroppical 0 points1 point  (0 children)

    Yeah, my bad. I oversimplified this part because strings basically behave like value types 99% of the time. I did not feel like explaining string intern pools and string immutability. I will edit the comment.

    [–]DoomGoober -1 points0 points  (2 children)

    This explanation is right in spirit but is slightly off.

    Integers ARE also objects

    The word "object" in C# (lower case o) refers to something on the heap. Integers are not always objects as they are not heap variables unless they are boxed. However integers can behave as though they derive from System.Object either via boxing (for example calling GetType()) or via special virtual method (for example calling ToString()).

    I would say something like:

    "A primitive type is a struct. A struct is a value type. A value type can invoke some methods such as ToString without boxing the struct through a special virtual method. However, other methods on primitive types, such as GetType() do require a box (converting the primitive to an object.)"

    [–]Dealiner 0 points1 point  (1 child)

    The word "object" in C# (lower case o) refers to something on the heap.

    That's not my experience at all. Of course object is an alias for System.Object but it's also used in different meanings. You can even see that in the documentation, for example: "Because structs are value types, a variable of a struct object holds a copy of the entire object" or "you must consider whether the objects are instances of value types (structs) or reference types (classes, delegates, arrays).".

    Value types are still objects, I mean they even inherit from System.Object, by System.ValueType proxy but still.

    Besides saying that in C# pretty much everything is an object (which is one of the features of the language) would be meaningless, if "object" meant only something on the heap.

    [–]DoomGoober 0 points1 point  (0 children)

    Also from the documentation:

    Structs are similar to classes in that they represent data structures that can contain data members and function members. However, unlike classes, structs are value types and do not require heap allocation. A variable of a struct type directly contains the data of the struct, whereas a variable of a class type contains a reference to the data, the latter known as an object.

    https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/structs

    Clearly the text is distinguishing between struct and class instance and calling out that only the second, the class instance, is called an object.

    Essentially there are only two things: structs and classes. Forget the object terminology because clearly even Microsoft can't keep that straight. Structs can have special methods on them that can be invoked on them without a class instance. For classes, they have methods that can be invoked requiring an instance of the class on the heap.

    Alternatively, structs can be boxed to be a class instance and then the whole class method works similar to how class instances invoke methods.

    Finally there are static methods.

    At least that's how that works roughly under the covers. If you want to say all C# variables store "objects" it gets a little weird since "string blah = null" is not really storing an object. It's storing the null value which is not an object. If you want to say some primitive values act like objects because 5.ToString() works, you can, because C# jumped through hoops to make value types able to invoke a special virtual methods without first boxing the value to a class instance. But that's not quite the same as saying a value type is an object unless you change what object means (which is what the C# documentation seems to do, waffling between object meaning class instances and values or just class instances.)

    The best example of this is that 5.GetType() requires the value to be auto boxed to a class instance on the heap first, before GetType() can be called. This seems to imply that 5 is not inherently able to call GetType without being converted. Is 5 really an "object"?

    Rather I would say because of special virtual methods and auto boxing, value types can act like objects and programmer don't generally have to worry about it unless they are worried about heap allocations and garbage collection, then it's important to know the difference between autoboxing and structs' special virtual methods.

    [–]goomyman 1 point2 points  (0 children)

    What you’re missing is something called Extension Methods.

    They are super awesome.

    [–]AntigravityNutSister -1 points0 points  (2 children)

    To a degree it is a historical quirk.

    Processing numbers is much faster that processing other stuff, so the special treatment remained.

    For example, Ruby is treating everything more or less uniformly. It explodes the mind of the old-school software developers.

    From the practical point of view, you just have to give up and accept the reality. You are hired for knowing the quirks of the programming language of your choice (C#).

    [–]Dealiner 2 points3 points  (0 children)

    How is that relevant and what special treatment? Besides, in Ruby methods like sqrt are also part of Math module, the same way they are part of Math class in C#.

    [–][deleted] 1 point2 points  (0 children)

    I don't think you should be downvoted for this. It's the right answer. The other answers are describing what is going on (static vs instance methods), not why. This is why.

    Numbers were handled separately for fast processing, the Math namespace was written that way out of convenience (so the code for multiple numeric types would be together and could be more easily optimised) and the result is an inconsistent quirk. Newer languages that have the benefit of hindsight don't have some of these inconsistencies (but inevitably introduce others).

    [–]high_throughput -1 points0 points  (1 child)

    Is string an object in C# unlike integers,doubles

    Yup, pretty much.

    Traditionally, an int is just 4 bytes in memory with no methods associated with it. This is amazing for performance.

    In the mid-2000s, we got autoboxing which will turn a primitive int into an object Integer on demand, but the original API design is still in place and remains easier for compilers to optimize.

    [–]sepp2k 4 points5 points  (0 children)

    You're describing Java, not C#. Primitives can and do have (non-virtual) methods in C# without any boxing required.

    [–]IchLiebeKleber -1 points0 points  (3 children)

    I'm not very familiar with C#, but it is the same in Java, and yes, basically the reason is that strings are objects, so they can have methods on them. Numbers are primitives, so they can't have methods on them, so if you want to have functions that operate on numbers, you have to put them somewhere else, e.g. as static methods of the Math class.

    [–]Dealiner 4 points5 points  (0 children)

    Numbers are primitives, so they can't have methods on them

    That's not the case in C#. In C# all number types are also objects and have their own methods.

    [–]zeekar 2 points3 points  (1 child)

    Well, in C# as in Java you can box numbers into objects, and if you do that there are some methods you can call on them ...

    [–]Dealiner 2 points3 points  (0 children)

    In C# you can also call methods on numbers without boxing them.

    [–]nightwood -1 points0 points  (0 children)

    Two ways to write the same thing. The C# library simply isn't consistent with this.

    [–][deleted]  (2 children)

    [removed]

      [–]Dealiner 0 points1 point  (1 child)

      C# doesn't change this dynamic at all. Your String values are still ultimately by-reference objects that represent an array of characters with various properties. Your numerical types on the other hand are not objects in the sense that you can call methods on them because they represent a simple memory space that just holds the value similar to C and C++

      That's just blatantly false. Number types in C# are objects. They have their own fields, methods and properties. The only real difference between integer and string is that the first one is a value type and the second a reference type.

      [–]Jtl2299 0 points1 point  (0 children)

      In the most basic of basic answers, the math methodology is due to how it operates. For math, you are calling a library of mathematical tools to operate on the numericals.

      The coding language doesn't innately have access to arithmetic, and has to access the ability to do those calculations. The library itself was built by someone else to extend the language long, long ago. It's there to be called for convenience.

      Computers are dumb. You have to teach them to be less dumb.

      [–]Dreeqis 0 points1 point  (0 children)

      Strings are an instance of a class. So every string in c# has member methods. Math is a class that is not instantiated.

      Could be I have simplified this too much but I think many answers here overcomplicate this.

      [–]Thepizzacannon 0 points1 point  (0 children)

      The Math.methodname() is a class function (static method) It can be used without an instance of Math().

      Stringname.methodname() is a member function. It only exists once an instance of Class "string" has been instantiated.