인터페이스 만 임베디드하는 객체를 포함하도록 List와 같은 제네릭 클래스에서 유형을 정의하는 방법이 있습니까? 아마도 클래스 유형 및 인터페이스 일 수 있습니다.하나의 목록에 여러 인터페이스가 포함됨 <T>
다음과 같은 방법으로 그것을 표현해야하는 경우List<myObjectBase, IDisposable, IClonable> myList;
인터페이스 만 임베디드하는 객체를 포함하도록 List와 같은 제네릭 클래스에서 유형을 정의하는 방법이 있습니까? 아마도 클래스 유형 및 인터페이스 일 수 있습니다.하나의 목록에 여러 인터페이스가 포함됨 <T>
다음과 같은 방법으로 그것을 표현해야하는 경우List<myObjectBase, IDisposable, IClonable> myList;
내가 제대로 이해 확실하지만,이 방법에 대해 안 :
class MyList<T> : List<T>
where T : myObjectBase, IDisposable, IClonable
{
}
이 방법을 수행 할 수 있습니다 기본 객체에서 파생 된 객체를 목록에 추가하고 해당 인터페이스를 구현합니다.
이것은 훌륭한 해결책입니다. 기록을 위해, 계급 상속은 실제로 메모리와 cpu가 현명하게 비용이 듭니까? 5 번 상속받은 클래스와 비교하여 하나의 상속받지 않은 클래스를 갖는 것이 얼마나 비쌉니까? 내가 이렇게 많은 것을 만들어야 만한다면 우아하지 않을 수 있습니다. 그래도 내 현재의 경우에는 훌륭합니다. – jsmars
@jsmars 충분히 신경 쓰지 않아도됩니다. 비용은 고정되어 있습니다. 상속 사슬의 길이는 중요하지 않습니다. .NET은 기본적으로 C++과 같은 방식으로 "vtable"을 사용합니다. [Wikipedia의이 기사] (http://en.wikipedia.org/wiki/Virtual_method_table)는 나쁘지 않습니다. –
해당 솔루션이 마음에 들지 않습니다. 파생 된 List
번호는 :
public class CommonStuff : MyObjectBase, IDisposable, IClonable {}
이 그럼 당신은 쓸 수 있습니다 :
List<CommonStuff> myList;
없음을 예를 들어
, 여러 일반 매개 변수는 지원되지 않습니다.
그다지 의미가 없습니다. ArrayList
과 같은 것을 통해 일반 List<T>
클래스를 사용하면 얻을 수있는 이점이 없습니다. 당신은 모든 유형 안전 혜택을 잃을 것입니다.
더 나은 옵션은 ... 당신이 원하는 모든 것들을 처리하는 복합 클래스를 생성하고 그 사용합니다 :
:public class CommonBase : MyBaseClass, ICloneable, IDisposable
{
}
를 그리고 있음을 사용하여 일반적인 매개 변수로
var newList = new List<CommonBase>();
.net에는 여러 제약 조건이있는 제네릭 형식의 매개 변수를 받아들이는 메서드를 사용할 수 있습니다. 목록 <T>이 IFoo와 IBar를 구현하는 객체 만 저장하도록 지정할 수 있다면 해당 목록의 항목을 IFoo와 IBar를 구현하는 유형이 필요한 루틴으로 전달할 수 있습니다. 그렇지 않으면 IFoo와 IBar에 공통 조상이 없으면 IFoo와 IBar를 구현하는 알 수없는 유형의 객체를 캐스팅 할 수있는 좋은 방법이 없습니다. 그런 식으로 전달 된 것을 요구하는 루틴으로 전달할 수 있습니다 IFoo와 IBar를 구현하는 개체. – supercat
ArrayList을 사용할 수 있으며이 목록에있는 개체의 유형을 확인할 수 있습니다. 더 편리 할 수도 있습니다.
if(list[i] is Type)
질문은 정적 유형 안전 검사를 * 늘리는 방법에 관한 것이고 정적 유형 안전 검사를 포기하는 것이 좋습니다. 이것은 제기 된 문제에 대한 해결책보다는 오히려 반대 방향으로 나아가는 단계처럼 보입니다. 또한 임의의 객체 목록을 원할 경우 ArrayList가 아닌 List
다음은 나를 위해 여러 인터페이스를 추가하는 가장 간단한 해결책입니다. 도움이 될 수 있습니다
목록 <ICommonInterface>으로 myList = 새로운 목록 <ICommonInterface>()
myFirstClass m1C = new myFirstClass();
mySecondClass m2C = new mySecondClass();
myList.Add(m1C);
myList.Add(m2C);
foreach (var item in myList)
{
item.Clone();
item.Dispose();
}
class myFirstClass : ICommonInterface
{
// implement interface methods
}
class mySecondClass : ICommonInterface
{
// implement interface methods
}
interface ICommonInterface : IDisposable, IClonable
{
}
interface IDisposable
{
void Dispose(){}
}
interface IClonable
{
void Clone(){}
}
한 가지 방법은 그 하나 명의 멤버, 자기 T >에서 인터페이스 ISelf <를 정의하는 것입니다, 간단하게이 "반환 "T로; 그런 다음 결합 될 수있는 모든 인터페이스에 대해 IWhatever와 ISelf를 모두 상속하는 T > 인 < 을 정의하십시오. <T>. 이 경우, IFoo <Whizbang> 및 IBar <Whizbang>를 구현하는 클래스 Whizbang 암시 ISelf <Whizbang>, IFoo < IBar <Whizbang> >, IBar < IFoo <Whizbang> >을 구현하는 것 등IFoo와 IBar를 모두 구현해야하는 루틴은 IFoo <IBar> 유형의 매개 변수를 사용할 수 있습니다. 해당 매개 변수는 IFoo를 구현합니다. 자체 속성은 IBar을 구현합니다. 이 패턴을 사용해 복수의 인터페이스를 구현하는 오브젝트는, 임의의 순서로리스트 된 인터페이스의 일부 또는 모든 것을 사용해, 지정된 서식의 상자로 된 인터페이스 타입에 캐스트 할 수 있습니다.
당신은 세 가지 유형의 옵션을 귀하의 목록에 저장할 수 있기를 원하십니까? (따라서 IDObject 또는 IClonable을 구현하는 클래스를 구현하는 클래스 인 myObjectBase를 채울 수 있습니다.) –