简体   繁体   中英

Should I use Public Shared Sub and Public Shared Functions or not? Do they share data between users?

I'm working with .Net using VB and have just finished a website project and I'm getting ready to roll it out...but as I go through a final cleanup/walkthrough I've noticed that I currently have used a Public Shared Function 62 times and a Public Shared Sub 14 times, as well as a couple of Public Shared properties.

This is an area I've just never been entirely clear on and want to optimize my code properly.

A lot of articles I read seem to indicate that a Public Shared just makes it easier to access a function or sub without creating an instance of it first.

But then other places I read talk about whether this is Shared amongst users on the site.

This is where I'm unsure/confused. If 2 users are on at the same time and they both call the same Public Shared Function or Sub, can things cross over?

Do variables/properties work the same or differently? For instance if I'm storing a user object as a Public Shared Property is that limited to this user only, or will all users be able to access it?

If you could only pick one, then rerun would be right. But there's a reason shared exists and it's best to understand it so you can use it appropriately.

Let's say you have a function that just returns all the records in a database, then that would be fine to put in a shared class. And let's say this function has a parameter that let's you specify one record you want to return. In this case you're still safe because each call to the function will add another frame to the stack and track the variables for that frame separately.

However, if you start working with a class member variable within your function then that's where you can run into trouble. Let's say your class uses a member variable that contains the number of rows per page to display. Each time a user changes their preference it will affect all users.

So, I hope that clears it up for you a bit.

Edit: In repose to your question...

Consider the MessageBox class. As you know you do not have to create an instance of it to use its methods. And if two calls are simultaneously made to its Show(string text) method, you don't have to worry about the second call overwriting the message the first passed because each call to the method maintains its own set of variables.

However, consider the following class:

public static class MyMessageBox
{
    public static string Message { get; set; }

    public static void Show() 
    {
        MessageBox.Show(MyMessageBox.Message);
    }
}

Notice a few things about this class: 1) Show has to access the Message property through a reference to the static class MyMessageBox. It can't reference it as 'this.Message' because there is no actual instance of the class and therefore no such thing as 'this'.

2) Because this is a static class, all properties/fields must be declared as static. However, don't misunderstand that you can also have a non-static class with static variables and methods. Functionally, making your class static doesn't change a darned thing about the way your code behaves... it only causes the compiler to enforce certain rules in your class.

Making a method static allows you to be able to call it as MyClass.SomeMethod() instead of instanceOfMyClass.SomeMethod(). This is only a difference in syntax. In reality, all methods are always static (ie there are never multiple instances of your method code... it's just in one place. It's the variables that there are instantiated.). In addition to the difference in syntax, making a method static also enforces rules that keep you from referencing any non-static properties/fields which makes sense since you aren't calling it from an actual instance of your object.

3) Most importantly, notice that this would be a horrible way to design this class. If two calls are made to the class, it's possible that one person could set the Message property to "Hello" and someone else could then set it to "World" before the first person displayed their message. Then each person calls the Show() method and you get two message boxes that say "World".

There are times when this kind of design is needed, and so you have to uses multi-threading techniques to make subsequent callers wait in line to use a particular resource. But for something as simple as this that would obviously be ridiculous.

Public shared means there is no instance of the class related and can cause major problems in multihreaded environments. There are some other issues with with shared functions in that they create very coupled environment that is difficult to mock and test. It is best in general to avoid using shared functions and I would say to strive to use shared properties as little as possible if re factoring them out is not difficult I would.

That's what Shared is meant to convey, the value is shared by every piece of code in the running application. That also means that if you have a website that can be accessed by more users at the same time, they will have the same value in the Shared field or property.

In general, there is nothing wrong with Shared methods, if you understand they are less flexible than instance methods. For example, you can't change what it does only in one part of the application.

As for Shared fields and properties, you should be careful with them in multi-threaded environment. Changing them on one thread changes them in other threads too, but the change may not show immediately due to caching.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM