Jestem refactoring kodu w aplikacji systemu Windows, a ja natknąłem się na pewnego rodzaju, że nie jestem pewien, że lubię: klasa ma kolor globalny zmienne, takie jak następujące:Strategie przekazywania kolorów wokół (unikanie ref?)
private Color myForegroundColor = Color.Azure;
private Color myBackgroundColor = Color.Empty;
// ...etc.
Istnieje kilka z nich, i są one przekazywane przez około ref metod odpowiedzialnych za opracowanie niektórych części interfejsu użytkownika.
Domyślam się, że Color
jest strukturą i że każdy kolor jest przekazywany przez ref w celu uniknięcia tworzenia nowych kopii za każdym razem, gdy wywoływana jest metoda. IE coś takiego:
// Avoid creating a copy of myForgroundColor inside SetUpButton():
MyHelperClass.SetUpButton(ref myForegroundColor);
nie mogę oprzeć się wrażeniu, że to wykorzystanie ref
całej tej klasie i pokrewnych zajęć jest zły. Czuje się jak "code smell", ale nie mogę powiedzieć dlaczego.
Widziałem kilka stanowisk na podobnych problemów, z zaleceniami jak „użyć klasy zawierającej kolorów, który jest następnie przekazywany jako typ wartości”, ale to nie jest do końca jasne, jak byłoby najlepiej Zrób to.
Co chciałbym zrobić, to stworzyć coś podobnego do poniższego:
public class ColorContainer
{
public UiSettingsContainer()
{
MyColor = Color.Black;
MyNextColor = Color.Blue;
// ..etc...
}
public Color MyColor { get; private set; }
// ...etc....
}
ten pozwolił mi zachować kontrolę nad kolorami, ale implikacje dotyczące pamięci są trochę niejasne dla mnie; jeśli utworzyłem instancję tej klasy i przekazałem ją do metod wymagających informacji o zawartych kolorach, czy kopia color
(z tym, że jest strukturą) nie zostałaby utworzona, gdy tylko metoda implementacji jej użyje?
mam rację zakładając, że ten kod będzie tworzyć nową kopię, a zatem mniej skuteczne ...
// Assumption: This creates a new copy of color in memory.
public void SetSomeColor(Color col){
someComponent.color = col;
}
// Calling it:
SetSomeColor(myColorContainerInstance.MyColor);
... niż tego kodu, która stałaby tylko wykorzystanie istniejącej struktury? :
// Question: Does this avoid creating a new copy of MyColor in memory?
public void SetSomeColor(ColorContainer container){
someComponent.color = container.MyColor;
}
// Calling it:
SetSomeColor(myColorContainerInstance);
obecnie jestem pochylony w kierunku rozwiązania podobnego do poniższego, w którym wnoszę kolory w oddzielnej klasie i reorganizacji kod trochę, ale nadal korzystać ref
. W tym przypadku jednak, MyColor
będą musiały być polem publicznego w ColorContainer
, co oznacza, że będę mieć mniejszą kontrolę nad tym, kto może go ustawić jego wartość:
// Assumption: This creates a new copy of color in memory.
public void SetSomeColor(ref Color col){
someComponent.color = col;
}
// Calling it:
SetSomeColor(ref myColorContainerInstance.MyColor);
Czy jest to dobre rozwiązanie, czy są lepsze strategie obsługiwać takie zasoby?
Czy możesz nie tylko ustawić użytkownika jako statycznego/globalnego gościa? –
Dlaczego chcesz uniknąć kopiowania obiektów "Kolorowych"? – delnan
Jeśli 'SetSomeColor' nie jest oznaczony jako" wirtualny ", istnieje bardzo duża szansa, że JIT będzie tak czy inaczej wstawiał metodę, co zapobiega kopiowaniu struktury, nawet jeśli argument nie jest oznaczony jako" ref ". –