C #에서 필드와 속성의 차이점 은 무엇입니까? 그러나 내 질문은 (내 관점에서) 약간의 차이가 있습니다.
내가 알면
- 나는 “속성에서만 작동하는 기술”과 함께 수업을 사용하지 않을 것이며
- getter / setter에서 유효성 검사 코드를 사용하지 않습니다.
속성 설정의 일부 유형의 제어와 같은 차이점 (스타일 / 미래 개발 항목 제외)이 있습니까?
다음과 같은 추가 차이점이 있습니까?
public string MyString { get; set; }
과
public string myString;
(첫 번째 버전에는 C # 3.0 이상이 필요하며 컴파일러는 개인 필드를 생성한다는 것을 알고 있습니다.)
답변
캡슐화.
두 번째 인스턴스에서는 방금 변수를 정의했으며 첫 번째에는 변수 주위에 getter / setter가 있습니다. 따라서 나중에 변수의 유효성을 검사하기로 결정하면 훨씬 쉬워집니다.
또한 Intellisense에서는 다르게 표시됩니다. 🙂
편집 : OP 업데이트 업데이트 질문-다른 제안을 무시하려면 다른 이유는 단순히 OO 디자인이 좋지 않기 때문입니다. 그리고 그럴만 한 이유가 없다면 항상 공개 변수 / 필드보다 속성을 선택하십시오.
답변
필드와 속성은 동일하게 보이지만 다릅니다. 속성은 메서드이므로 속성에 지원되지 않는 특정 사항 및 속성에는 발생할 수 있지만 필드의 경우에는 전혀 발생하지 않는 사항이 있습니다.
차이점 목록은 다음과 같습니다.
- 필드는
out/ref
인수의 입력으로 사용할 수 있습니다 . 속성은 할 수 없습니다. - 필드는 여러 번 호출 될 때 항상 동일한 결과를 생성합니다 (여러 스레드에 대한 문제를 생략 한 경우). 과 같은 속성
DateTime.Now
이 항상 자신과 같지는 않습니다. - 속성은 예외를 던질 수 있습니다-필드는 절대 그렇게하지 않습니다.
- 속성에 부작용이 있거나 실행하는 데 시간이 오래 걸릴 수 있습니다. 필드는 부작용이 없으며 주어진 유형에 대해 항상 예상되는 것보다 빠릅니다.
- 속성은 getter / setters에 대해 서로 다른 접근성을 지원합니다. 필드는 지원하지 않습니다 (그러나 필드를 만들 수는 있음
readonly
). - 리플렉션을 사용할 때 속성과 필드는 다르게 취급되어 다르게
MemberTypes
위치합니다 ( 예 :GetFields
vsGetProperties
) - JIT 컴파일러는 필드 액세스와 비교하여 속성 액세스를 매우 다르게 처리 할 수 있습니다. 그러나 동일한 네이티브 코드로 컴파일 할 수는 있지만 차이의 범위가 있습니다.
답변
몇 가지 빠르고 명백한 차이점
-
속성에는 접근 자 키워드가있을 수 있습니다.
public string MyString { get; private set; }
-
하위 항목에서 속성을 재정의 할 수 있습니다.
public virtual string MyString { get; protected set; }
답변
근본적인 차이점은 필드는 지정된 유형의 데이터가 저장되는 메모리의 위치입니다. 특성은 지정된 유형의 값을 검색하거나 설정하기 위해 실행되는 하나 또는 두 개의 코드 단위를 나타냅니다. 이러한 접근 자 메서드의 사용은 필드처럼 동작하는 것처럼 보이는 멤버 (할당 작업의 양쪽에 나타날 수 있음)를 사용하여 구문 적으로 숨겨집니다.
답변
접근자는 필드 이상입니다. 다른 사람들은 이미 몇 가지 중요한 차이점을 지적했으며 하나 더 추가 할 것입니다.
속성은 인터페이스 클래스에 참여합니다. 예를 들면 다음과 같습니다.
interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
이 인터페이스는 여러 가지 방법으로 만족 될 수 있습니다. 예를 들면 다음과 같습니다.
class Person: IPerson
{
private string _name;
public string FirstName
{
get
{
return _name ?? string.Empty;
}
set
{
if (value == null)
throw new System.ArgumentNullException("value");
_name = value;
}
}
...
}
이 구현에서 우리는 Person
클래스가 유효하지 않은 상태가되는 것과 호출자가 할당되지 않은 속성에서 null을 얻는 것을 막고 있습니다.
그러나 디자인을 더욱 발전시킬 수있었습니다. 예를 들어, 인터페이스가 setter를 처리하지 않을 수 있습니다. IPerson
인터페이스 소비자 는 속성을 설정하는 것이 아니라 속성을 얻는 데에만 관심이 있다고 말하는 것은 합법적입니다 .
interface IPerson
{
string FirstName { get; }
string LastName { get; }
}
Person
클래스 의 이전 구현은 이 인터페이스를 충족시킵니다. 호출자가 속성을 설정할 수 있다는 사실은 소비자 (소비자)의 관점에서 의미가 없습니다 IPerson
. 구체적인 구현의 추가 기능은 예를 들어 빌더에 의해 고려됩니다.
class PersonBuilder: IPersonBuilder
{
IPerson BuildPerson(IContext context)
{
Person person = new Person();
person.FirstName = context.GetFirstName();
person.LastName = context.GetLastName();
return person;
}
}
...
void Consumer(IPersonBuilder builder, IContext context)
{
IPerson person = builder.BuildPerson(context);
Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}
이 코드에서 소비자는 부동산 세터에 대해 알지 못합니다. 자신의 사업이 아닙니다. 소비자는 게터 만 필요하며 인터페이스, 즉 계약에서 게터를 얻습니다.
완전히 유효한 또 다른 구현은 IPerson
불변 인 개인 클래스와 해당 개인 팩토리입니다.
class Person: IPerson
{
public Person(string firstName, string lastName)
{
if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName))
throw new System.ArgumentException();
this.FirstName = firstName;
this.LastName = lastName;
}
public string FirstName { get; private set; }
public string LastName { get; private set; }
}
...
class PersonFactory: IPersonFactory
{
public IPerson CreatePerson(string firstName, string lastName)
{
return new Person(firstName, lastName);
}
}
...
void Consumer(IPersonFactory factory)
{
IPerson person = factory.CreatePerson("John", "Doe");
Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}
이 코드에서 샘플 소비자는 다시 한 번 속성을 채울 지식이 없습니다. 소비자는 게터와 구체적인 구현 (이름이 비어있는 경우 테스트와 같은 배후의 비즈니스 논리) 만 처리하며 특수 클래스 (빌더 및 공장)에 맡겨집니다. 이러한 모든 작업은 필드에서 완전히 불가능합니다.
답변
첫번째:
public string MyString {get; set; }
속성입니다; 두 번째 ( public string MyString
)는 필드를 나타냅니다.
차이점은 특정 기술 (인스턴스에 대한 ASP.NET 데이터 바인딩)은 속성이 아닌 필드에서만 작동한다는 것입니다. XML 직렬화의 경우에도 마찬가지입니다. 속성 만 직렬화되고 필드는 직렬화되지 않습니다.
답변
대부분의 경우 속성과 필드는 비슷해 보이지만 그렇지 않습니다. 필드에 존재하지 않는 속성에는 제한이 있으며 그 반대도 마찬가지입니다.
다른 사람들이 언급했듯이. 접근자를 비공개로 설정하여 속성을 읽기 전용 또는 쓰기 전용으로 만들 수 있습니다. 필드로는 그렇게 할 수 없습니다. 필드는 불가능하지만 속성은 가상 일 수도 있습니다.
속성을 getXXX () / setXXX () 함수의 구문 설탕으로 생각하십시오. 이것이 그들이 무대 뒤에서 어떻게 구현되는지입니다.