개발 이야기/Visual C#2009. 11. 14. 23:56

웹테스트에서 작성된 시나리오를 기준으로 웹부하테스트 진행해보겠습니다.

1. 부하테스트를 추가합니다.


2. 마법사에서 부하테스트를 설정한다.

마법사를 시작합니다.

부하값을 설정합니다.

테스트를 등록하고 비율을 설정합니다.

3. 테스트를 진행합니다.


4. 웹부하 테스트 결과값이 출력된다.


취합된 성능 카운터를 가지고 분석을 한다.
지금까지 보여드린것은 웹부하테스트를 하는 기본적인 기능입니다.
운영서버는 로컬테스트가 아닌 별도의 LoadAgent를 설치하여 서버셋팅 후 해당 테스트를 진행하게된다.
Posted by 사나에
개발 이야기/Visual C#2009. 11. 12. 00:13

Visual Studio Team System 2008 테스트 기능

1. 단위 테스트 : 매개변수를 전달하여 클래스의 메서드를 호출하고 리턴되는 값을 확인하여 테스팅을 한다.
2. 웹 테스트 : 웹 시나리오를 작성하는 것으로 특정 페이지에 요청된 세부 정보를 기록한다.
3. 부하 테스트 : 단위테스트, 웹테스트에 단위별로 부하를 주고 그때 성능을 취합한다.
그 외 제네릭 테스트, 수동 테스트, 순서가 지정된 테스트가 있다.

웹테스트

1. 신규프로젝트에서 테스트프로젝트를 선택한다.

2. 테스트프로젝트에서 항목을 추가한다.



3. 웹 테스트 레코더가 있는 IE창이 뜬다.


4. 레코딩이 완료되면 웹 시나리오가 작성된다.


5. 시나리오를 실행한다.


테스트를 실행하면 정상적으로 패스했는지 에러가 났는지 여부를 알수가 있다.
웹테스트에서는 요청한 페이지에 에러가 없는지 정상적인 루틴을 수행하는지를 확인 할 수가 있다.
다음 글에서 오늘 진행한 웹테스트 시나리오를 작성하였으니  부하테스트 방법을 알려드리겠습니다.

Posted by 사나에
개발 이야기/Visual C#2009. 8. 20. 10:34


어느날.. Visual studio 2008에서 프로젝트에 파일을 하나 추가하려는데
템플릿을 찾을 수 없다면서 이벤트로그를 확인하라는 메세지가 나왔다.
황당~~

이벤트로그를 보았더니 이렇게 나온다.

Visual studio 2008 명령 프롬프트에서 "devenv.exe /installvstemplates" 명령을 실행하였더니 템플릿이 갱신된다.

Posted by 사나에
개발 이야기/Visual C#2009. 4. 23. 13:46

IT능력나눔 프로그램, ‘테크매치(Tech Match)

사회공헌 프로그램에 ‘전략’과 ‘실용’을 얹다

“한국마이크로소프트의 사회공헌 활동에는 뭔가 특별한 것이 있다!”. 올해부터 시작한 탈북 청소년 정보화 지원활동을 비롯해서 어르신 정보화 교육 지원, 초•중•고 교육정보화 프로그램 'PiL(Partners In Learning)’, 수원의 경수실버 IT 봉사단 후원, 시민사회단체(NGO) 정보화 지원 등 지금까지 한국마이크로소프트가 펼쳐 온 사회공헌 활동들을 되짚어 보면 자연스레 떠오르는 몇 가지 공통 키워드가 있다. 첫 번째는 모든 활동의 중심에 마이크로소프트의 핵심 역량인 ‘IT’라는 기술이 자리잡고 있는 것이고, 두 번째는 특정한 시기의 현금지원 같은 ‘일회성 이벤트’가 눈에 띄지 않는다는 것이다. 이 두 가지 키워드를 다시 연결해보면 한국마이크로소프트의 사회공헌 활동의 기저에는 하나의 ‘전략’이 자리잡고 있음을 알 수 있다. 이는 바로 자사의 강점인 IT를 통해 수혜자들에게 ‘실질적’인 도움을 주는 이른바 ‘상생(相生)’ 전략이다.

지난 해 시작되어 올 해 조금씩 확산되고 있는 테크매치(Tech Match)는 한국마이크로소프트 사회공헌 활동의 핵심 전략이라 할 수 있는 ‘상생+전략+실용주의’를 고스란히 담아낸 대표적인 자원봉사 프로그램이다. 프로그램의 골자는 마이크로소프트 MVP(Most Valuable Professional, 마이크로소프트 기술 관련한 최고 전문가이면서 마이크로소프트 직원은 아니다)들을 IT 환경이 취약한 NGO와 연결하여 NGO의 IT 역량 향상에 기여하겠다는 것. 주목할 만한 것은 본 프로그램의 참여자들도, 수혜자들도 모두 만족할 수 있는 윈윈(win-win)의 효과를 거두고 있다는 것이다. 국내 최고의 소프트웨어 달인들이 참여해 펼치는 사회공헌 활동은 과연 어떤 모습일까? ‘커뮤니티에의 헌신’을 통해 최고 전문가로 성장해 온 MVP들의 ‘나눔본능’이 NGO 안에서는 과연 어떤 효과를 거두고 있을까?


MVP와 사회공헌 활동의 교집합 ‘나눔 정신

테크매치 프로그램의 선봉장 격인 JnC Company의 염기웅 대표는 Microsoft Office Access(이하 액세스) 분야에 있어 둘째가라면 서러워할 만한 ‘고수 중의 고수다’. 1998년 대학 졸업 후 싱가포르에 위치한 프랑스계 은행에 입사하면서 액세스를 배웠다는 그는, 액세스를 처음 공부하면서 겪었던 어려움을 다른 사람들이 피해갈 수 있도록 하기 위해 자발적으로 나서 커뮤니티 사이트(www.dbabc.com)를 개설했다. 이후 그는 시간과 노력을 아끼지 않고 방문자들의 질의에 대해 성의 있는 답변을 달기 시작했고, 현장감이 묻어난 수준 높은 강의 파일들을 속속 업데이트했다. 덕분에 염기웅 대표는 지난 2003년 마이크로소프트의 MVP 리스트에 당당히 이름을 올리며 액세스 분야의 스페셜리스트로 인정받았다.

“마이크로소프트 액세스가 무엇에 사용하는 프로그램인지 아십니까? 워드나 엑셀이라고 하면 모르는 사람은 거의 없으실 겁니다. 하지만 국내에서는 유독 액세스의 활용이 저조해 아직 액세스의 이름조차 모르는 분들이 많죠. 저도 입사 후 나름의 활용법을 익히기까지 엄청난 고생을 했습니다. 그러다 독감처럼 호된 시간이 지나가고 액세스가 뭔지 좀 알고 나니 불현듯 제가 먼저 경험들을 다른 사람들과 나눠야겠다는 생각이 들더군요. 바로 이것이 www.dbabc.com의 출발이었고, 마이크로소프트 MVP가 될 수 있었던 계기가 되어주었습니다”

커뮤니티 사이트 구성원 대다수가 ‘Read Only Man’, 이른바 ROM족인 상황에서 염기웅 대표 같은 커뮤니티 개설자•운영자들은 그야말로 보석과도 같은 존재다. 자발적으로 나서 자신의 노하우를 공유하고, 질의에 대한 문제 해결법을 제공하며, 장기적으로 우리 소프트웨어 기술 경쟁력 강화에 보탬이 되는 일들을 아무런 대가 없이 ‘나눔의 기쁨’ 하나로 수행하고 있기 때문이다. 이런 그가 올 해부터 테크매치 프로그램의 선봉장으로 나서며 NGO에 대한 IT 자원봉사에 나섰다. 정보 나눔에 이어, 사회봉사 활동으로까지 본격적으로 나선 그, 혹시 이타적인 유전자라도 갖고 있는 것이 아니냐는 질문에 황급히 손사래를 친다.

“테크매치에 참여하기 전까지 저는 사회공헌이나 기부, 나눔 등에 관해서는 거의 관심이 없었습니다. 연말 같은 때 정치가나 기업인, 연예인들이 하는 게 기부라고 생각했죠. 저처럼 생존을 걱정해야 하는 소규모 기업 사장으로서 사회봉사는 거리가 있어도 한참은 멀었었습니다(웃음). 로또에 당첨되거나 회사가 엄청난 성공을 거둔 다음 기부를 하는 상상이야 해봤지만 자원봉사라고는 평생 한번도 생각해 보지 못한 제가 이런 인터뷰까지 하게 됐으니 테크매치가 가진 매력이 어느 정도인지 짐작이 가실 겁니다”

건장한 체격에 무표정한 답변을 이어가던 그도 테크매치 이야기가 나오자 이내 눈가에 서글서글한 미소가 퍼진다. 그에게 미소를 전해 준 테크매치 프로그램의 출발은 지난 해 봄으로 거슬러 올라간다. 임직원들의 기부 프로그램인 ‘기빙매치’ 프로그램을 확장하기 위해 요셉의원을 방문한 한국마이크로소프트 사회공헌 담당자는 자원봉사자들과 인사를 나누던 중 소프트웨어를 제대로 활용하지 못해 후원금 지로 및 영수증 송부 업무에 많은 자원봉사자가 매달려 그것도 수기로 일일이 처리하는 비효율성을 주목했다. 한국마이크로소프트는 국내 최고의 IT 고수들인 MVP들에게 기술 지원 도움을 요청했고. 염기웅 대표와 오피스 튜터의 전경수 대표가 요셉의원을 함께 방문했다. 과연 MVP들의 방문 결과는 어떤 결과를 만들어 냈을까? 과장을 조금만 보태 말하자면 마치 마법과도 같은 일이 일어났다. MVP들이 불과 4시간의 시간을 들여 간단한 프로그래밍을 했을 뿐인데 같은 업무에 들여야 하는 96% 공수를 덜어내는 놀라운 성과를 거둬 올렸기 때문이다. 요셉의원에서 겪은 이런 짜릿한 경험은 염기웅 대표를 테크매치 프로그램의 전도사로 변화시키기에 충분했다.


“처음 자원봉사 얘기를 듣고는 요청한 분과의 관계도 있고, MVP를 통해 얻은 것들에 대한 고마움도 있고 해서 마지못해 수락은 했지만 그 땐 딱 한 번뿐이라는 생각이 있었습니다. 그런데 요셉의원에 한번 다녀온 후부터는 기부에 관해 갖고 있던 생각이 순식간에 변하더군요. 우리가 너무나 당연히 알고 있는 지식에 대한 말 한 마디가 이런 엄청난 효과를 볼 수 있다니! 내가 가진 기술이나 경험으로 누군가에게 도움을 줄 수 있다는 뭉클한 기쁨은 그 어떤 것과도 비교하기 어려운 감정이었습니다. 감동이라고까지 표현할 수 있을 것 같네요”

MVP에게는 어렵지 않은 일이었지만 요셉의원에게는 결정적인 도움이 된 이번 사례는 테크매치프로그램을 탄생시킨 직접적인 배경이 되었다. 이후 한국마이크로소프트는 IT 기술에 대해서 도움의 손길을 필요로 하는 NGO와 MVP들을 연결하여, MVP는 자원봉사의 보람과 기쁨을 느끼고 NGO는 IT 역량의 향상을 통해 사회 공익 활동을 보다 효과적으로 강화할 수 있도록 지원하는 ‘상생’과 ‘나눔’의 프로그램으로 정착시켜가고 있다. 또한 본 프로그램의 구심점이 되어 Tech Match를 진행해 가는데 있어서 MVP 들이 진단을 내린 NGO들이 필요로 하는 소프트웨어에 대해서 무상 기증하는 체계를 마련하고, MVP의 자원봉사에 대한 감사와 보상의 차원에서 법률.정책실에서는 변호사들이 무료 법률 상담 서비스를 제공하는 등 프로그램이 상생의 바탕 위에서 발전되어 나가도록 하고 있다.

MVP들의 신문화 코드로 업그레이드

자발적으로 나서 스스로 정보를 공유함으로써 커뮤니티 리더로 성장한 마이크로소프트의 MVP들은 MVP 가치와 정신을 ‘나눔’에서 찾을 수 있다고 입을 모은다. 이렇듯 나눔에 익숙한 그들이 테크매치라는 체계적인 프로그램을 만나면서 본격적인 ‘나눔 본능’을 발산하고 있다. 대표적인 활동 사례로 지난 4월 연세대학교 동문회관에서 개최된 ‘NGO Day'를 들 수 있다. 이날 행사장에는 약 300 여 명의 NGO 들이 운집했으며 마이크로소프트 MVP 8인이 전문 강사로 참여해, NGO 실무자들이 현업에서 바로 활용할 수 있는 IT 기술을 사례 중심으로 전달하기도 했다. 마이크로소프트는 NGO Day를 앞으로 매년 발전시켜 나갈 예정이다. 보다 기대되는 활동은 올 11월부터 시작될 예정이다. 염기웅 대표는 현장 방문을 통해 NGO들이 필요로 하는 IT 요구사항에 귀를 기울여 온 MVP들이 뭉쳐 벌써 두 달째 깜짝 프로젝트를 진행 중이라고 살짝 귀띔한다.

“테크매치 프로그램을 진행하다보니 NGO들이 가장 필요로 하는 것은 홈페이지였습니다. 대부분 관리 인력이 없어 어려움을 호소하더군요. 그래서 NGO 관리자들이 직접 페이지를 추가, 변경할 수 있는 홈페이지 제작 프로그램을 만들고 있습니다. 이지선, 김수영, 윤일진, 서동진, 장미연, 김시원씨등 모두 해당 커뮤니티에서 유명하신 분들이 나서 주셨죠. 지금까지 미처 테크매치 프로그램을 알지 못했다거나 쑥스러움에 참여를 망설이고 계신 MVP분들이 있다면 주저 없이 나눔의 기쁨에 동참해주시기 바랍니다. 연탄을 나르고, 아이들을 씻겨주는 봉사도 의미가 있지만 저희가 가진 IT 지식과 기술, 경험이 NGO들에게 어떤 도움이 되고 어떤 효과를 발휘하는지 경험해 보고 나면 분명 놀라실 겁니다”

염기웅 대표는 앞으로도 130인의 MVP 모두가 프로그램에 참여해 테크매치가 마이크로소프트 MVP들의 신문화 코드로 자리매김하기를 기대하고 있다. 지식 기부를 통한 정신적 기쁨과 보람을 맛보면서도 무료 법률 강좌와 상담까지 무료로 받을 수 있으니 ‘일석 이조’ 이상의 효과가 아니겠냐는 것이다. 마지막으로 테크매치 활동 외에 그가 요즘 관심을 두고 있는 활동들과 함께 앞으로의 계획을 물었다.

“테크매치를 통해 제 안의 나눔 에너지를 가득 충전한 것처럼 이제는 본업에 있어 제 성공에너지를 더욱 많이 충전해야 할 것 같습니다. 제가 대표로 있는 JnC Company가 이제 곧 팀데이터라는 이름으로 사명을 바꾸고 비즈니스 모델을 전환합니다. 저희가 가진 핵심역량을 살려 ‘데이터 가공’에 집중할 생각이죠. 요즘 전사 차원에서 BI(Business Intelligence) 구축이 활발한데 저희는 팀 규모의 BI를 실현해 드리는 회사라고 이해하시면 됩니다. ‘부서에서 필요한 데이터는 해당 부서에서 만들어야 한다’는 개념으로 액세스와 엑셀 등 마이크로소프트 오피스를 활용해 누구든 손쉽게 활용할 수 있는 BI를 구축하는 것이죠. 저렴한 비용으로 높은 사용자 만족을 이끌어낼 수 있었습니다. 업무 범위가 적어서인지 핀 포인트(pin point)에 집중할 수 있었던 것이 좋은 결과를 이끌어 낸 것 같습니다. 이 사업이 아주 재미있습니다. 보람도 있고요”


출처 : http://www.microsoft.com/korea/magazine/2008-winter/people/people.mspx

지쏘니 후기
작년 여름 TechMatch 이름으로 자원봉사를 시작하게 되었다.
다들 처음 만나서 처음 프로젝트를 같이 함에 있어 서툰부분이 없지않았지만 모두들 하고자하는 열정으로 하나하나 만들어 갈 수 있었다. 과정은 길고도 험난했지만 완성되어가는 사이트를 만날때 마다 그 기쁨은 이루 표현할 수 없는 감동이였다.
자원봉사 이름하에 모여 작년, 올해~ 그리고 계속적으로 고생해주시는 TechMatch 팀원들~~~ 같이 할 수 있어 행복했고 앞으로도 지속적으로 즐거운 마음으로 자원봉사를 같이 진행 할 수 있기를 바랍니다.^^

- 2009.04.23 -
Posted by 사나에
개발 이야기/Visual C#2009. 4. 17. 20:56

System.Data.Metadata.Edm 네임스페이스

System.Data.Metadata.Edm 네임스페이스에는 Entity Framework에서 사용하는 모델에 적용되는 개념을 나타내는 형식 집합과 응용 프로그램에서 메타데이터 작업을 수행하는 데 도움을 주는 클래스 집합이 포함됩니다.

==> GlobalItem 클래스 : 모든 EDM(EDM(Entity Data Model)) 형식과 엔터티 컨테이너의 기본 항목 클래스를 나타낸다.

using System;
using System.Data;
using System.Data.EntityClient;
using System.Data.Metadata.Edm;
using System.Collections.ObjectModel;

class BrowseTypes
{
  static void Main()
  {
    try
    {
      // Establish a connection to the underlying data provider by
      // using the connection string specified in the config file.
      using (EntityConnection connection =
         new EntityConnection("Name=AdventureWorksEntities"))
      {
         // Open the connection.
         connection.Open();
         // Access the metadata workspace.
         MetadataWorkspace workspace =
             connection.GetMetadataWorkspace();

         // Browse the metadata type hierarchy in the conceptual model.
         BrowseTypesExample(workspace, DataSpace.CSpace);

         // Browse the metadata type hierarchy in the storage model.
         BrowseTypesExample(workspace, DataSpace.SSpace);
      }
    }
    catch (MetadataException exceptionMetadata)
    {
      Console.WriteLine("MetadataException: {0}",
                      exceptionMetadata.Message);
    }
    catch (System.Data.MappingException exceptionMapping)
    {
      Console.WriteLine("MappingException: {0}",
                       exceptionMapping.Message);
    }
  }

  private static void BrowseTypesExample(MetadataWorkspace workspace,
    DataSpace model)
  {
    // Get a collection of the GlobalItems.
    // An GlobalItem class is the base class for
    // the entity data model types and entity containers.
    ReadOnlyCollection<GlobalItem> items =
         workspace.GetItems<GlobalItem>(model);

    // Iterate through the collection to get each item.
    foreach (GlobalItem item in items)
    {
       EntityContainer entityContainer = item as EntityContainer;
       if (entityContainer != null)
       {
         Console.WriteLine(
            "EntityContainer Name: {0}",
             entityContainer.Name);
                continue;
       }

       EntityType entityType = item as EntityType;
       if (entityType != null)
       {
          Console.WriteLine(
            "EntityType Name: {0}, Namespace: {1}",
             entityType.Name, entityType.NamespaceName);
          continue;
       }

       AssociationType associationType = item as AssociationType;
       if (associationType != null)
       {
          Console.WriteLine(
            "AssociationType Name: {0}, Namespace: {1}",
            associationType.Name, associationType.NamespaceName);
          continue;
        }

        PrimitiveType primType = item as PrimitiveType;
        if (primType != null)
        {
          Console.WriteLine(
            "PrimitiveType Name: {0}, Namespace: {1}",
            primType.Name, primType.NamespaceName);
            continue;
        }

        EdmFunction function = item as EdmFunction;
        if (function != null)
        {
          Console.WriteLine(
            "Function Name: {0}, Namespace: {1}",
            function.Name, function.NamespaceName);
          continue;
        }
      }
  }
}




참고 : http://msdn.microsoft.com/ko-kr/library/system.data.metadata.edm.globalitem.aspx


Posted by 사나에

☞ IDE(통합 개발 환경)


Visual Studio
에서는 Integrated Developement Environment(IDE), 통합 개발 환경을 제공합니다. IDE를 통해서 개발자는 개발 및 배포 등 개발 사이클 관리가 용이하게 된다.


Visual C#
제공되는 도구 목록

·         소스 코드를 작성하기 위한 코드 편집기

·         C# 소스 코드를 실행 가능한 프로그램으로 변환하기 위한 C# 컴파일러

·         프로그램을 테스트하기 위한 Visual Studio 디버거

·         마우스를 사용하여 사용자 인터페이스를 신속하게 개발하기 위한 도구 상자 디자이너

·         프로젝트 파일과 설정을 보고 관리하기 위한 솔루션 탐색기

·         컴파일러 옵션, 배포 경로, 리소스 등을 구성하기 위한 프로젝트 디자이너

·         파일이 아닌 형식에 따라 소스 코드를 탐색하기 위한 클래스

·         사용자 인터페이스의 컨트롤에 대한 속성과 이벤트를 구성하기 위한 속성

·         .NET Framework 어셈블리와 COM 개체를 포함하여 동적 링크 라이브러리에서 사용할 있는 메서드와 클래스를 보기 위한 개체 브라우저

·         로컬 컴퓨터와 인터넷에서 제품 설명서를 찾고 검색하기 위한 Document Explorer

 

IDE 사용자 지정


Visual C# 모든 창은 위치를 고정하거나 자유롭게 움직이도록 만들 있고, 표시하거나 숨기도록 지정할 있고 위치로 옮길 수도 있습니다. 창의 동작을 변경하려면 제목 표시줄에 있는 고정핀 모양의 아이콘이나 아래쪽 화살표를 클릭하고 사용 가능한 옵션 중에서 원하는 항목을 선택합니다. 도킹된 창을 새로운 도킹 위치로 옮기려면 놓기 아이콘이 나타날 때까지 제목 표시줄을 끌어 옮깁니다. 마우스 왼쪽 단추를 누른 마우스 포인터를 위치의 아이콘 위로 옮깁니다. 포인터를 왼쪽, 오른쪽, 위쪽 또는 아래쪽 아이콘 위에 놓으면 창이 지정된 쪽에 도킹됩니다. 포인터를 중간 아이콘 위에 놓으면 창이 창으로 바뀝니다. 포인터를 놓으면 파란색의 반투명 사각형이 나타납니다. 사각형은 위치에서 창이 도킹될 지점을 나타냅니다.

 

Posted by 사나에
개발 이야기/Visual C#2008. 12. 19. 23:50
출처 : http://code.msdn.microsoft.com/csharpfuture

C# 4.0이 나왔네요.



New features in C# 4.0

Mads Torgersen, C# Language PM

December 08

Contents

Introduction. 1

Dynamic Lookup. 3

Named and Optional Arguments. 6

Features for COM interop. 8

Variance. 9

Relationship with Visual Basic. 11

Resources. 11

 

Introduction

It is now close to a year since Microsoft Visual C# 3.0 shipped as part of Visual Studio 2008. In the VS Managed Languages team we are hard at work on creating the next version of the language (with the unsurprising working title of C# 4.0), and this document is a first public description of the planned language features as we currently see them.

Please be advised that all this is in early stages of production and is subject to change. Part of the reason for sharing our plans in public so early is precisely to get the kind of feedback that will cause us to improve the final product before it rolls out.

Simultaneously with the publication of this whitepaper, a first public CTP (community technology preview) of Visual Studio 2010 is going out as a Virtual PC image for everyone to try. Please use it to play and experiment with the features, and let us know of any thoughts you have. We ask for your understanding and patience working with very early bits, where especially new or newly implemented features do not have the quality or stability of a final product. The aim of the CTP is not to give you a productive work environment but to give you the best possible impression of what we are working on for the next release.

The CTP contains a number of walkthroughs, some of which highlight the new language features of C# 4.0. Those are excellent for getting a hands-on guided tour through the details of some common scenarios for the features. You may consider this whitepaper a companion document to these walkthroughs, complementing them with a focus on the overall language features and how they work, as opposed to the specifics of the concrete scenarios.

C# 4.0

The major theme for C# 4.0 is dynamic programming. Increasingly, objects are “dynamic” in the sense that their structure and behavior is not captured by a static type, or at least not one that the compiler knows about when compiling your program. Some examples include

a.       objects from dynamic programming languages, such as Python or Ruby

b.      COM objects accessed through IDispatch

c.       ordinary .NET types accessed through reflection

d.      objects with changing structure, such as HTML DOM objects

While C# remains a statically typed language, we aim to vastly improve the interaction with such objects.

A secondary theme is co-evolution with Visual Basic. Going forward we will aim to maintain the individual character of each language, but at the same time important new features should be introduced in both languages at the same time. They should be differentiated more by style and feel than by feature set.

The new features in C# 4.0 fall into four groups:

Dynamic lookup

Dynamic lookup allows you to write method, operator and indexer calls, property and field accesses, and even object invocations which bypass the C# static type checking and instead gets resolved at runtime.

Named and optional parameters

Parameters in C# can now be specified as optional by providing a default value for them in a member declaration. When the member is invoked, optional arguments can be omitted. Furthermore, any argument can be passed by parameter name instead of position.

COM specific interop features

Dynamic lookup as well as named and optional parameters both help making programming against COM less painful than today. On top of that, however, we are adding a number of other small features that further improve the interop experience.

Variance

It used to be that an IEnumerable<string> wasn’t an IEnumerable<object>. Now it is – C# embraces type safe “co-and contravariance” and common BCL types are updated to take advantage of that.

Dynamic Lookup

Dynamic lookup allows you a unified approach to invoking things dynamically. With dynamic lookup, when you have an object in your hand you do not need to worry about whether it comes from COM, IronPython, the HTML DOM or reflection; you just apply operations to it and leave it to the runtime to figure out what exactly those operations mean for that particular object.

This affords you enormous flexibility, and can greatly simplify your code, but it does come with a significant drawback: Static typing is not maintained for these operations. A dynamic object is assumed at compile time to support any operation, and only at runtime will you get an error if it wasn’t so. Oftentimes this will be no loss, because the object wouldn’t have a static type anyway, in other cases it is a tradeoff between brevity and safety. In order to facilitate this tradeoff, it is a design goal of C# to allow you to opt in or opt out of dynamic behavior on every single call.

The dynamic type

C# 4.0 introduces a new static type called dynamic. When you have an object of type dynamic you can “do things to it” that are resolved only at runtime:

dynamic d = GetDynamicObject(…);
d.M(7);

The C# compiler allows you to call a method with any name and any arguments on d because it is of type dynamic. At runtime the actual object that d refers to will be examined to determine what it means to “call M with an int” on it.

The type dynamic can be thought of as a special version of the type object, which signals that the object can be used dynamically. It is easy to opt in or out of dynamic behavior: any object can be implicitly converted to dynamic, “suspending belief” until runtime. Conversely, there is an “assignment conversion” from dynamic to any other type, which allows implicit conversion in assignment-like constructs:

dynamic d = 7; // implicit conversion
int i = d; // assignment conversion

Dynamic operations

Not only method calls, but also field and property accesses, indexer and operator calls and even delegate invocations can be dispatched dynamically:

dynamic d = GetDynamicObject(…);
d.M(7); // calling methods
d.f = d.P; // getting and settings fields and properties
d[“one”] = d[“two”]; // getting and setting thorugh indexers
int i = d + 3; // calling operators
string s = d(5,7); // invoking as a delegate

The role of the C# compiler here is simply to package up the necessary information about “what is being done to d”, so that the runtime can pick it up and determine what the exact meaning of it is given an actual object d. Think of it as deferring part of the compiler’s job to runtime.

The result of any dynamic operation is itself of type dynamic.

Runtime lookup

At runtime a dynamic operation is dispatched according to the nature of its target object d:

COM objects

If d is a COM object, the operation is dispatched dynamically through COM IDispatch. This allows calling to COM types that don’t have a Primary Interop Assembly (PIA), and relying on COM features that don’t have a counterpart in C#, such as indexed properties and default properties.

Dynamic objects

If d implements the interface IDynamicObject d itself is asked to perform the operation. Thus by implementing IDynamicObject a type can completely redefine the meaning of dynamic operations. This is used intensively by dynamic languages such as IronPython and IronRuby to implement their own dynamic object models. It will also be used by APIs, e.g. by the HTML DOM to allow direct access to the object’s properties using property syntax.

Plain objects

Otherwise d is a standard .NET object, and the operation will be dispatched using reflection on its type and a C# “runtime binder” which implements C#’s lookup and overload resolution semantics at runtime. This is essentially a part of the C# compiler running as a runtime component to “finish the work” on dynamic operations that was deferred by the static compiler.

Example

Assume the following code:

dynamic d1 = new Foo();
dynamic d2 = new Bar();
string s;

d1.M(s, d2, 3, null);

Because the receiver of the call to M is dynamic, the C# compiler does not try to resolve the meaning of the call. Instead it stashes away information for the runtime about the call. This information (often referred to as the “payload”) is essentially equivalent to:

“Perform an instance method call of M with the following arguments:

1.       a string

2.       a dynamic

3.       a literal int 3

4.       a literal object null

At runtime, assume that the actual type Foo of d1 is not a COM type and does not implement IDynamicObject. In this case the C# runtime binder picks up to finish the overload resolution job based on runtime type information, proceeding as follows:

1.       Reflection is used to obtain the actual runtime types of the two objects, d1 and d2, that did not have a static type (or rather had the static type dynamic). The result is Foo for d1 and Bar for d2.

2.       Method lookup and overload resolution is performed on the type Foo with the call M(string,Bar,3,null) using ordinary C# semantics.

3.       If the method is found it is invoked; otherwise a runtime exception is thrown.

Overload resolution with dynamic arguments

Even if the receiver of a method call is of a static type, overload resolution can still happen at runtime. This can happen if one or more of the arguments have the type dynamic:

Foo foo = new Foo();
dynamic d = new Bar();

var result = foo.M(d);

The C# runtime binder will choose between the statically known overloads of M on Foo, based on the runtime type of d, namely Bar. The result is again of type dynamic.

The Dynamic Language Runtime

An important component in the underlying implementation of dynamic lookup is the Dynamic Language Runtime (DLR), which is a new API in .NET 4.0.

The DLR provides most of the infrastructure behind not only C# dynamic lookup but also the implementation of several dynamic programming languages on .NET, such as IronPython and IronRuby. Through this common infrastructure a high degree of interoperability is ensured, but just as importantly the DLR provides excellent caching mechanisms which serve to greatly enhance the efficiency of runtime dispatch.

To the user of dynamic lookup in C#, the DLR is invisible except for the improved efficiency. However, if you want to implement your own dynamically dispatched objects, the IDynamicObject interface allows you to interoperate with the DLR and plug in your own behavior. This is a rather advanced task, which requires you to understand a good deal more about the inner workings of the DLR. For API writers, however, it can definitely be worth the trouble in order to vastly improve the usability of e.g. a library representing an inherently dynamic domain.

Open issues

There are a few limitations and things that might work differently than you would expect.

·         The DLR allows objects to be created from objects that represent classes. However, the current implementation of C# doesn’t have syntax to support this.

·         Dynamic lookup will not be able to find extension methods. Whether extension methods apply or not depends on the static context of the call (i.e. which using clauses occur), and this context information is not currently kept as part of the payload.

·         Anonymous functions (i.e. lambda expressions) cannot appear as arguments to a dynamic method call. The compiler cannot bind (i.e. “understand”) an anonymous function without knowing what type it is converted to.

One consequence of these limitations is that you cannot easily use LINQ queries over dynamic objects:

dynamic collection = …;

var result = collection.Select(e => e + 5);

If the Select method is an extension method, dynamic lookup will not find it. Even if it is an instance method, the above does not compile, because a lambda expression cannot be passed as an argument to a dynamic operation.

There are no plans to address these limitations in C# 4.0.

Named and Optional Arguments

Named and optional parameters are really two distinct features, but are often useful together. Optional parameters allow you to omit arguments to member invocations, whereas named arguments is a way to provide an argument using the name of the corresponding parameter instead of relying on its position in the parameter list.

Some APIs, most notably COM interfaces such as the Office automation APIs, are written specifically with named and optional parameters in mind. Up until now it has been very painful to call into these APIs from C#, with sometimes as many as thirty arguments having to be explicitly passed, most of which have reasonable default values and could be omitted.

Even in APIs for .NET however you sometimes find yourself compelled to write many overloads of a method with different combinations of parameters, in order to provide maximum usability to the callers. Optional parameters are a useful alternative for these situations.

Optional parameters

A parameter is declared optional simply by providing a default value for it:

public void M(int x, int y = 5, int z = 7);

Here y and z are optional parameters and can be omitted in calls:

M(1, 2, 3); // ordinary call of M
M(1, 2); // omitting z – equivalent to M(1, 2, 7)
M(1); // omitting both y and z – equivalent to M(1, 5, 7)

Named and optional arguments

C# 4.0 does not permit you to omit arguments between commas as in M(1,,3). This could lead to highly unreadable comma-counting code. Instead any argument can be passed by name. Thus if you want to omit only y from a call of M you can write:

M(1, z: 3); // passing z by name

or

M(x: 1, z: 3); // passing both x and z by name

or even

M(z: 3, x: 1); // reversing the order of arguments

All forms are equivalent, except that arguments are always evaluated in the order they appear, so in the last example the 3 is evaluated before the 1.

Optional and named arguments can be used not only with methods but also with indexers and constructors.

Overload resolution

Named and optional arguments affect overload resolution, but the changes are relatively simple:

A signature is applicable if all its parameters are either optional or have exactly one corresponding argument (by name or position) in the call which is convertible to the parameter type.

Betterness rules on conversions are only applied for arguments that are explicitly given – omitted optional arguments are ignored for betterness purposes.

If two signatures are equally good, one that does not omit optional parameters is preferred.

M(string s, int i = 1);
M(object o);
M(int i, string s = “Hello”);
M(int i);

M(5);

Given these overloads, we can see the working of the rules above. M(string,int) is not applicable because 5 doesn’t convert to string. M(int,string) is applicable because its second parameter is optional, and so, obviously are M(object) and M(int).

M(int,string) and M(int) are both better than M(object) because the conversion from 5 to int is better than the conversion from 5 to object.

Finally M(int) is better than M(int,string) because no optional arguments are omitted.

Thus the method that gets called is M(int).

Features for COM interop

Dynamic lookup as well as named and optional parameters greatly improve the experience of interoperating with COM APIs such as the Office Automation APIs. In order to remove even more of the speed bumps, a couple of small COM-specific features are also added to C# 4.0.

Dynamic import

Many COM methods accept and return variant types, which are represented in the PIAs as object. In the vast majority of cases, a programmer calling these methods already knows the static type of a returned object from context, but explicitly has to perform a cast on the returned value to make use of that knowledge. These casts are so common that they constitute a major nuisance.

In order to facilitate a smoother experience, you can now choose to import these COM APIs in such a way that variants are instead represented using the type dynamic. In other words, from your point of view, COM signatures now have occurrences of dynamic instead of object in them.

This means that you can easily access members directly off a returned object, or you can assign it to a strongly typed local variable without having to cast. To illustrate, you can now say

excel.Cells[1, 1].Value = "Hello";

instead of

((Excel.Range)excel.Cells[1, 1]).Value2 = "Hello";

and

Excel.Range range = excel.Cells[1, 1];

instead of

Excel.Range range = (Excel.Range)excel.Cells[1, 1];

Compiling without PIAs

Primary Interop Assemblies are large .NET assemblies generated from COM interfaces to facilitate strongly typed interoperability. They provide great support at design time, where your experience of the interop is as good as if the types where really defined in .NET. However, at runtime these large assemblies can easily bloat your program, and also cause versioning issues because they are distributed independently of your application.

The no-PIA feature allows you to continue to use PIAs at design time without having them around at runtime. Instead, the C# compiler will bake the small part of the PIA that a program actually uses directly into its assembly. At runtime the PIA does not have to be loaded.

Omitting ref

Because of a different programming model, many COM APIs contain a lot of reference parameters. Contrary to refs in C#, these are typically not meant to mutate a passed-in argument for the subsequent benefit of the caller, but are simply another way of passing value parameters.

It therefore seems unreasonable that a C# programmer should have to create temporary variables for all such ref parameters and pass these by reference. Instead, specifically for COM methods, the C# compiler will allow you to pass arguments by value to such a method, and will automatically generate temporary variables to hold the passed-in values, subsequently discarding these when the call returns. In this way the caller sees value semantics, and will not experience any side effects, but the called method still gets a reference.

Open issues

A few COM interface features still are not surfaced in C#. Most notably these include indexed properties and default properties. As mentioned above these will be respected if you access COM dynamically, but statically typed C# code will still not recognize them.

There are currently no plans to address these remaining speed bumps in C# 4.0.

Variance

An aspect of generics that often comes across as surprising is that the following is illegal:

IList<string> strings = new List<string>();
IList<object> objects = strings;

The second assignment is disallowed because strings does not have the same element type as objects. There is a perfectly good reason for this. If it were allowed you could write:

objects[0] = 5;
string s = strings[0];

Allowing an int to be inserted into a list of strings and subsequently extracted as a string. This would be a breach of type safety.

However, there are certain interfaces where the above cannot occur, notably where there is no way to insert an object into the collection. Such an interface is IEnumerable<T>. If instead you say:

IEnumerable<object> objects = strings;

There is no way we can put the wrong kind of thing into strings through objects, because objects doesn’t have a method that takes an element in. Variance is about allowing assignments such as this in cases where it is safe. The result is that a lot of situations that were previously surprising now just work.

Covariance

In .NET 4.0 the IEnumerable<T> interface will be declared in the following way:

public interface IEnumerable<out T> : IEnumerable
{
             IEnumerator<T> GetEnumerator();
}

public interface IEnumerator<out T> : IEnumerator
{
             bool MoveNext();
             T Current { get; }
}

The “out” in these declarations signifies that the T can only occur in output position in the interface – the compiler will complain otherwise. In return for this restriction, the interface becomes “covariant” in T, which means that an IEnumerable<A> is considered an IEnumerable<B> if A has a reference conversion to B.

As a result, any sequence of strings is also e.g. a sequence of objects.

This is useful e.g. in many LINQ methods. Using the declarations above:

var result = strings.Union(objects); // succeeds with an IEnumerable<object>

This would previously have been disallowed, and you would have had to to some cumbersome wrapping to get the two sequences to have the same element type.

Contravariance

Type parameters can also have an “in” modifier, restricting them to occur only in input positions. An example is IComparer<T>:

public interface IComparer<in T>
{
             public int Compare(T left, T right);
}

The somewhat baffling result is that an IComparer<object> can in fact be considered an IComparer<string>! It makes sense when you think about it: If a comparer can compare any two objects, it can certainly also compare two strings. This property is referred to as contravariance.

A generic type can have both in and out modifiers on its type parameters, as is the case with the Func<…> delegate types:

public delegate TResult Func<in TArg, out TResult>(TArg arg);

Obviously the argument only ever comes in, and the result only ever comes out. Therefore a Func<object,string> can in fact be used as a Func<string,object>.

Limitations

Variant type parameters can only be declared on interfaces and delegate types, due to a restriction in the CLR. Variance only applies when there is a reference conversion between the type arguments. For instance, an IEnumerable<int> is not an IEnumerable<object> because the conversion from int to object is a boxing conversion, not a reference conversion.

Also please note that the CTP does not contain the new versions of the .NET types mentioned above. In order to experiment with variance you have to declare your own variant interfaces and delegate types.

COM Example

Here is a larger Office automation example that shows many of the new C# features in action.

using System;
using System.Diagnostics;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

class Program
{
    static void Main(string[] args) {
        var excel = new Excel.Application();
        excel.Visible = true;

        excel.Workbooks.Add();                    // optional arguments omitted

        excel.Cells[1, 1].Value = "Process Name"; // no casts; Value dynamically 
        excel.Cells[1, 2].Value = "Memory Usage"; // accessed

        var processes = Process.GetProcesses()
            .OrderByDescending(p =&gt; p.WorkingSet)
            .Take(10);

        int i = 2;
        foreach (var p in processes) {
            excel.Cells[i, 1].Value = p.ProcessName; // no casts
            excel.Cells[i, 2].Value = p.WorkingSet;  // no casts
            i++;
        }

        Excel.Range range = excel.Cells[1, 1];       // no casts

        Excel.Chart chart = excel.ActiveWorkbook.Charts.
            Add(After: excel.ActiveSheet);         // named and optional arguments

        chart.ChartWizard(
            Source: range.CurrentRegion,
            Title: "Memory Usage in " + Environment.MachineName); //named+optional

        chart.ChartStyle = 45;

        chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
            Excel.XlCopyPictureFormat.xlBitmap,
            Excel.XlPictureAppearance.xlScreen);

        var word = new Word.Application();
        word.Visible = true;

        word.Documents.Add();          // optional arguments

        word.Selection.Paste();
    }
}

The code is much more terse and readable than the C# 3.0 counterpart.

Note especially how the Value property is accessed dynamically. This is actually an indexed property, i.e. a property that takes an argument; something which C# does not understand. However the argument is optional. Since the access is dynamic, it goes through the runtime COM binder which knows to substitute the default value and call the indexed property. Thus, dynamic COM allows you to avoid accesses to the puzzling Value2 property of Excel ranges.

Relationship with Visual Basic

A number of the features introduced to C# 4.0 already exist or will be introduced in some form or other in Visual Basic:

·         Late binding in VB is similar in many ways to dynamic lookup in C#, and can be expected to make more use of the DLR in the future, leading to further parity with C#.

·         Named and optional arguments have been part of Visual Basic for a long time, and the C# version of the feature is explicitly engineered with maximal VB interoperability in mind.

·         NoPIA and variance are both being introduced to VB and C# at the same time.

VB in turn is adding a number of features that have hitherto been a mainstay of C#. As a result future versions of C# and VB will have much better feature parity, for the benefit of everyone.

Resources

All available resources concerning C# 4.0 can be accessed through the C# Dev Center at www.csharp.net. Specifically, this white paper and other resources can be found at the Code Gallery site code.msdn.com/csharpfuture. Enjoy!

Posted by 사나에
개발 이야기/Visual C#2008. 12. 19. 23:42
Get Microsoft Silverlight 

Visual Studio 2010 CTP && .Net Framework 4.0

URL's referenced in this episode:
http://tinyurl.com/GetCTP
http://tinyurl.com/VSFeedback
http://tinyurl.com/CTPActivation

For more 10-4 episodes, be sure to visit:
http://channel9.msdn.com/Shows/10-4/

Virtual PC 2007로 제공되네요.
OS : Windows Server 2008


출처  : 10-4 Episode 1: Working with the Visual Studio 2010 CTP VPC
Posted by 사나에
개발 이야기/Visual C#2008. 11. 25. 08:48

요즘 저는 우리 제품의 코드 리뷰를 하고 있고 거기서 성능 이슈를 야기하는 문제점 몇 가지를 발견하였습니다. 그래서 코딩 표준화로 시스템의 성능을 형상시키는 방법을 공유하고 싶습니다.

 

1. String vs StringBuilder 

요즘 String은 개발자에게 일반적인 타입이 되었고 이것은 문자의 수를 표현합니다. 사실, String은 문자의 배열입니다.

 

String은 많은 개발자들이 다음과 같이 사용합니다.

 

String output = "";

output += "Hello";

output += " ";

output += "World";

 

System.Diagnostics.Debug.WriteLine(output);

 

 

output+=“xx" 을 호출했을 때 백엔드에서 어떻게 실행될까요? 실행해 봅시다.

 

Char[] tempValue = new Char[output.Length + "Hello".Length];

tempValue = output + "Hello";

Array.Clear(output, 0, output.Length);

output = null;

output = new Char[tempValue.Length];

output = tempValue;

Array.Clear(tempValue);

 

 

위 코드 처럼 Char 배열을 길이를 설정하고 문자열을 넣고 그 전의 문자열을 지우게 됩니다. 이런 작업을 문자열 연산이 있을 때 마다 진행합니다. 그러므로 문자열 연산이 자주 일어날 시에는 += 방법은 추천하지 않습니다.

 

StringBuilder는 동적 배열로 런타임에서 메모리에 할당됩니다. 여러분이 문자를 끝에서 추가 할 때 그 추가한 변수 값은 메모리에 할당되어서 문자열을 출력할 때 병합됩니다. 컴파일러는 StringBuilder를 제공하며, 이는 Append 메서드를 통한 변경은 지원합니다.

 

 

2. 문자열 추가

 String = “xxx” + yyy + “ “ + zzz

때때로 당신은 상기와 같은 형식으로 문자열이 필요합니다.

이 아티클을 읽은 후에는 다음과 같은 문자열 포맷을 이용하기를 바랍니다.

String.Format("xxx{0} {1}", yyy, zzz);

 

String.Format는 문자열을 포맷하는데 도움이 됩니다.

하지만 여러분이 다른 문자열 변수에 어떤 문자열을 추가하기를 원한다면 String.Format보다 String.Concat을 사용하는 게 성능상 효율적입니다.

String.Concat("xxx ", yyy, zzz); 

 

3. String.Equals vs String == CompareValue 

당신이 두 문자열을 비교할 경우, 정상적으로 당신은 String == CompareValue을 사용할 것입니다. 그러나 어떤 경우에는 원래의 문자열 비교 값과 같지 않는 경우가 있을 것입니다.( 대소문자를 구분하기때문에..) 
그래서 이런 경우는 저는 다음과 같이 사용했습니다.
 

String source = "abcdef";

String compareValue = "Abcdef";

if (source.ToLower() == compareValue.ToLower())

{

    //Do something

}

 

 

ToLower() or ToUpper() 둘 다 좋은 방법이긴 하지만 이는 가상 변수를 만드는 것으로 ToLower()를 호출 시에 다른 가상의 변수를 만들고 비교 값을 저장하게 됩니다. 비교하고 다시 그 가상변수를 없애는 작업을 하게 됩니다.

 

그러므로 개인적으로 다음 방법을 추천합니다.

이는 Object를 비교하는 방법으로 당신의 코드를 업데이트 시킬 수 있습니다. 

if (source.Equals(compareValue, StringComparison.OrdinalIgnoreCase))

  

4. String != null && String != “”  

내가 보는 것 중에 또 다른 것은 문자열을 확인하는 것입니다.

String source = "";

if  ((source != null) && (String != ""))

{

    //Do something

}

 

이는 다음과 같이 String.IsNullOrEmpty()을 사용할 수 있습니다.

if (String.IsNullOrEmpty(source))

{

    //Do something

}

 

StringBuilder에서 MaxCapacity속성을 통해 더 빠른 성능을 나타낼 수 있습니다. (MaxCapacity보유할 수 있는 최대 문자 수를 지정하는 것입니다.)

 

다음에는 배열(Array)에 대해 알아보겠습니다.

읽어 주셔서 감사합니다.

 
===============================================================================================
출처 : http://www.hoons.kr/Board.aspx?Name=cshaptip&Mode=2&BoardIdx=17164&Key=&Value=

Posted by 사나에

 ds = OUTPUT.DataSet.Copy();

            string strValue = string.Empty;
            string strText = string.Empty;

            SortedList sl = new SortedList();

            int iTBRowsCount = ds.Tables[0].Rows.Count;

            for (int i = 0; i < iTBRowsCount; i++)
            {
                strValue = ds.Tables[0].Rows[i]["YEAR"].ToString() + ds.Tables[0].Rows[i]["MONTH"].ToString().PadLeft(2, '0');
                strText = string.Format("- {0}년 {1}월호 -", ds.Tables[0].Rows[i]["YEAR"].ToString(), ds.Tables[0].Rows[i]["MONTH"].ToString().PadLeft(2, '0'));

                sl.Add(strValue.ToString(), strText.ToString());
            }

            for (int i = 0; i < iTBRowsCount; i++)
            {
                AKLDrop_Month.Items.Insert(i, new ListItem(sl.GetByIndex(iTBRowsCount - i - 1).ToString(), sl.GetKey(iTBRowsCount - i - 1).ToString()));
            }

            // 선택한 값을 설정해준다.
            AKLDrop_Month.SelectedValue = sYear + sMonth;

Posted by 사나에