List에서 상속하지 않는 이유는 무엇입니까?
프로그램을 계획할 때, 저는 종종 다음과 같은 일련의 생각으로 시작합니다.
축구팀은 축구선수들의 명단일 뿐이다.따라서 다음과 같이 표현해야 합니다.
var football_team = new List<FootballPlayer>();이 리스트의 순서는 선수가 로스터에 등재된 순서를 나타냅니다.
그러나 나중에 깨달은 것은 팀은 단순한 선수 명단 외에 기록해야 할 다른 특성도 가지고 있다는 것입니다.를 들어, 이번 , 색상, a, 를, 번, 재, 재, 니, 니, 니, 니, 니 등입니다.string팀명 등을 나타내는 것
그래서 나는 생각한다:
, A, A, A)도 있습니다. 하지만 거기엔 이름이 있어.
string중인 ( ))int를 제공하지 에, 저는제 .NET은 축구팀을 저장하는 클래스를 제공하지 않기 때문에, 저는 제 클래스를 만듭니다.이 있는 는 the장 is is is is is is is is is is is is is is is is is is is is is is is이다.List<FootballPlayer>다음과 같이 합니다.class FootballTeam : List<FootballPlayer> { public string TeamName; public int RunningTotal }
하지만 가이드라인에 따르면 로부터 물려받지 말아야 합니다.나는 이 가이드라인에 두 가지 점에서 완전히 혼란스럽다.
왜 안 되나요?
아무래도 퍼포먼스에 최적화 되어 있는 것 같아요.어떻게요?확장하면 어떤 성능 문제가 발생합니까?List확히 뭐뭐 ?서 ?? ???
는 '하다'는 이다.ListMicrosoft가 제공하는 것으로, 저는 제어할 수 없기 때문에, 「퍼블릭 API」를 공개하면 나중에 변경할 수 없습니다.하지만 나는 이것을 이해하려고 애쓴다.퍼블릭 API란 무엇이며 왜 신경을 써야 합니까?현재 진행 중인 프로젝트에 이 공개 API가 없거나 앞으로도 없을 것 같다면 이 지침을 무시해도 될까요?에서 상속받으면List 공개 API가 필요했는데 어떤 어려움이 있을까요?
그게 왜 중요하죠?리스트는 리스트입니다.무엇이 바뀔 수 있을까요?내가 바꾸고 싶은 게 뭘까?
가 상속을 않는 List 왜 않았습니까?sealed
또 뭐 쓸까?
컬렉션에 , 는 「Microsoft」를 것을 알 수 .Collection" "가 "List그러나 이 클래스는 매우 빈털터리로, 예를 들어 유용한 것이 많지 않습니다.jvitor83의 답변은 특정 방법에 대한 성능 근거를 제공하지만 속도가 느린 이유는 무엇입니까?AddRange AddRange
속처에서 Collection 더 이다.List이득이 없다고 생각합니다. 없이 것이다 나는 뭔가 것 않을 수 나는 그것을 하고 있다.그래서 나는 내가 뭔가 오해하고 있다는 느낌을 받지 않을 수 없다.Collection사실 제 문제에 대한 올바른 해결책이 아닙니다.
'하다' 요.IList의 상용 수 없어요이건 수십 줄의 상용 코드인데 아무 것도 얻지 못했어.
.List in인가 in in:
class FootballTeam
{
public List<FootballPlayer> Players;
}
여기에는 다음 두 가지 문제가 있습니다.
그것은 내 코드를 불필요하게 장황하게 만든다.는 이제 한다.
my_team.Players.Count한 것이my_team.Count할 수List그건 야!...지만만 그은많많 !호!!!!그 모든 일에 대해 내가 얻는 것은 무엇인가?이건 그냥 말이 안 돼축구팀에는 선수 명단이 없습니다.선수 명단입니다.당신은 존 맥풋볼러가 썸팀 선수들에 합류했다고 말하지 않는다."존이 썸팀에 가입했다"고 말합니다.문자열에 문자를 추가하는 것이 아니라 문자열에 문자를 추가하는 것입니다.도서관 책에 책을 추가하는 것이 아니라 도서관에 책을 추가하는 것입니다.
'밑에서' 일어나는 일은 'Y의 내부 리스트에 X를 추가하는 것'이라고 할 수 있지만, 이것은 매우 직관에 반하는 세계관념인 것 같다.
질문(요약)
C#입니까? 즉, 인간의 마음에 이것은, 「논리적으로」(즉, 「인간의 마음에」)입니다.listthings과과휘 파파 ?파? ????
에서 상속되고 있다List<T>상상용 납납 ??? ??? ???제제 받을 ?? ???아/어 주세요?가 에서 할 때 할 List<T>안안??
여기 몇 가지 좋은 답이 있습니다.나는 그들에게 다음과 같은 점을 덧붙인다.
데이터 구조를 논리적으로 표현하는 올바른 C# 방법은 무엇입니까? 즉, "인간의 마음에"라는 것은 몇 가지 벨과 휘파람으로 이루어진 목록입니다.
축구의 존재를 잘 아는 컴퓨터 프로그래머가 아닌 10명에게 빈칸을 채우도록 요청하십시오.
축구팀은 _____의 특정 종류입니다.
"종소리와 휘파람이 적은 축구선수 명단"이라고 말하는 사람이 있는가, 아니면 "스포츠팀" "클럽" "조직"이라고 말하는 사람이 있는가?축구팀이 특정한 종류의 선수 명단이라는 당신의 생각은 당신 마음과 당신 마음에만 있다.
List<T>메커니즘입니다.풋볼팀은 비즈니스 객체입니다.즉, 프로그램의 비즈니스 영역에 있는 개념을 나타내는 객체입니다.섞지 마!축구팀은 일종의 팀이다; 그것은 선수 명단을 가지고 있고, 선수 명단은 선수들의 명단이다.선수 명단은 특정한 종류의 선수 명단이 아니다.선수 명단은 선수 명단이다.그래서 '그냥'이라고 불리는Roster은 ,입니다.List<Player> 그것을 ReadOnlyList<Player>풋볼 팀에 대해 아는 모든 사람이 선수 명단에서 선수를 삭제할 수 있다고 믿지 않는 한 말이야
에서 상속되고 있다
List<T>상상용 납납 ??? ??? ???
누구에게 받아들여지지 않는가?나? 아니야.
언제 받을 수 있어요?
메커니즘을 확장하는 메커니즘을 만들 때.
가 에서 할 때 할
List<T>안안??
메커니즘이나 비즈니스 오브젝트를 구축하고 있습니까?
하지만 그건 많은 암호야!그 모든 일에 대해 내가 얻는 것은 무엇인가?
에는 더 해서 '쓸 수 것'이라는 질문을 .List<T>50분 동안 은 분명서는 아주 양의 은 몇 입니다.장황함을 두려워하지 않는 것은 분명합니다.여기서는 아주 적은 양의 코드에 대해 이야기하고 있습니다.이것은 몇 분간의 작업입니다.
갱신하다
나는 그것에 대해 좀 더 생각해 보았고 축구팀을 선수 목록으로 만들지 말아야 할 또 다른 이유가 있다.사실 축구팀을 선수 명단이 있는 것처럼 모델화 하는 것은 좋지 않은 생각일 수도 있다.팀의 선수 명단이 있는 것의 문제점은 당신이 가지고 있는 것이 한 순간에 팀의 스냅숏이라는 것입니다.이 수업의 비즈니스 케이스는 모르겠지만, 만약 내가 축구팀을 대표하는 수업을 듣는다면, 나는 "2003년에서 2013년 사이에 부상으로 경기에 빠진 시호크 선수 몇 명이나?" 또는 "다른 팀에서 뛰었던 덴버 선수가 매년 야드 수가 가장 많이 증가했는가?"와 같은 질문을 던지고 싶다."혹은 "올해 돼지 가족은 끝까지 갔나요?"
즉, 축구팀은 선수의 영입, 부상, 은퇴 등 역사적 사실의 집합체로서 잘 모델화되어 있는 것 같습니다.현재의 선수 명단은 아마도 전면과 중앙에 있어야 할 중요한 사실이지만, 이 오브젝트에 대해 좀 더 역사적인 관점을 필요로 하는 다른 흥미로운 일들이 있을 수 있습니다.
와, 당신의 게시물은 많은 질문과 요점을 가지고 있다.마이크로소프트에서 얻을 수 있는 대부분의 추론은 정확히 들어맞습니다. 그럼 이 모든 해 볼까요?List<T>
List<T>매우 최적화되어 있습니다.그 주된 용도는 오브젝트의 프라이빗 멤버로 사용되는 것입니다.- Microsoft 에 microsoft 、 다 microsoft microsoft 、 microsoft microsoft microsoft microsoft microsoft microsoft microsoft 、 microsoft microsoft microsoft microsoft microsoft microsoft microsoft microsoft microsoft microsoft 。
class MyList<T, TX> : List<CustomObject<T, Something<TX>> { ... }할 수var list = new MyList<int, string>();. - CA1002 : 범용 리스트는 공개하지 말아 주세요.기본적으로 이 앱을 단독 개발자로 사용할 계획이라도 좋은 코딩 프랙티스로 개발할 가치가 있기 때문에 당신과 제2의 천성에 주입할 수 있습니다.리스트는 아직 공개가 허가되어 있습니다.
IList<T>색인화된 목록을 원하는 소비자가 있는지 확인합니다.이렇게 하면 나중에 클래스 내에서 구현을 변경할 수 있습니다. - †
Collection<T>알 수 그 이름이 모든 것을 말해준다; 그것은 단지 수집품일 뿐이다.이 있다, 보다 정확한 이 있다.SortedCollection<T>,ObservableCollection<T>,ReadOnlyCollection<T>을 , , , , , , , , 「 。IList<T>하지만 아니다List<T>. Collection<T>에서는 멤버(추가, 삭제 등)가 가상이기 때문에 덮어쓸 수 있습니다.List<T>지지않않않않- 당신의 질문의 마지막 부분은 정확합니다.축구팀은 단순한 선수 명단 이상의 것이므로, 그 선수 명단을 포함하는 클래스가 되어야 한다.구성 대 상속을 생각합니다.축구팀에는 선수 명단(명부)이 있지만 선수 명단은 선수 명단이 아닙니다.
이 코드를 작성하면 클래스는 다음과 같이 됩니다.
public class FootballTeam<T>//generic class
{
// Football team rosters are generally 53 total players.
private readonly List<T> _roster = new List<T>(53);
public IList<T> Roster
{
get { return _roster; }
}
// Yes. I used LINQ here. This is so I don't have to worry about
// _roster.Length vs _roster.Count vs anything else.
public int PlayerCount
{
get { return _roster.Count(); }
}
// Any additional members you want to expose/wrap.
}
class FootballTeam : List<FootballPlayer>
{
public string TeamName;
public int RunningTotal;
}
이전 코드는 거리에서 축구를 하는 많은 남자들이 우연히 이름을 가지고 있다는 것을 의미합니다.예를 들어 다음과 같습니다.

어쨌든 이 코드는 (m-y의 답변에서)
public class FootballTeam
{
// A team's name
public string TeamName;
// Football team rosters are generally 53 total players.
private readonly List<T> _roster = new List<T>(53);
public IList<T> Roster
{
get { return _roster; }
}
public int PlayerCount
{
get { return _roster.Count(); }
}
// Any additional members you want to expose/wrap.
}
수단: 경영진, 선수, 관리자 등이 있는 축구팀입니다.예를 들어 다음과 같습니다.

당신의 논리는 이렇게 그림으로 표현되고 있습니다.
이 경우는 다음과 같습니다.
그 팀은 행동이 추가된 선수 명단인가요?
또는
그 팀은 선수 명단을 가지고 있는 그들만의 대상인가?
목록을 확장하면 다음과 같은 여러 가지 방법으로 자신을 제한할 수 있습니다.
접근 권한을 제한할 수 없습니다(예: 사용자 목록 변경 금지).List 메서드는 모두 필요 또는 필요 여부에 관계없이 모두 사용할 수 있습니다.
다른 것들의 목록도 갖고 싶다면 어떻게 해야 할까요?예를 들어, 팀에는 코치, 매니저, 팬, 장비 등이 있습니다.그들 중 일부는 그 자체로 목록이 될 수 있다.
상속 옵션을 제한합니다.예를 들어, 일반 팀 오브젝트를 작성한 후 BaseballTeam, FootballTeam 등을 상속할 수 있습니다.목록에서 상속하려면 팀에서 상속을 수행해야 하지만, 이는 모든 다양한 유형의 팀이 해당 로스터의 동일한 구현을 수행해야 함을 의미합니다.
구성 - 개체 내에서 원하는 동작을 제공하는 개체를 포함합니다.
상속 - 개체가 원하는 동작을 가진 개체의 인스턴스가 됩니다.
둘 다 용도가 있지만, 이것은 구성이 더 나은 분명한 경우입니다.
모두가 지적했듯이 선수단은 선수 명단이 아니다.이 실수는 아마도 다양한 수준의 전문 지식을 가진 많은 사람들에 의해 저질러진다.이 경우처럼 종종 문제가 미묘하고 때로는 매우 심각합니다.이러한 설계는 리스코프 대체 원칙을 위반하기 때문에 좋지 않습니다.인터넷에는 이 개념을 설명하는 좋은 기사가 많이 있습니다.예: http://en.wikipedia.org/wiki/Liskov_substitution_principle
요약하면 클래스 간의 부모/자녀 관계에는 다음 두 가지 규칙이 있습니다.
- 자녀는 부모를 완전히 정의하는 것 이상의 특성을 요구해서는 안 됩니다.
- 부모는 자녀를 완전히 정의하는 것 외에 어떠한 특성도 요구하지 않아야 합니다.
즉, 부모란 자녀에 대한 필수 정의이며 자녀는 부모에 대한 충분한 정의입니다.
여기 하나의 해결책을 잘 생각해보고 이러한 실수를 피할 수 있도록 위의 원칙을 적용하는 방법이 있다.부모 클래스의 모든 연산이 구조적으로나 의미론적으로 파생 클래스에 유효한지 검증함으로써 가설을 검증해야 한다.
- 축구팀은 축구선수 명단입니까? (목록의 모든 속성이 같은 의미의 팀에 적용됩니까?)
- 팀은 동질적인 실체의 집합입니까?네, 팀은 플레이어의 집합입니다.
- 참가자의 포함 순서가 팀의 상태를 기술하고 있으며, 팀은 명시적으로 변경되지 않는 한 순서가 유지되도록 보장하고 있는가?아니요, 그리고 아니요
- 팀 내 순차적 위치에 따라 참가자가 포함되거나 제외될 것으로 예상됩니까?아니요.
보시다시피, 리스트의 첫 번째 특성만 팀에 적용됩니다.따라서 팀은 목록이 아닙니다.리스트는 팀을 관리하는 방법에 대한 구현 세부사항이기 때문에 플레이어 객체를 저장하고 팀 클래스의 메서드를 사용하여 조작해야 합니다.
이 시점에서 팀 클래스는 리스트를 사용해 실장하는 것이 아니라 대부분의 경우 세트 데이터 구조(HashSet 등)를 사용해 실장하는 것이 좋다고 생각합니다.
이 what가FootballTeam인인 팀팀 께께 저?? ???
class FootballTeam
{
List<FootballPlayer> Players { get; set; }
List<FootballPlayer> ReservePlayers { get; set; }
}
그걸 어떻게 모델로 삼을 건데?
class FootballTeam : List<FootballPlayer>
{
public string TeamName;
public int RunningTotal
}
그 관계는 분명히 a가 있고 a가 아니다.
★★★★★★★★★★★★★★★★★」RetiredPlayers
class FootballTeam
{
List<FootballPlayer> Players { get; set; }
List<FootballPlayer> ReservePlayers { get; set; }
List<FootballPlayer> RetiredPlayers { get; set; }
}
이름을 합니다.SomethingCollection
does용 does does does does ?SomethingCollection의미론적으로 말이 되나요?이 조작은, 타입이 다음의 컬렉션인 경우에만 실시해 주세요.Something.
FootballTeamA ATeam is a Collection.A.ATeam다른 답변에서 지적한 바와 같이 코치, 트레이너 등을 둘 수 있습니다.
FootballCollection축구공이나 축구 용품을 모아놓은 것처럼 들리네요. TeamCollection, 팀 모음집, 팀 모음집, 팀 모음집 팀 모음.
FootballPlayerCollection에서 상속되는 클래스의 유효한 이름이 될 플레이어의 집합처럼 들린다.List<FootballPlayer>네가 정말 그러고 싶다면 말이야
이에요.List<FootballPlayer>어쩌면 그럴지도 모른다.IList<FootballPlayer>이치노
정리하다
자신에게 물어보아라.
★
XaY? 또는 HasXaY제 반 이름이 그런 의미인가요?
[디자인] >
어떤 메서드와 속성을 표시할지는 설계 결정 사항입니다.상속하는 기본 클래스는 구현 세부 정보입니다.나는 전자로 한 걸음 물러설 가치가 있다고 생각한다.
개체는 데이터 및 동작의 집합입니다.
첫 번째 질문은 다음과 같습니다.
- 작성하는 모델에서 이 오브젝트는 어떤 데이터로 구성되어 있습니까?
- 이 개체는 해당 모델에서 어떤 동작을 나타냅니까?
- 이것은 장래에 어떻게 변화할 것인가?
유전은 "isa" (a) 관계를 의미하고, 구성은 "hasa" 관계를 의미한다는 것을 기억하십시오.애플리케이션의 진화에 수반해, 상황에 최적인 것을 선택해 주세요.
구체적인 타입으로 생각하기 전에 인터페이스로 생각하는 것을 고려해 주세요.그렇게 하면 뇌를 「디자인 모드」로 하기 쉬워지는 사람이 있기 때문입니다.
이것은 일상 코딩의 이 레벨에서 모두가 의식적으로 하는 것이 아닙니다.하지만 이런 주제를 곰곰이 생각하고 있다면, 당신은 디자인 물속을 밟고 있는 것입니다.그것을 아는 것은 자유로울 수 있다.
설계 세부 사항 검토
, 그럼 ㄴㄴㄴ데를 한 번 보세요.List<T> ★★★★★★★★★★★★★★★★★」IList<T>MSDN 비주얼 스튜디오어떤 메서드와 속성이 노출되는지 확인합니다.은 모두 어떤 요?FootballTeam어떻게 생각하십니까?
footballTeam.Reverse()해가되??? ??footballTeam.ConvertAll<TOutput>()가가원 하처 ?? ????
이것은 속임수 질문이 아닙니다. '먹다'는 '먹다'는 '먹다'는 '먹다'는 '먹다'입니다.「」/「」를 실장List<Player> ★★★★★★★★★★★★★★★★★」IList<Player>고객님의 모델에 이상적이라면 그렇게 하십시오.
'라고 판단했을 하고, 의 집합할 수 하고 경우, '행동'을 구현하고 .ICollection<Player> ★★★★★★★★★★★★★★★★★」IList<Player>꼭 그렇게 해 주세요.★★★★★★★★★★★★★★★★★★:
class FootballTeam : ... ICollection<Player>
{
...
}
오브젝트에 플레이어(데이터)의 컬렉션/목록을 포함시키고 싶은 경우 컬렉션 또는 목록을 속성 또는 멤버로 하려면 반드시 그렇게 하십시오.개념상:
class FootballTeam ...
{
public ICollection<Player> Players { get { ... } }
}
당신은 사람들이 플레이어를 세거나 추가 또는 삭제하기 보다는 열거만 할 수 있기를 원할 수 있습니다. IEnumerable<Player>충분히 유효한 선택입니다.
이러한 인터페이스는, 사용의 모델에서는 전혀 도움이 되지 않는 경우가 있습니다.(적당하다.IEnumerable<T>많은 상황에서 도움이 됩니다.) 하지만 여전히 가능합니다.
이 중 하나가 모든 경우에 분명히 잘못되었다고 말하려는 사람은 잘못된 것입니다.당신에게 그것이 모든 경우에 절대적으로 옳다는 것을 말하려고 하는 사람은 잘못된 것입니다.
도입으로 이행하다
데이터 및 동작을 결정하면 구현에 대한 결정을 내릴 수 있습니다.여기에는 상속 또는 구성을 통해 의존하는 구체적인 클래스가 포함됩니다.
이것은 큰 스텝은 아닐지도 모릅니다.또, 설계와 실장이라고 하는 것은, 머릿속에서 1~2초만에 모든 것을 훑어보고, 타이핑을 개시하는 것이 가능하기 때문에, 사람들은 종종 혼동합니다.
사고 실험
인위적인 예: 다른 사람들이 언급했듯이, 한 팀이 항상 선수들의 "단순한" 집합은 아닙니다.팀의 매치 스코어 컬렉션을 유지하고 있습니까?당신의 모델은 클럽과 호환되나요?만약 그렇다면, 그리고 당신의 팀이 플레이어의 컬렉션을 가지고 있다면, 그것은 직원이나 스코어의 컬렉션도 가지고 있을 것입니다.그 후, 다음과 같은 결과가 됩니다.
class FootballTeam : ... ICollection<Player>,
ICollection<StaffMember>,
ICollection<Score>
{
....
}
설계상으로는 이에서 C#을 할 수 List<T>어쨌든 C#은 단일 상속을 지원하므로(이 malarkey를 C++로 사용해 본 적이 있는 경우는, 이것을 Good Thing이라고 생각할 수 있습니다).상속을 통한 수집과 구성을 통한 수집을 구현하면 지저분하게 느껴질 수 있습니다.또, 다음과 같은 속성Count 수 .ILIst<Player>.Count ★★★★★★★★★★★★★★★★★」IList<StaffMember>.Count그런 다음 혼란스럽기보다 고통스러울 뿐입니다.이것이 어디로 가고 있는지 알 수 있습니다.이 방법을 생각할 때의 직감은 이 방향으로 가는 것이 잘못되었다는 것을 말해 줄 것입니다(그리고 옳든 그르든, 만약 당신이 이 방법을 도입한다면 당신의 동료들도 마찬가지일 것입니다).
짧은 답변(너무 늦음)
컬렉션 클래스에서 상속하지 않는 것에 대한 지침은 C#에 고유하지 않습니다.여러 프로그래밍 언어로 제공됩니다.법이 아니라 지혜를 받는 것이다.한 가지 이유는 실제로 구성이 이해성, 구현성 및 유지보수의 측면에서 상속보다 유리하다고 여겨지기 때문입니다.특히 시간이 지남에 따라 객체의 정확한 데이터와 동작이 변화함에 따라 추상화되지 않는 한 유용하고 일관된 "isa" 관계보다 유용하고 일관된 "hasa" 관계를 찾는 것이 현실 세계/도메인 개체에서 더 일반적입니다.이로 인해 항상 컬렉션 클래스에서 상속이 제외되는 것은 아니지만 시사하는 바가 있을 수 있습니다.
선,, 사사과과 관관다다다다상속을 「」는Team클래스는 객체 조작만을 위해 설계된 동작(예: 동작)을 노출합니다.를 들어, 「」라고 하는 것은,AsReadOnly() ★★★★★★★★★★★★★★★★★」CopyTo(obj)메서드는 팀 오브젝트에 의미가 없습니다.AddRange(items) 더 알기 쉬운 AddPlayers(players)★★★★★★ 。
를 는, LINQ 의 범용 .ICollection<T> ★★★★★★★★★★★★★★★★★」IEnumerable<T>좀 더 말이 될 것 같아요
말했듯이, 작문은 올바른 방법이다.개인 변수로 플레이어 목록을 구현하기만 하면 됩니다.
질문을 다시 쓰겠습니다.그래서 다른 시각으로 볼 수도 있어요.
내가 축구팀을 대표해야 할 때, 나는 그것이 기본적으로 이름이라는 것을 이해한다.'독수리'처럼
string team = new string();
그리고 나서 나는 팀에도 선수가 있다는 것을 깨달았다.
선수 명단도 넣을 수 있도록 끈 타입을 늘리면 안 되는 이유는 무엇입니까?
그 문제에 대한 당신의 입장은 제멋대로입니다.팀이 가진 것이 무엇인지가 아니라 무엇이 있는지 생각해 보세요.
그런 다음 다른 클래스와 속성을 공유하는지 확인할 수 있습니다.그리고 유산에 대해 생각해 보세요.
문맥에 따라 다르다
당신의 팀을 선수 목록으로 간주할 때, 당신은 축구팀의 "아이디어"를 한 가지 측면으로 투영하고 있습니다."팀"을 필드에서 볼 수 있는 사람으로 축소합니다.이 예측은 특정 컨텍스트에서만 정확합니다.다른 맥락에서 보면 이는 완전히 잘못된 것일 수 있습니다.당신이 팀의 스폰서가 되고 싶다고 상상해 보세요.그러니까 팀장님과 상의하셔야 합니다.이 맥락에서 팀은 매니저의 리스트에 반영됩니다.그리고 이 두 목록은 보통 그다지 겹치지 않습니다.다른 맥락은 현재 대 이전 플레이어 등입니다.
불분명한 의미론
그래서 팀을 선수들의 목록으로 간주하는 것의 문제는 팀의 의미가 상황에 따라 달라지고 컨텍스트가 바뀌었을 때 확장될 수 없다는 것입니다.또한 어떤 컨텍스트를 사용하고 있는지 표현하기가 어렵습니다.
클래스는 확장 가능
하는 경우( " " )IList activePlayers멤버의 이름(및 멤버의 코멘트)을 사용하여 컨텍스트를 명확하게 할 수 있습니다.콘텍스트가 추가되어 있는 경우는 멤버를 추가하기만 하면 됩니다.
클래스가 더 복잡하다
경우에 따라서는 추가 클래스를 만드는 것이 오버킬이 될 수 있습니다.각 클래스 정의는 클래스 로더를 통해 로드되어야 하며 가상 시스템에 의해 캐시됩니다.이로 인해 런타임의 퍼포먼스와 메모리가 소비됩니다.당신이 매우 특정한 배경을 가지고 있다면, 축구팀을 선수 목록으로 생각해도 괜찮을 것이다.이 '아까', '아까', '아까', '아까' 이렇게 요. IList 가 아니라 것 , , , , , , , , , , ,.
결론 / 고려사항
매우 구체적인 문맥을 가지고 있을 때는 팀을 선수 리스트로 생각해도 괜찮습니다.예를 들어, 메서드 내에서는 다음과 같이 작성해도 전혀 문제가 없습니다.
IList<Player> footballTeam = ...
F# 를 사용하는 경우는, 다음의 타입의 약어를 작성할 수도 있습니다.
type FootballTeam = IList<Player>
그러나 문맥이 더 넓거나 불분명한 경우에는 이 작업을 수행하지 마십시오.이는 특히 나중에 사용할 수 있는 컨텍스트가 명확하지 않은 새 클래스를 만드는 경우에 해당됩니다.경고 표시는 클래스에 추가 속성(팀 이름, 코치 등)을 추가하기 시작하는 경우입니다.이는 클래스가 사용되는 컨텍스트가 고정되어 있지 않으며 향후 변경될 것이라는 명백한 신호입니다.이 경우 팀을 선수 목록으로 간주할 수 없지만 팀의 속성으로 현재 활동 중인 선수(부상되지 않은 선수 등) 목록을 모델링해야 합니다.
축구팀은 축구선수들의 명단이 아니다.축구팀은 축구선수들의 리스트로 구성되어 있다!
이것은 논리적으로 올바르지 않습니다.
class FootballTeam : List<FootballPlayer>
{
public string TeamName;
public int RunningTotal
}
그리고 이것은 옳습니다.
class FootballTeam
{
public List<FootballPlayer> players
public string TeamName;
public int RunningTotal
}
하기 때문이다.List<FootballPlayer> "has-a" 또는 "has-a"List<FootballPlayer>이 질문에는 쓰여진 그대로의 답변이 없습니다.
OP의 에 대해 해 줄 것을 .List<T>:
'고 있습니다.
List<T>왜왜????
★★★★★★★★★★★★★★★★★★List<T>이치노일반적으로 비교적 적은 고통으로 구현을 전환할 수 있기 때문에 자체 코드에서는 문제가 되지 않습니다. 그러나 퍼블릭 API에서는 훨씬 더 큰 문제가 될 수 있습니다.
퍼블릭 API란 무엇이며 왜 신경을 써야 합니까?
퍼블릭 API는 서드파티 프로그래머에게 공개하는 인터페이스입니다.프레임워크 코드를 생각해 보세요.그리고 참조되는 가이드라인이 "입니다.「NET Framework Design Guidelines(NET 프레임워크 설계 가이드라인)」가 아니라 「NET 프레임워크 설계 가이드라인「NET 애플리케이션 설계 가이드 라인」을 참조해 주세요.차이가 있는데, 일반적으로 공개 API 설계는 훨씬 더 엄격합니다.
현재 진행 중인 프로젝트에 이 공개 API가 없거나 앞으로도 없을 것 같다면 이 지침을 무시해도 될까요?List에서 상속받았는데 공개 API가 필요한 경우 어떤 어려움이 있습니까?
꽤 그래, 응.그 이면에 있는 이유를 생각해보고 그것이 당신의 상황에 적용되는지 여부를 확인하는 것이 좋을지도 모르지만, 만약 당신이 퍼블릭 API를 구축하지 않는다면, 당신은 특별히 API에 대해 걱정할 필요가 없다(이것은 서브셋이다).
(API를 하지 않음) .List<T>향후 발생할 수 있는 문제를 안고 지침을 위반할 수 있습니다.
그게 왜 중요하죠?리스트는 리스트입니다.무엇이 바뀔 수 있을까요?내가 바꾸고 싶은 게 뭘까?
이렇게 '어울리다'를 쓰잖아요.FootballTeam예를 들어, 추가가 불가능하다고 가정해 보십시오.FootballPlayer봉봉연면면 면면면면면면이를 추가할 수 있는 방법은 다음과 같습니다.
class FootballTeam : List<FootballPlayer> {
override void Add(FootballPlayer player) {
if (this.Sum(p => p.Salary) + player.Salary > SALARY_CAP)) {
throw new InvalidOperationException("Would exceed salary cap!");
}
}
}
하지만 그럴 순 없어override Addvirtual(일부러)
사용자와 경우, 를 사용하는 할 수 .IList<T>컴파일 오류를 복구합니다.
class FootballTeam : IList<FootballPlayer> {
private List<FootballPlayer> Players { get; set; }
override void Add(FootballPlayer player) {
if (this.Players.Sum(p => p.Salary) + player.Salary > SALARY_CAP)) {
throw new InvalidOperationException("Would exceed salary cap!");
}
}
/* boiler plate for rest of IList */
}
다만, 서드파티를 공개하고 있는 경우는, 컴파일 에러나 런타임 에러의 원인이 되는 변경을 실시했을 뿐입니다.
TL;DR - 공용 API에 대한 지침입니다.개인 API의 경우 원하는 작업을 수행합니다.
여기에는 많은 훌륭한 답변이 있지만, 저는 제가 보지 못한 것에 대해 언급하고 싶습니다.객체 지향 디자인은 객체에 힘을 실어주는 것입니다.
모든 규칙, 추가 작업 및 내부 세부 정보를 적절한 개체 내에 캡슐화합니다.이렇게 하면 이 하나와 상호작용하는 다른 개체는 이 모든 것을 걱정할 필요가 없습니다.실제로 한 걸음 더 나아가 다른 오브젝트가 이러한 내부 오브젝트를 바이패스하는 것을 적극적으로 방지해야 합니다.
에서 List기타 모든 오브젝트는 목록으로 표시할 수 있습니다.플레이어를 추가하거나 제거하는 방법에 직접 액세스할 수 있습니다.그러면 다음과 같이 통제력을 잃게 됩니다.
선수가 은퇴했는지, 사임했는지, 해고되었는지 여부를 확인하여 언제 은퇴하는지 구별하려고 합니다. 하면 '실현'을 할 수 요.RemovePlayer적절한 입력 열거를 사용하는 메서드입니다. 에서 List, , , , , , , to to to to to to to to에 직접 하는 것을 막을 수 Remove,RemoveAll그리고 심지어Clear그 결과, 당신은 실제로 힘을 잃었습니다.FootballTeam를 누릅니다
캡슐화에 대한 추가 정보...다음과 같은 문제를 제기했습니다.
그것은 내 코드를 불필요하게 장황하게 만든다.이제 제_팀에게 연락해야 합니다.플레이어.my_team만 세는 게 아니라 세는 거야.세어보세요.
맞습니다. 모든 고객이 귀사 팀을 이용하는 것은 불필요하게 장황할 것입니다.그 아주 입니다.List Players당신 동의 없이 당신 팀을 만지작거릴 수 있도록요
계속 말씀하세요.
이건 그냥 말이 안 돼축구팀에는 선수 명단이 없습니다.선수 명단입니다.당신은 존 맥풋볼러가 썸팀 선수들에 합류했다고 말하지 않는다."존이 썸팀에 가입했다"고 말합니다.
첫 번째 부분은 틀렸다: '리스트'라는 단어를 삭제하면, 사실 한 팀에 선수가 있다는 것은 명백하다.
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★에 의한 콜은 없습니다.ateam.Players.Add(...)ateam.AddPlayer(...), 실장에서는, ( 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」Players.Add(...)내부적으로
캡슐화가 오브젝트의 성능을 향상시키는 데 얼마나 중요한지 알 수 있기를 바랍니다.각 클래스가 다른 개체의 간섭을 두려워하지 않고 자신의 작업을 잘 수행하도록 허용하려고 합니다.
사람들이 말할 수 있게 해주나요?
myTeam.subList(3, 5);
말이 되나요?그렇지 않은 경우 목록이 되지 않아야 합니다.
이는 "팀" 객체의 동작에 따라 달라집니다.컬렉션과 동일하게 동작하는 경우 먼저 일반 목록으로 표현해도 됩니다.그러면 목록에서 반복되는 코드가 계속 중복된다는 것을 알게 될 수 있습니다. 이 시점에서 선수 목록을 줄바꿈하는 FootballTeam 개체를 만들 수 있습니다.FootballTeam 클래스는 선수 명단에서 반복되는 모든 코드의 홈이 됩니다.
그것은 내 코드를 불필요하게 장황하게 만든다.이제 제_팀에게 연락해야 합니다.플레이어.my_team만 세는 게 아니라 세는 거야.카운트. 다행히 C#에서는 인덱서를 정의하여 인덱스를 투명하게 하고 내부 목록의 모든 메서드를 전달할 수 있습니다.하지만 그건 많은 암호야!그 모든 일에 대해 내가 얻는 것은 무엇인가?
캡슐화고객은 Football Team 내부에서 무슨 일이 일어나고 있는지 알 필요가 없습니다.모든 고객이 알고 있듯이, 이것은 데이터베이스에서 플레이어 목록을 검색함으로써 구현될 수 있습니다.고객은 알 필요가 없으며, 이로 인해 디자인이 개선됩니다.
이건 그냥 말이 안 돼축구팀에는 선수 명단이 없습니다.선수 명단입니다.당신은 존 맥풋볼러가 썸팀 선수들에 합류했다고 말하지 않는다."존이 썸팀에 가입했다"고 말합니다.문자열에 문자를 추가하는 것이 아니라 문자열에 문자를 추가하는 것입니다.도서관 책에 책을 추가하는 것이 아니라 도서관에 책을 추가하는 것입니다.
정확히 :) 당신은 football team이라고 말할 것이다.풋볼팀이 아닌 추가(john)List.Add(john).내부 리스트는 표시되지 않습니다.
데이터 구조를 나타내는 올바른 C# 방법은 무엇입니까?
기억하라, "모든 모델은 틀리지만, 일부 모델은 유용하다." - 조지 E. P. 박스
"올바른 방법"은 없고, 유용한 방법만 있을 뿐이다.
사용자와 사용자에게 유용한 항목을 선택하십시오.바로 그겁니다.
무리하지 말고 경제적으로 발전하세요. 쓰는 코드가 적을수록 디버깅해야 할 코드가 줄어듭니다.
(다음 판을 읽습니다).
--편집필
제 최선의 대답은...사정에 따라 다르겠지.목록에서 상속하면 주로 Football Team이 비즈니스 엔티티처럼 보이기 때문에 이 클래스의 클라이언트가 노출되어서는 안 될 메서드에 노출됩니다.
-- 에디션 2
나는 진심으로 내가 "과잉 엔지니어"라는 코멘트에서 무엇을 언급했는지 기억나지 않는다.KISS의 사고방식은 좋은 가이드라고 생각합니다만, List에서 비즈니스 클래스를 상속하면 추상화 유출로 인해 해결보다 더 많은 문제가 발생한다는 점을 강조하고 싶습니다.
한편, 단순히 List에서 상속하는 것이 도움이 되는 경우는 한정되어 있다고 생각합니다.이전 판에서 썼던 것처럼 상황에 따라 다르죠.각 사례에 대한 답변은 지식, 경험 및 개인적 선호도에 크게 영향을 받습니다.
정답을 좀 더 정확하게 생각할 수 있도록 도와주신 @kai님 덕분입니다.
이것은 "A"와 "해당"의 트레이드오프를 떠올리게 합니다.때로는 슈퍼클래스로부터 직접 상속받는 것이 더 쉽고 말이 된다.독립형 클래스를 만들고 상속받은 클래스를 멤버 변수로 포함하는 것이 더 적절한 경우도 있습니다.클래스의 기능에 액세스 할 수 있습니다만, 인터페이스나 클래스로부터의 상속에 의해서 생기는 그 외의 제약에 얽매이지 않습니다.
어떤 일을 하세요?다른 많은 것들과 마찬가지로... 상황에 따라 다르죠제가 사용하고 싶은 가이드는 다른 클래스에서 상속받기 위해서는 진정한 'is a' 관계가 있어야 한다는 것입니다.그래서 만약 당신이 BMW라는 클래스를 쓴다면, 그것은 자동차로부터 물려받을 수 있다. 왜냐하면 BMW는 진정한 자동차이기 때문이다.말 클래스는 실제로 말은 포유동물이고 포유류의 기능은 말과 관련이 있어야 하기 때문에 포유동물 클래스에서 상속할 수 있습니다.하지만 팀이 리스트라고 말할 수 있나요?제가 알기로는 팀이 정말 "목록"인 것 같지는 않습니다.이 경우 멤버 변수로 List가 있습니다.
시리얼화 문제
One aspect is missing. Classes that inherit from List can't be serialized correctly using XmlSerializer. In that case DataContractSerializer must be used instead, or an own serializing implementation is needed.public class DemoList : List<Demo>
{
// using XmlSerializer this properties won't be seralized
// There is no error, the data is simply not there.
string AnyPropertyInDerivedFromList { get; set; }
}
public class Demo
{
// this properties will be seralized
string AnyPropetyInDemo { get; set; }
}
추가 정보:클래스가 List <>에서 상속된 경우 XmlSerializer는 다른 속성을 시리얼화하지 않습니다.
대신 IList 사용
개인적으로는 리스트에서 상속받지 않고 IList를 구현하고 싶다.Visual Studio가 대신 작업을 수행하고 완전히 작동하는 IPment를 만듭니다.여기를 봐 주세요.IList를 완전하게 실장하는 방법
가이드라인에 따르면 퍼블릭 API는 목록, 세트, 사전, 트리 등 사용 여부에 대한 내부 설계 결정을 공개해서는 안 됩니다."팀"은 반드시 목록이 아닙니다.목록으로 구현할 수 있지만 공개 API 사용자는 필요에 따라 사용자 클래스를 사용해야 합니다.이를 통해 퍼블릭인터페이스에 영향을 주지 않고 결정을 변경하여 다른 데이터 구조를 사용할 수 있습니다.
라고 말할 때List<T>'최적화라고 하는 것은, 고가의 탑재하고 않다는 합니다」라고 것입니다최적화'라고 하는 것은, 가상 방식등의 고비용의 기능이 없는 것을 의미한다고 생각합니다. ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.List<T>퍼블릭 API에서는 비즈니스 규칙을 적용하거나 나중에 기능을 커스터마이즈할 수 없습니다.그러나 이 상속된 클래스를 프로젝트 내에서 내부로 사용하는 경우(API로 수천 명의 고객/파트너/다른 팀에 노출될 가능성이 있는 것이 아니라), 시간을 절약하고 복제하고 싶은 기능만 있으면 됩니다.상속의 이점List<T>예측 가능한 미래에 커스터마이즈되지 않을 많은 바보같은 래퍼 코드를 제거한다는 것입니다. 클래스가 List<T>API를 사용합니다.
나는 많은 사람들이 단지 FxCop 규칙 때문에 많은 추가 작업을 하는 것을 종종 본다. 혹은 누군가의 블로그는 그것이 "나쁜" 관행이라고 말한다.많은 경우, 이것은 패턴 팔루자의 기묘함을 디자인하기 위한 코드를 변환합니다.많은 가이드라인과 마찬가지로 예외가 있을 수 있는 가이드라인으로 취급한다.
내 더러운 비밀:사람들이 뭐라고 하든 신경 안 쓰고 그냥 하는 거야NET Framework는 "Xxxx Collection" (머리 위의 예로는 UIElement Collection)으로 구성되어 있습니다.
그래서 내가 말하는 걸 멈출 수 있는 건:
team.Players.ByName("Nicolas")
내가 그것을 발견했을 때 보다
team.ByName("Nicolas")
또한 내 Player Collection은 코드 복제 없이 "Club"과 같은 다른 클래스에서 사용할 수 있습니다.
club.Players.ByName("Nicolas")
어제의 베스트 프랙티스는 내일의 베스트 프랙티스가 아닐 수도 있습니다.대부분의 베스트 프랙티스의 배경에는 이유가 없습니다.대부분은 커뮤니티 간의 폭넓은 합의일 뿐입니다.커뮤니티에 물어보는 대신, 자신에게 물어보면, 어떤 것이 더 읽기 쉽고 유지보수가 쉬울까요?
team.Players.ByName("Nicolas")
또는
team.ByName("Nicolas")
정말이에요. 무슨 의심이라도 있나요?List<를 사용할 수 없게 되는 다른 기술적 제약에 대처해야 할 수도 있습니다.T > 를 참조해 주세요.그러나 존재하지 않아야 할 제약은 추가하지 마십시오.마이크로소프트가 그 이유를 문서화하지 않았다면, 그것은 분명 어디서 나온 "베스트 프랙티스"일 것입니다.
대부분의 답변이 그렇듯이 복잡한 비교는 없지만, 이 상황에 대처하기 위한 방법을 공유하겠습니다.장으로 by를 IEnumerable<T>을해도 됩니다.Teamextensions (Linq의 모든 )List<T>.
class Team : IEnumerable<Player>
{
private readonly List<Player> playerList;
public Team()
{
playerList = new List<Player>();
}
public Enumerator GetEnumerator()
{
return playerList.GetEnumerator();
}
...
}
class Player
{
...
}
에게 베르트랑 마이어가 있다는 싶습니다.Team을 받다List<Player>눈 하나 깜짝하지 않고.
그의 저서 '개체 지향 소프트웨어 구성'에서 그는 직사각형 창에 하위 창이 있을 수 있는 GUI 시스템의 구현에 대해 설명합니다.그는 단순히WindowRectangle ★★★★★★★★★★★★★★★★★」Tree<Window>도입의 재이용에 도움이 됩니다.
하지만 C#은 에펠이 아닙니다.후자는 기능의 여러 상속 및 이름 변경을 지원합니다.C#에서는 서브클래스를 하면 인터페이스와 임프레메이션이 모두 상속됩니다.실장은 덮어쓸 수 있지만 발신자 규칙은 슈퍼 클래스에서 직접 복사됩니다.그러나 에펠에서는 공용 메서드의 이름을 수정하여 이름을 변경할 수 있습니다.Add ★★★★★★★★★★★★★★★★★」Remove로로 합니다.Hire ★★★★★★★★★★★★★★★★★」Fire 안에서Team의가 " " "인스턴스인 Team is is is is is is is is is is is is 로 거슬러 List<Player>는 「사용할 수 없다」를 합니다.Add ★★★★★★★★★★★★★★★★★」Remove 메서드 의 변경은 필요 없습니다.Hire ★★★★★★★★★★★★★★★★★」Fire출됩니니다다
클래스 사용자가 모든 메서드와 속성을 필요로 하는 경우** 목록에서 클래스를 파생해야 합니다.필요하지 않은 경우 목록을 동봉하고 클래스 사용자에게 실제로 필요한 메서드의 래퍼를 만듭니다.
퍼블릭 API를 작성하거나 많은 사람들이 사용하는 다른 코드를 작성할 경우 이는 엄격한 규칙입니다.작은 앱이 있고 개발자가 2명 이하인 경우에는 이 규칙을 무시해도 됩니다.이렇게 하면 시간을 절약할 수 있습니다.
작은 앱의 경우 덜 엄격한 다른 언어를 선택하는 것도 고려할 수 있습니다.Ruby, JavaScript - 코드를 적게 쓸 수 있는 모든 것.
저는 당신의 일반화에 동의하지 않는다고 생각합니다.팀은 단순히 선수들의 집합이 아닙니다.팀에는 이름, 엠블럼, 관리/관리 직원, 코칭 팀, 선수 등 훨씬 더 많은 정보가 있습니다.따라서 실제 세계를 적절하게 모델링하려면 Football Team 클래스가 컬렉션이 아니라 3개의 컬렉션이 있어야 합니다.
Specialized String Collection과 같은 Player Collection 클래스는 내부 스토어에 개체를 추가하거나 내부 스토어에서 개체를 제거하기 전에 유효성 검사 및 검사와 같은 다른 기능을 제공합니다.
Player Collection의 개념이 선호하시는 접근법에 맞는 것 같습니까?
public class PlayerCollection : Collection<Player>
{
}
그리고 풋볼팀은 이렇게 보일 수 있습니다.
public class FootballTeam
{
public string Name { get; set; }
public string Location { get; set; }
public ManagementCollection Management { get; protected set; } = new ManagementCollection();
public CoachingCollection CoachingCrew { get; protected set; } = new CoachingCollection();
public PlayerCollection Players { get; protected set; } = new PlayerCollection();
}
클래스보다 인터페이스 우선
클래스는 클래스에서 파생되는 것을 피하고 필요한 최소한의 인터페이스를 구현해야 합니다.
상속으로 캡슐화가 중단됨
- 컬렉션 구현 방법에 대한 내부 세부 정보를 제공합니다.
- 적절하지 않을 수 있는 인터페이스(퍼블릭 기능 및 속성 세트)를 선언합니다.
무엇보다도, 이것은 당신의 코드를 재팩터화하는 것을 더 어렵게 만든다.
클래스는 구현 세부 사항입니다.
클래스는 코드의 다른 부분에서 숨겨야 하는 구현 세부 정보입니다.로 요 in inSystem.List는 추상적인 데이터 타입의 특정 실장입니다.현재와 미래에 적절하지 않을 수도 있습니다.
개념적으로 데이터 유형이 "목록"이라고 불리는 것은 약간 과장된 것입니다.aSystem.List<T>는 요소의 추가, 삽입 및 삭제를 위한 상각 O(1) 연산과 요소의 수를 취득하거나 요소를 인덱스별로 취득 및 설정하는 O(1) 연산을 지원하는 가변 순서 컬렉션입니다.
인터페이스가 작을수록 코드의 유연성이 높아진다.
데이터 구조를 설계할 때 인터페이스가 단순할수록 코드가 유연해집니다.LINQ가 얼마나 강력한지 확인해 보세요.
인터페이스 선택 방법
"리스트"라고 생각할 때, 여러분은 스스로에게 "나는 야구 선수들의 컬렉션을 대표할 필요가 있다"고 말하는 것으로 시작해야 합니다.예를 들어, 수업에서 모델링을 하기로 결정했다고 가정해 보겠습니다.먼저 이 클래스에서 공개해야 하는 최소한의 인터페이스 양을 결정합니다.
이 프로세스를 안내하는 데 도움이 되는 몇 가지입니다.
- 세어볼 필요가 있나요?도입을 검토하지 않는 경우
- 이 컬렉션은 초기화 후 변경됩니까?고려하지 않을 경우.
- 인덱스로 항목에 액세스할 수 있는 것이 중요합니까?고려하다
- 컬렉션에 아이템을 추가하는 순서가 중요합니까?혹시?
- 이러한 것을 정말로 필요로 하는 경우는, 을 실장해 주세요.
이렇게 하면 코드의 다른 부분을 야구 선수 컬렉션의 구현 세부 정보와 결합하지 않고 인터페이스를 존중하는 한 구현 방법을 자유롭게 변경할 수 있습니다.
이 방법을 사용하면 코드를 읽기, 리팩터링 및 재사용하기 쉬워집니다.
보일러 플레이트 회피에 관한 주의사항
최신 IDE에서 인터페이스를 구현하는 것은 쉬울 것입니다.우클릭 후 [Implement Interface]를 선택합니다.그런 다음 필요에 따라 모든 구현을 멤버클래스로 전송합니다.
즉, 보일러 플레이트를 많이 쓰고 있는 것을 알게 되면, 필요한 것보다 더 많은 기능을 노출하고 있기 때문일 가능성이 있습니다.그것은 당신이 수업에서 물려받지 말아야 하는 것과 같은 이유입니다.
이러한 을 몇 할 수도 .이 내이다.IArrayLinkArray 라이브러리의 인터페이스입니다.
언제 받을 수 있어요?
Eric Lippert의 말을 인용하면:
메커니즘을 확장하는 메커니즘을 만들 때.
를 들어, '아까', '아까', '아까', '아까보다'가입니다.AddRange in the method in the method in 。IList<T>:
public interface IMoreConvenientListInterface<T> : IList<T>
{
void AddRange(IEnumerable<T> collection);
}
public class MoreConvenientList<T> : List<T>, IMoreConvenientListInterface<T> { }
선수를 필요로 하는 축구팀 만들기
넌 어떨지 모르겠지만, 선수들이 없는 축구팀은 들어본 적이 없어!그래서 네 직감이 옳았어그리고 안타깝게도 많은 답변들이 틀렸습니다!
요.FootballTeam에 넣다FootballPlayers그러나 FootballTeam 클래스를 작성할 때 클래스를 만드는 모든 사용자에게 FootballPlayers 목록을 삽입하도록 강제할 수 있습니다.
그게 더 논리적으로 이해가 되는데...
아래는 팀 클래스에 적합한 선수가 있는지 확인하기 위해 많이 입력된 FootBallTeam 클래스입니다.선수 명단이 비어 있는 팀을 만들 수도 있지만, 이 경우 당신은 그것에 대해 명시적입니다.
public class FootballPlayer
{
public string Name { get; set; }
public int Number { get; set; }
}
public class FootballTeam<TList> where TList : List<FootballPlayer>
{
private List<FootballPlayer> _players;
public FootballTeam(TList players)
{
_players = players;
}
}
// Now anyone using your class must insert a roster of players as a list!
var roster = new List<FootballPlayer>();
roster.Add(new FootballPlayer{ Name="Player1",Number=0});
roster.Add(new FootballPlayer{ Name="Player2",Number=1});
roster.Add(new FootballPlayer{ Name="Player3",Number=2});
var NewTeam = new FootballTeam<List<FootballPlayer>>(roster);
...테크놀로지에 종사하는 어느 누구도 축구팀에 선수가 필요없다고 말하지 마십시오. :)
언급URL : https://stackoverflow.com/questions/21692193/why-not-inherit-from-listt
'programing' 카테고리의 다른 글
| 명령줄 인수를 읽고 처리(파스)하려면 어떻게 해야 합니까? (0) | 2023.04.09 |
|---|---|
| VBA + Excel + Try Catch (0) | 2023.04.09 |
| SQL Server: 여러 행을 하나의 행으로 결합 (0) | 2023.04.09 |
| Swift에서 HTTP 요청을 하는 방법은 무엇입니까? (0) | 2023.04.09 |
| 경과시간 측정(Swift) (0) | 2023.04.09 |