속성 대 방법


135

빠른 질문 : 언제 C #에서 속성을 사용하기로 결정하고 언제 메소드를 사용하기로 결정합니까?

우리는이 논쟁에 바쁘고 우리가 재산이나 방법을 사용해야하는지 논란의 여지가있는 부분을 발견했습니다. 한 가지 예는 다음과 같습니다.

public void SetLabel(string text)
{
    Label.Text = text;
}

이 예에서는 LabelASPX 페이지의 컨트롤입니다. 이것을 방법으로 만들 것인지 아니면 속성으로 할 것인지 결정 (이 경우)을 지배 할 수있는 원칙이 있습니까?

가장 일반적이고 포괄적 인 답변을 받아들이지 만, 내가 제시 한 예에 대해서도 언급하겠습니다.


2
-1이 질문은 전에 요청되고 답변되었습니다 : stackoverflow.com/questions/164527/…
Element

방법 / 분야 / 재산 장단점은 긴 논쟁을 일으킬 수 있습니다. 속성에 대한 일반적인 용도 : 개인 / 보호 필드를 원하지만 동시에 노출하려는 경우. 또 다른 용도는 문장뿐만 아니라 표현식 (원하는 경우 동작)도 if()확인합니다 (MSDN에 따라). 그러나 사용자가 변수 (속성)에 액세스하는 데 따른 처리 비용 (코드를 사용할 수 없음)을 항상 인식하지 못하고 엄격한 이유로 속성을 벤치마킹해야하기 때문에 까다로울 수 있습니다. 아, 그리고 "보너스"는 속성을 가진 포인터를 사용할 수 없습니다.
mireazma

답변:


145

로부터 속성 및 메서드 사이의 선택 클래스 라이브러리 개발을위한 디자인 가이드 라인의 섹션 :

일반적으로 메소드는 조치를 나타내고 특성은 데이터를 나타냅니다. 속성은 필드와 같이 사용되어야하며 속성이 계산적으로 복잡하거나 부작용을 발생시키지 않아야합니다. 다음 지침을 위반하지 않으면 경험이 적은 개발자가 속성을 더 쉽게 사용할 수 있으므로 방법보다는 속성을 사용하는 것이 좋습니다.


3
나는 그것의 많은 것에 동의하지만 부작용에 관한 부분이 옳다고 생각하지 않습니다. 예를 들어, "색상"은 종종 개체의 속성이며 명백한 부작용 (개체의 색 변경)이 있습니다. 속성 변경은 객체 상태 변경의 명백한 부작용입니다.
Erik Funkenbusch

46
미스터리 맨 컬러 변경은 부작용이 아닌 원하는 효과입니다. 부작용은 일차 행동에 의도되지 않은 것입니다.
무하마드 하산 칸

2
@Mystere Man : 색을 바꾸는 definelty는 부작용이 아닙니다. 저는이 답변에 완전히 동의합니다
Ahmed Said

2
"경험이 적은 개발자가 속성을 더 쉽게 사용할 수 있기 때문에" -알다시피 이것이 속성을 노출하는 유일한 이유입니다. 그러나 내가 맞습니까?
Tsabo

2
속성의 내부 구현과 방법의 차이점은 무엇입니까? 속성이 사용될 때마다 호출 스택에 푸시 된 것이 있습니까? 그렇지 않으면 어떻게 처리됩니까?
Praveen

57

네, 당신이하고있는 모든 것이 가져오고 설정하는 것이라면, 속성을 사용하십시오.

여러 데이터 멤버에 영향을 줄 수있는 복잡한 작업을 수행하는 경우 방법이 더 적합합니다. 또는 getter가 매개 변수를 사용하거나 setter가 값 매개 변수 이상을 사용하는 경우.

가운데에는 선이 약간 흐려질 수있는 회색 영역이 있습니다. 단단하고 빠른 규칙은 없으며 다른 사람들이 때로는 무언가가 재산인지 방법인지 의견에 동의하지 않을 것입니다. 중요한 것은 자신 이하는 방식 (또는 팀이하는 방식)과 (상대적으로) 일관성을 유지하는 입니다.

그것들은 대체로 상호 교환 가능하지만 속성은 구현이 비교적 "단순"하다는 것을 사용자에게 신호합니다. 아, 그리고 구문은 조금 더 깨끗합니다.

일반적으로 말하자면, get 또는 set으로 시작하고 0 또는 1 개의 매개 변수 (각각)를 사용하는 메소드 이름을 작성하면 특성의 주요 후보라는 철학이 있습니다.


1
하향 투표. 이것은 정확하지 않습니다. 게터 또는 세터의 복잡성은 게터 / 세터 코드 내에 캡슐화됩니다. 전혀 복잡하지 않거나 "여러 데이터 멤버에 영향을 미치는"경우 비표준 또는 여러 매개 변수에 메서드가 필요하지만 그렇지 않은 경우에는이 답변이 정확하지 않습니다.
Hal50000

첫 번째 문장은 모든 것을 설명합니다. 브라보.
SWIIWII

13

속성은 개체에서 데이터를 주입하거나 검색하는 방법입니다. 클래스 내의 변수 또는 데이터에 대한 추상화를 만듭니다. Java의 getter 및 setter와 유사합니다.

메서드는 작업을 캡슐화합니다.

일반적으로 속성을 사용하여 단일 비트의 데이터 또는 판매 세와 같은 클래스에서 작은 계산을 노출합니다. 장바구니의 항목 수와 비용에서 파생됩니다.

데이터베이스에서 데이터를 검색하는 것과 같이 작업을 만들 때 메서드를 사용합니다. 움직이는 부분이있는 작업은 방법의 후보입니다.

코드 예제에서 클래스를 포함하는 외부에서 액세스 해야하는 경우 속성으로 래핑합니다.

public Label Title 
{
   get{ return titleLabel;}
   set{ titleLabel = value;}
}

텍스트 설정 :

Title.Text = "Properties vs Methods";

Label의 Text 속성 만 설정하면 다음과 같이하십시오.

public string Title 
{
   get{ return titleLabel.Text;}
   set{ titleLabel.Text = value;}
}

텍스트 설정 :

Title = "Properties vs Methods";

12

객체의 실제 속성을 설정하는 경우 속성을 사용합니다.

작업 / 기능을 수행하는 경우 방법을 사용하십시오.

귀하의 예에서는 설정되는 명확한 속성입니다.

그러나 기능이 AppendToLabel 인 경우 메소드를 사용합니다.


11

MSDN을 검색 한 결과, 메소드 작성 에 대한 몇 가지 훌륭한 지침을 제공 하는 특성 대 메소드 에 대한 참조를 찾았습니다 .

  • 작업은과 같은 변환 Object.ToString입니다.
  • 작업 캐시는 사용자에게 결과 캐싱을 고려해야한다는 의사 소통을하기에 충분히 비쌉니다.
  • get 접근자를 사용하여 속성 값을 얻는 것은 관찰 가능한 부작용이 있습니다.
  • 멤버를 두 번 연속으로 호출하면 다른 결과가 생성됩니다.
  • 실행 순서가 중요합니다. 유형의 속성은 어떤 순서로든 설정하고 검색 할 수 있어야합니다.
  • 멤버는 정적이지만 변경할 수있는 값을 반환합니다.
  • 멤버가 배열을 반환합니다. 배열을 반환하는 속성은 매우 잘못 될 수 있습니다. 일반적으로 사용자가 내부 상태를 변경할 수 없도록 내부 배열의 사본을 반환해야합니다. 이는 사용자가 자신이 색인화 된 속성이라고 쉽게 가정 할 수 있다는 사실과 함께 비효율적 인 코드로 이어집니다.

해당되는 모든 곳에서 이것이 의미가 있음에 동의합니다. 그러나 WPF에서 XAML 바인딩을 통해 속성을 사용하면 setter에서 적절한 작업을 수행하는 것보다 선택의 여지가 없다는 것이 맞습니까? (특히 ComboBoxes, ListBoxes 등을위한 새로운 SelectedItem에 대해)
Nicolas

9

"Property"라는 이름 만 보면됩니다. 무슨 뜻인가요? 사전은 여러 가지 방법으로 사전을 정의하지만이 경우 "필수 또는 특유의 속성 또는 사물의 품질"이 가장 적합합니다.

행동의 목적에 대해 생각하십시오. 실제로, "필수 또는 특유의 속성"을 변경 또는 검색하고 있습니까? 예제에서 함수를 사용하여 텍스트 상자의 속성을 설정하고 있습니다. 어리석은 것 같아요?

속성은 실제로 함수입니다. 모두 getXXX () 및 setXXX ()로 컴파일됩니다. 그것은 단지 구문 설탕으로 그것들을 숨기지 만, 과정에 의미 론적 의미를 제공하는 설탕입니다.

속성과 같은 속성을 생각하십시오. 자동차에는 많은 속성이 있습니다. 색상, MPG, 모델 등. 모든 속성을 설정할 수있는 것은 아니며 일부는 계산할 수 있습니다.

한편, 방법은 행동입니다. GetColor는 속성이어야합니다. GetFile ()은 함수 여야합니다. 경험의 또 다른 규칙은 객체의 상태를 변경하지 않으면 기능이어야한다는 것입니다. 예를 들어 CalculatePiToNthDigit (n)은 연결된 Math 객체의 상태를 실제로 변경하지 않기 때문에 함수 여야합니다.

이것은 약간 혼란 스러울 수 있지만 실제로는 객체가 무엇인지, 무엇을 나타내는 지 결정하는 것으로 요약됩니다. 그것이 속성인지 함수인지 파악할 수 없다면 어떤 것이 중요하지 않을 수 있습니다.


9

시맨틱 속성은 객체의 속성입니다. 메소드는 객체의 동작입니다.

레이블은 속성이며 속성으로 만드는 것이 더 합리적입니다.

객체 지향 프로그래밍과 관련하여 동작의 일부와 속성에 대한 명확한 이해가 있어야합니다.

자동차 {색상, 모델, 브랜드}

자동차에는 색상, 모델 및 브랜드 속성이 있으므로 의미 상 자동차에 자체 색상을 설정하도록 요청하지 않기 때문에 SetColor 또는 SetModel 메소드를 갖는 것은 의미가 없습니다.

따라서 속성 / 메소드 사례를 실제 객체에 매핑하거나 시맨틱 관점에서 보면 혼란이 사라질 것입니다.


4

또한 속성의 큰 장점은 디버깅하는 동안 Visual Studio에서 속성 값을 볼 수 있다는 것입니다.


3

매개 변수 가 1 인 추가 / 설정 방법에 속성을 사용하는 것을 선호합니다 . 매개 변수가 더 많으면 메소드를 사용하십시오.


3

속성은 단순하게 설정하고 하나의 라이너를 가져와야합니다. 더 많은 것은 실제로 방법으로 옮겨야합니다. 복잡한 코드는 항상 메소드에 있어야합니다.


3

변수 액세스, 즉 개별 변수를 가져오고 설정하거나 컨트롤에서 데이터를 가져오고 설정하기위한 속성 만 사용합니다. 모든 종류의 데이터 조작이 필요 / 수행되는 즉시 메소드를 사용합니다.


3

디자인 문제로서 속성은 클래스 객체의 데이터 또는 속성을 나타내지 만 메서드는 클래스 객체의 동작 또는 동작입니다.

.Net에서 세계는 속성을 사용하는 다른 의미가 있습니다.

  • 속성은 데이터 바인딩에 사용되지만 get_ / set_ 메서드는 사용되지 않습니다.
  • 자연적인 처리 메커니즘 인 XML 직렬화 사용자 속성
  • PropertyGrid 컨트롤 및 인턴 ICustomTypeDescriptor를 통해 속성에 액세스 할 수 있습니다.이 속성 은 사용자 정의 라이브러리를 작성하는 경우 효과적으로 사용할 수 있습니다.
  • 속성에 의해 제어되는 속성 , 하나는 Aspect 지향적 인 소프트웨어를 설계하는 현명하게 사용할 수 있습니다.

속성 사용에 대한 오해 (IMHO) :

  • 작은 계산을 표시하는 데 사용됩니다. ControlDesigner.SelectionRules 의 get 블록은 72 라인으로 실행됩니다 !!
  • 내부 데이터 구조를 노출하는 데 사용됩니다. 속성이 내부 데이터 멤버에 매핑되지 않더라도 클래스의 특성 인 경우 속성으로 사용할 수 있습니다. Viceversa는 클래스 속성의 속성이 바람직하지 않더라도 데이터 멤버와 같은 배열을 리턴합니다 (메소드의 사본을 리턴하는 데 메소드가 사용됨).

여기의 예에서는 다음과 같이 더 많은 비즈니스 의미로 작성되었을 수 있습니다.

public String Title
{
    set { Label.Text = text; }
}

2

속성은 Visual Studio의 비주얼 디자이너에서 액세스 할 수 있으면 액세스 할 수 있기 때문에 정말 좋습니다.

그것들은 단지 설정하고 가져오고 아마도 상당한 양의 코드에 액세스하지 않는 일부 유효성 검사 인 경우 사용됩니다. 유효성 검사 중에 복잡한 개체를 만드는 것은 간단하지 않으므로주의하십시오.

다른 방법은 선호되는 방법입니다.

의미에 관한 것이 아닙니다. Visual Studio Visual Designer에서 속성을 사용하면 부적절한 시작이 이상해집니다.

예를 들어 클래스의 속성 내에서 구성 값을 얻었습니다. 구성 클래스는 실제로 파일을 열고 SQL 쿼리를 실행하여 해당 구성의 값을 얻습니다. 이로 인해 내 응용 프로그램이 아닌 Visual Studio 자체에서 구성 파일을 열고 잠그는 응용 프로그램에서 문제가 발생했습니다 (설정 방법을 통해). 이 문제를 해결하려면 방금 메소드로 변경해야했습니다.


1

다음은 Bill Wagner의 속성과 메서드를 사용하는시기에 대한 유용한 지침 입니다.

  • 이 모든 것이 참일 때 속성을 사용하십시오. 게터는 단순해야하므로 예외가 발생하지 않습니다. 이는 네트워크 (또는 데이터베이스) 액세스가 없음을 의미합니다. 실패 할 수 있으므로 예외가 발생합니다.
  • 그들은 서로 의존해서는 안됩니다. 여기에는 한 속성을 설정하고 다른 속성에 영향을주는 것이 포함됩니다. 예를 들어 FirstName 속성을 설정하면 이름 + 성 속성을 구성하는 읽기 전용 FullName 속성에 영향을 미치므로 이러한 종속성이 나타납니다.
  • 어떤 순서로든 설정 가능해야합니다.
  • 게터에는 관찰 가능한 부작용이 없습니다.이 가이드 라인은 속성에서 일부 형태의 게으른 평가를 배제하지 않습니다.
  • 메소드는 항상 즉시 리턴해야합니다. 데이터베이스 액세스 호출, 웹 서비스 호출 또는 기타 유사한 작업을 수행하는 속성은 제외됩니다.
  • 멤버가 배열을 반환하는 경우 메서드를 사용하십시오.
  • 게터에 대한 반복 된 호출 (중재 코드없이)은 동일한 값을 반환해야합니다.
  • 동일한 값을 가진 세터에 대한 반복 호출은 단일 호출과 차이가 없어야합니다.

  • get은 내부 데이터 구조에 대한 참조를 반환해서는 안됩니다 (항목 23 참조). 메소드는 깊은 사본을 리턴 할 수 있으며이 문제를 피할 수 있습니다.

* 중복 된 질문에 대한 답을 얻었습니다.


최고 평점 및 수락 된 답변 here stackoverflow.com/a/1294189/1551 왜 downvote?
Chris Ballance

2
나는 파티에 조금 늦었다는 것을 알고 있지만, 당신의 답을 복사하여 붙여 넣은 사실로 인해 공감대가 생겼을 가능성이 높습니다. 복사 붙여 넣기를 통해이 질문은 기본적으로 다른 질문과 중복됨을 인정했습니다. 따라서 응답하지 않고 중복으로 플래그를 지정해야합니다. 내가 보는 것이 좋습니다 메타에 대한 기사 처리하는 방법을 중복 질문.
Joshua

0

이것은 간단합니다.

1 : 필드에 저장하기 전에 데이터의 유효성을 검사하려는 경우 속성을 사용하십시오. 따라서 이런 방식으로 속성은 필드를 캡슐화합니다. 당신이 당신의 분야를 떠나면 최종 사용자는 나이와 같은 비즈니스 요구 사항에 따라 유효하거나 유효하지 않을 수있는 값을 18보다 커야합니다. 따라서 가치가 상점에 해당하는 필드이기 전에 우리는 그 유효성을 확인해야합니다. 이런 식으로 속성은 데이터를 나타냅니다.

2 : 일부 데이터를 매개 변수로 제공하고 메소드가 제공된 값을 기반으로 일부 처리를 수행하고 처리 된 값을 출력으로 리턴하는 등의 조치를 수행하려는 경우 메소드를 사용하십시오. 또는이 계산으로 일부 필드의 값을 변경하려고합니다. "이 방법으로 방법은 행동을 나타냅니다".


-1

나는 자바에서 왔으며 get .. set .. 메소드를 잠시 사용했다.

코드를 작성할 때 스스로에게 묻지 않습니다. "이 데이터에 액세스하는 것이 간단하거나 많은 프로세스가 필요합니까?" 상황이 바뀔 수 있기 때문에 (오늘날이 속성을 검색하는 것은 간단합니다. 내일은 일부 또는 무거운 프로세스가 필요할 수 있습니다).

오늘은 SetAge (int age) tomonrow 메소드를 가지고 있으며, birthdate를 사용하여 나이를 계산하는 SetAge (date birthdate) 메소드도 있습니다.

컴파일러가 get 및 set 속성을 변환한다는 점에 매우 실망했지만 내 Get ... 및 Set .. 메서드는 동일하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.