피터지고 치열하게 삶을 유지하다  
Front Page
Notice | Keyword | Tag | Location | Guestbook | Admin | Write Article   
 
.Net Framework 1.1 에서 .Net Framework 2.0 으로의 Migration (CollectionBase 문제)

.Net Framework 1.1에서 .Net Framework 2.0 으로 이동시 경험한 실패 1

CollectionBase 문제 - 임시 해결책

namespace Netron.GraphLib
{
      /// <summary>
      /// Collection of shape objects
      /// </summary>
     [ClassInterface(ClassInterfaceType.AutoDual)]
     [Guid("8A34971D-6811-452e-809E-160E00E94EE9")]
     [Serializable] public class ShapeCollection : CollectionBase
     {
            #region Constructor
               public ShapeCollection()
               {
               }

               private ShapeCollection(ArrayList newarray)
               {
                     this.InnerList.Clear();
                     foreach( Shape sh in newarray)
                     {
                         Add(sh);
                     }
               }
            #endregion

            #region Methods
               public int GetCount()
               {
                     return this.InnerList.Count;
               }

               [ComVisible(false)]
               public object Clone()
               {
                     return new ShapeCollection(this.InnerList);
               }

               [ComVisible(false)]
               public int Add(Shape shape)
               {
                     return this.InnerList.Add(shape);
               }

               [ComVisible(false)]
               public Shape this[int index]
               {
                     get{
                            if(index>-1 && index<this.InnerList.Count)
                                    return this.InnerList[index] as Shape;
                             else
                                     return null;
                     }
               }

               [ComVisible(false)]
               public bool Contains(object shape)
               {
                     if(shape is Shape)
                            return this.InnerList.Contains(shape);
                     else
                            return false;
               }

               [ComVisible(false)]
               public void Remove(Shape shape)
               {
                     this.InnerList.Remove(shape);
               }
           #endregion
      }
}

위와 같은 Custom Collection 이 있다고 할때 .Net Framework 2.0에서 COM Interop에서 GetEnumerator()를
호출하여 IEnumVARIANT를 얻고, 안에 담고있는 Object 배열을 얻기위해의
Next(unsigned long celt, VARIANT FAR *rgVar, unsigned long FAR *pCeltFetched ) 메서드를 호출할 경우 Collection 에서 얻은 Count(celt)만큼 pCeltFetched에 리턴되나 rgVar 은 VT_EMPTY형으로
InvalidOperationException (0x80131509 ) 에러를 리턴함.

2.0 SDK 도움말을 보면 다음과 같은 말이 나와 있음

잘못된 인수 이외의 다른 이유로 메서드를 호출할 없는 경우 InvalidOperationException이 사용됩니다. 예를 들어, InvalidOperationException은 다음과 같은 경우에 throw됩니다.

열거자를 만든 후 컬렉션의 개체가 수정되는 경우 MoveNext 메서드에 의해 예외가 throw됩니다.

메서드를 호출하기 전에 리소스 집합이 닫히는 경우 GetString 메서드에 의해 예외가 throw됩니다.

잘못된 인수로 인해 메서드를 호출할 수 없는 경우 ArgumentException이 throw되거나 해당 파생 클래스인 ArgumentNullException 또는 ArgumentOutOfRangeException 중 하나가 대신 throw됩니다.

Ldflda MSIL(Microsoft Intermediate Language) 명령은 InvalidOperationException을 throw합니다.

InvalidOperationException은 0x80131509 값을 가지는 HRESULT COR_E_INVALIDOPERATION을 사용합니다.

InvalidOperationException 인스턴스의 초기 속성 값 목록에 대한 자세한 내용은 InvalidOperationException 생성자를 참조하십시오.

이 형식의 모든 public static(Visual Basic의 경우 Shared) 멤버는 스레드로부터 안전합니다. 인터페이스 멤버는 스레드로부터 안전하지 않습니다.

위의 내용대로 Next 호출시 컬렉션 개체가 수정되고 있는듯.

IEnumerable, IEnumerator 인터페이스를 상속받아 구현해주었으나 효과 없음.

IEnumerable의 메서드 GetEnumerator는 CollectionBase에 구현되어 있다.

CollectionBase와 IEnuerator을 상속받을 경우 GetEnumerator을 통해 ArrayList의 IEnumerator를 받으므로
ArrayList에 구현된 Reset, Current, MoveNext 가 호출되어 SapeCollection에 구현된 Reset, Current, MoveNext
가 무시된다.

자신만의 Custom Collection을 구현하기 위해서는 IEnumerable, IEnumerator를 상속받아 GetEnumerator,
Reset, Current, MoveNext를 정교하게 구현하여야 한다.

ShapeCollection의 경우 CollectionBase에서 제공하는 다른 Method들도 요구하므로 CollectionBase를
사용하여야 한다.

결론적으로 Next 호출시 내부적으로 MoveNext가 호출되고 이때 요소가 삭제, 추가등으로 변경되어 InvalidOperation Exception이 발생하는 것으로 생각된다. 2.0에서 왜 요소가 변경될까? 아마 CollectionBase
의 내부 구조가 변경된듯 하다.

2.0의 RegAsm.exe를 사용하여 tlb를 만들었으나 역시 상관없는둣.

1.1 도 되고 2.0, 기타 상위버전에서 확실해 돌아 갈 수 있는 해결책을 찾지못함

2.0 SDK를 사용할 수 있는 개발환경이라면(VS .NET 2005) Generic 사용을 적극 검토하라.!
1.1 이하에서 Custom Collection을 CollectionBase로 구현했다면 1.1 Runtime에서 동작하도록
강제하는 방법밖에 없는듯 하다.

크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기
Tag : , , ,
Track this back : http://www.codeforum.net/blog/pitoosung/trackback/2
Commented by at 2008/07/22 13:40  r x
저도 이문에제 봉착했네요..ㅠ_ㅠ
Generic으로 수정후 제가 리뷰하겠습니다.
Commented by at 2008/07/22 15:48  r x
Generic 코드는 COM으로 내보낼수 없다네요..
Shape를 가져오는게 아니라 필요한 Interface를 따로 구현해줘야 할것 같습니다.

name    password    homepage
 hidden


BLOG main image
피투성의 IT 분투기
 Notice
(2009.11.30) - ㅠ.ㅠ 안녕! 서버 H/W 시스템 교체(서버보드 사망, HP Workstation으로 교체)
(2008.2.2) IP : 195.225.178.29 - 스팸 차단 조치
(2008.1.14) 오후 06:34 ~ 08:07 : 시스템 복구
(2008.1.14) 오전 00:25(?) : 시스템 다운 - 흠 심각하군!
(2008.1.13) 오후 11:31 : 시스템 리부팅됨
(2008.1.13) 시스템 복구 : 오전(?)~오후 1:00
 Category
전체 (148)
프로그래밍 (42)
IT 세상속으로 (42)
세상 엿보기 (26)
지하창고 (18)
책의 향기 (12)
생각의 힘(바둑) (4)
OCR-내가 다 읽어줄께 (1)
두발의 짐승 (2)
지능형 로봇 (1)
 Calendar
«   2010/09   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
 Recent Entries
투명 Display 그리고 Augm... (2)
64bits(x64) Windows OS...
NFS & Eclipse & CDT & In...
행복에 대해 생각하며
Virtual Audio Cable (가...
 Recent Comments
^^ 안녕! 축하축하. 난 아...
피투성 - 03/16
오랜만에들림니다 아이폰...
쭌 - 03/15
Thanks for your kind tra...
hyungju - 2009
정보 감사합니다 덕분에...
허수 - 2009
관리자만 볼 수 있는 댓글...
- 2009
 Recent Trackbacks
내가 생각하는 한의학의...
Life Is Always Emergency
FreeBSD 6.2, 64bit, 메모...
엘레노아의 작업로그
알약 백신 제대로 사용하...
촌철살인
유용한 블로그 툴 몇개..
ENTClic@blog...just anot...
국내의 검색엔진에 등록하...
케이알선의 이야기
 Archive
2010/01
2009/12
2009/07
2008/09
2008/03
 Link Site
00_피투성의 지식창고_00
 Visitor Statistics
Total : 70561
Today : 55
Yesterday : 46
텍스트큐브 배너
Eolin
rss