I think Flydog57's answer is much more complete. In my answer I will add code example in hopes of making it a bit easier to understand.
Public - access modifier which determines from where your code(method/class/etc.) can be accessed. Public does not have any restriction so you can access your code from basically anywhere. On the other hand If a method or property or something else is private you can access it from only within the class it belongs to. There are other access modifiers as well kindly take a look here.
Static - static is a modifier keyword which determines wither your method, property etc. should be accessed using an object of the class or should be accessed directly with the class name.
In below code Add is static but Subtraction is not-static. So, we can only access Subtraction with object. In order to access Add we need to use class name "Math.AddAdd(5, 4)". Note: the output is given in the comment.
class Math{ public static int Add(int a, int b) { return a + b; } public int Subtraction(int a, int b) { return a - b; }}class Program{ static void Main(string[] args) { Math math = new Math(); Console.WriteLine(math.Subtraction(10,4)); // 6 Console.WriteLine(math.Add(5, 4)); // Error CS0176 Member 'Math.Add(int, int)' cannot be accessed with an instance reference; }}
Now if we remove the public access modifier. We get the below errors. Because the methods no longer could be accessed from the outside of the class. Take a look here to see the default access modifiers of different types.
class Math{ static int Add(int a, int b) { return a + b; } int Subtraction(int a, int b) { return a - b; }}class Program{ static void Main(string[] args) { Math math = new Math(); Console.WriteLine(math.Subtraction(5, 4)); // Error CS0122 'Math.Subtraction(int, int)' is inaccessible due to its protection level Console.WriteLine(math.Add(5, 4)); // Error CS0122 'Math.Subtraction(int, int)' is inaccessible due to its protection level }}
When do you use them:Both of this have lot of use cases. In the below example I am using static property TotalStudent to count the total number of student(object). While I am using Name property to keep the information's which is unique to that particular object. Also like above Math example c# and many other programming languages have Math static class which lets you do sum, add and other operations.
class Student{ public string Name { get; set; } public static int TotalStudent { get; set; } = 0; public Student(string name) { Name = name; TotalStudent++; }}class Program{ static void Main(string[] args) { Student s1 = new Student("Bob"); Console.WriteLine(s1.Name); // Bob Console.WriteLine(Student.TotalStudent); // 1 Student s2 = new Student("Alex"); Console.WriteLine(s2.Name); // Alex Console.WriteLine(Student.TotalStudent); // 2 }}