잊지 않겠습니다.

1. Preview 3/4의 uninstall.

: global에 등록되어있는 System.Web.Routing, System.Web.Mvc, System.Web.Abstractions에 대한 완벽한 uninstall이 필요하다.

: 프로그램 추가/삭제에서의 제거 뿐 아닌, Registery에서  HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Assemblies\Global에서의 완벽 제거가 필요

  

2. Namespace의 이전

: Html.ActionLink<Controller>의 Namespace가 System.Web.Mvc에서 Microsoft.Web.Mvc로 이전

  

3. RenderUserControl의 제거

RenderPartial로 함수 이름 변경

: 전에는 string을 이용한 Html의 표현 방식이였으나, 이제는 함수 형태로 변경

  

4. web.config 수정

: 버젼 정보 0.0.0.0을 모두 3.5.0.0으로 변경 

Posted by Y2K
,

HTTP에서의 File upload

: form에서의 post 방식을 통한 File을 업로드시키게 된다.

   <form action="/home/uploadfiles" method="post" enctype="multipart/form-data">  
        <label for="file">Filename:</label>  
        <input type="file" name="file" id="file" />  
           <input type="submit" name="submit" value="Submit" />  
   </form>  

 

POST를 통해서 HTTP Header에 같이 넣어지는 데이터는 다음과 같다.

 

POST /home/uploadfiles HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------------7d81b516112482
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64)
Content-Length: 324

-----------------------------7d81b516112482
Content-Disposition: form-data; name="file"; filename="\\SERVER\Users\Scott\Documents\test.txt"
Content-Type: text/plain

foo
-----------------------------7d81b516112482
Content-Disposition: form-data; name="submit"

Submit
-----------------------------7d81b516112482--

 

POST를 통해서 이동되는 데이터에서는 하나 이상의 파일이 multipart/form-data를 통해서 얻어지는 것이 가능하게 된다. 또한 POST를 통해서 Header에 각각의 binary data가 저장되게 된다.

multipart/form-data를 통하지 않은 데이터는 다음과 같이 보여지게 된다.

POST /home/uploadfiles HTTP/1.1
Content-Type: application/x-www-form-urlencoded
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64)
Content-Length: 13

submit=Submit

 

차이가 확연히 보이는 것을 알수 있다. File의 업로드 시에 필요한 File의 데이터에 대한 정보는 존재하지 않고 있다.ASP.NET에서의 FileUpload control의 경우에도 역시 form에서의 multipart/form-data를 통해서 데이터를 전송시키고 있다.

 

이때에 Http-Header의 정보에 있는 데이터를 얻어오는 방법은 다음과 같다.

                HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;  
                if (hpf.ContentLength == 0)  
                    continue;  

                string savedFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.GetFileName(hpf.FileName));  
                hpf.SaveAs(savedFileName);

 

요청되어진 Request에서 Files property는 multipart/form-data에서 얻어진 파일 이름과 그에 따른 File 값들로 구성되어진다. HttpPostedFileBase로 데이터를 받아서 서버단이나 원하는 위치에 지정하게 되면 저장되게 된다.

 

이러한 방법은 ASP.NET 또는 MVC 모델에서 뿐 아니라, HTTP단에서 Post를 이용한 데이터의 전송시에 항시 사용되는 방법이 된다.


Posted by Y2K
,

오늘 회사에서 대성씨의 REST에 대한 소개와 REST URI에 대한 내용을 들으면서 전부터 posting 할려고 했던 내용을 Posting 해보자 싶었다. 

  

일단, ASP.NET MVC Framework와 동일하게 진행되었던 ASP .NET의 프로젝트중 하나가 ASP.NET에서의 RESTFUL 이용 방법이였고, 이러한 방법자체가 ASP .NET MVC Framework에 같이 통합이 되어있는 상태이다.

  

기본적으로 Route에 추가하는 RouteHandler에서 회사에서 사용되는 uri.py의 기능과 동일한 기능을 사용하게 된다.

예를 들어.. User/Details/456 이라는 sub-uri를 보게 되면, User-Detail-ID 의 형태를 가지고, User의 Detail한 상태를 알아 볼 수 있는 URI에서의 정보를 제공할 수 있게 된다.

  

MVC에서 RouteHandler가 움직이는 원리는 다음에 포스팅 하기로 하고... 일단은 ASP .NET에서 권장하는 기본적인 Controller의 Action method name, 즉 동작(Action)에 대한 기본 명명법은 다음과 같다.

Action

Sample URL

Description

Details

/Product/Details/5

Displays a single resource such as a database record. For example, displays a single Product with an Id of 5.

Index

/Product/Index

Displays a collection of resources. For example, displays all of the products in the products database table.

Create

/Product/Create

Displays a form for creating a new resource. For example, displays a form for creating a new product.

Insert

/Product/Insert

Inserts a new resource into the database. Typically, you redirect to another action after performing an Insert.

Edit

/Product/Edit/5

Displays a form for editing an existing resource. For example, displays a form for editing a product with an Id of 5.

Update

/Product/Update/5

Updates existing resources in the database. Typically, you redirect to another action after performing an Update.

Destroy

/Product/Destroy/5

Displays a page that confirms whether or not you want to delete a resource from the database.

Delete

/Product/Delete/5

Deletes a resource from the database. Typically, you redirect to another action after performing a Delete.

Login

/Home/Login

Displays a login form.

Logout

/Home/Logout

Logs out a user. Typically, you redirect to another action after performing a Logout.

Authenticate

/Home/Authenticate

Authenticates a user name and password. Typically, you redirect to another action after performing an Authenticate.

  

 여기에서 주목할 점이, Update와 Delete, Destroy이다. REST에서 권장하는 HttpMethod인 PUT과 DELETE를 사용하지 않는 이유는 기본적인 ASP.NET MVC Framework에서는 PUT과 DELETE를 사용하고 있지 않기 때문이다. 기본적인 설정에서 사용하고 있지 않는 설정을 권장사항에 넣기 힘들어서 아무래도 Update와 Delete가 따로 Action으로 분류를 시키고 있는 것 같다. 

  

기본적인 MapRoute 방법자체는 다음과 같다.

             routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );

 각각의 Route의 이름과 Controller, Action, 그리고 필요하다면 그에 따른 parameter의 이름을 이용한 MapRoute를 작성시키고 있다. 여기에서 {controller}의 이름은 RegularExpression을 지원하기 때문에, 기본적인 REST 서버들과 거의 유사하게 움직인다. (정확히는 모른다. --)

Posted by Y2K
,

ASP .NET MVC Framework에서는 URL에 대한 각각의 Controller를 기본적으로 다음과 같이 사용하고 있다.

 

            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );

 

여기에서, 각각의 Route는 기본적으로 Controller/Action/Parameters 형태로서 구성이 되지만, 다음과 같이 다른 형태의 Route역시 가능하다.

 

http://localhost/Product/Create/id          
  routes.MapRoute(
                "Product",                                              // Route name
                "Product/{action}/{id}",                           // URL with parameters
                new { controller = "ProductManager", action = "List", id = "" }  // Parameter defaults
            );


http://localhost/Product/id/Edit

routes.MapRoute(   
                 "ProductEdit",        // Route name  
                 "Product/{id}/Edit",  // URL with parameters     
                 new { controller = "ProductManager", action = "Edit", id = "" }  // Parameter defaults 
           );

 

Caution!!!

Route를 여러개 지정하는 경우에는 차례대로 먼저 알아보게 된다. 기본적인 Controller를 가장 최 상단으로 올리는 경우에 그 뒤에 나오는 모든 sub-url을 기본적으로 controller로 해석하려고 하기 때문에 무조건 에러가 발생하게 된다.

사용자 지정 URL을 넣어주는 경우에는 먼저, 사용자 URL을 먼저 넣어주고 그 후에 기본적으로 사용하는 Default Route를 넣어주는 것이 하나의 방법이 된다.

Posted by Y2K
,

Microsoft.ajax

.NET Framework 2009. 1. 7. 13:01

MS에서 ASP.NET에서 사용하기 쉽도록 만든 java script library. 

    

1. call local web service 

Sys.Net.WebServiceProxy.invoke("Service Address", "method name", "IsPost Action", "Parameters", "return action")

  1. function check_activateion_requested(user_id) {  
  2.     Sys.Net.WebServiceProxy.invoke(          
  3. "/SYNCmailUtil.asmx",        "IsActivationRequired",        false,        { userId: user_id },        inputbox_enable        )}    function inputbox_enable(enable) {    if (enable) {        document.getElementsByName('logonName')[0].readOnly = "false";        document.getElementsByName('password')[0].readOnly = "false";    }    else {        document.getElementsByName('logonName')[0].readOnly = "true";        document.getElementsByName('password')[0].readOnly = "true";        document.getElementsByName('logonName')[0].value = "";        document.getElementsByName('password')[0].value = "";        document.getElementById('infoLabel').innerHTML = "Activation을 할 수 없는 유저입니다.";    }}  

    

    

Posted by Y2K
,

JSON 형태의 데이터를 C# 형태로의 변환

  

java script에서나 Netscape 진형에서 주로 사용되는 JSON 데이터 형태를 C# class로 변환 및 이를 이용한 AJAX 개발이 가능하다.  

  

먼저, C# class의 선언

  1. public class Company  
  2.     {  
  3.         public string Name { getset; }  
  4.         public string Location { getset; }  
  5.         public string Subject { getset; }  
  6.     }  

  

여기서 간단히 3개의 Input box를 갖는 View Page의 생성

  1. <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="CompanyView.aspx.cs" Inherits="MvcJson.Views.Home.CompanyView" %>  
  2. <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">  
  3. Company Name : <%=Html.TextBox("CompanyName") %> <br />  
  4. Company Subject : <%=Html.TextBox("Subject") %> <br />  
  5. Company Location : <%=Html.TextBox("Location") %> <br />  
  6. <input type="button" id="sendCompanyData" value="Send Company Data" /><br />  
  7. <div id="resultArea"></div>  
  8. </asp:Content>  


HttpContext를 이용해서 json data를 HTTP-POST로 전달하는 javascript

(jQuery 이용.) 

  1. <script type="text/javascript" src="<%= Url.Content("~/Scripts/jquery-1.2.6.js") %>"></script>  
  2. <script type="text/javascript" src="<%= Url.Content("~/Scripts/jquery.toJSON.js") %>"></script>  
  3. <script type="text/javascript">  
  4.   $(function() {  
  5.     //sending json object to controller action:  
  6.     $("#sendCompanyData").click(function() {  
  7.       var company = {  
  8.         "Name": $("#CompanyName").val(),  
  9.         "Subject": $("#Subject").val(),  
  10.         "Location": $("#Location").val()  
  11.       };  
  12.   
  13.       var encoded = $.toJSON(company);  
  14.   
  15.       $.ajax({  
  16.         url: "/Home/ShowCompany",  
  17.         type: "POST",  
  18.         dataType: 'json',  
  19.         data: encoded,  
  20.         contentType: "application/json; charset=utf-8",  
  21.         beforeSend: function() { $("#saveStatus").html("Saving").show(); },  
  22.         success: function(result) {  
  23.           alert(result.Result);  
  24.           $("#saveStatus").html(result.Result).show();  
  25.         }  
  26.       });  
  27.     });  
  28.   });   
  29. </script>  

  

데이터를 받을 Controller 작성

  1. public ActionResult ShowCompany()  
  2.         {  
  3.             if(HttpContext.Request.ContentType.Contains("application/json"))  
  4.             {  
  5.                 string inputContent;  
  6.                 int dataLength = (int) HttpContext.Request.InputStream.Length;  
  7.                 byte[] btDatas = new byte[dataLength];  
  8.                 HttpContext.Request.InputStream.Read(btDatas, 0, dataLength);  
  9.   
  10.                 inputContent = System.Text.Encoding.UTF8.GetString(btDatas);  
  11.   
  12.                 var result = (Company) JavaScriptConvert.DeserializeObject(inputContent, typeof(Company));  
  13.   
  14.                 return Json(new { Result = string.Format("{0} : {1} : {2}", result.Name, result.Subject, result.Location) });  
  15.             }  
  16.             else  
  17.             {  
  18.                 return Json(new { Result = "This data is not json" });  
  19.             }  
  20.         }  

  

결론 : JSON -> C# class 변환은 매우 자유로운 편이다. 예시의 JSON이 있다면 C# class를 자동으로 작성해주는 간단한 script만 있으면 둘이 같이 사용하기가 매우 편할것 같다.

Posted by Y2K
,

web에서 인증을 도와주고, 인증을 이용한 ActionFilter를 제공한다. 

  

1. web.config의 설정

   <authentication mode="Forms">
      <forms loginUrl="~/NotLogOn" />
    </authentication>

authentication mode는 반드시 Forms로 해주고, authorize가 되어있지 않는 경우에 돌아갈 url을 설정한다.

  

2. Login 정보 입력

FormsAuthentication 을 이용해서 user정보를 저장하는 cookie 값을 이용한다.  

   public interface IFormsAuthentication
    {
        void SetAuthCookie(string userName, bool createPersistentCookie);
        void SignOut();
    }
    public class FormsAuthenticationWrapper : IFormsAuthentication
    {
        public void SetAuthCookie(string userName, bool createPersistentCookie)
        {
            FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
        }
        public void SignOut()
        {
            FormsAuthentication.SignOut();
        }
    } 

  

3. Login 정보 입력 부분 구현

       public ActionResult Logon(string userName, string password, string saveCookie)
        {
            if(Request.HttpMethod != "POST")
            {
                return Redirect("/Logon/Index");
            }
            HostwayMembership membership = new HostwayMembership();
            if( membership.ValidateUser(userName, password) )
            {
                FormsAuth.SetAuthCookie(userName, saveCookie == "on");
                csDB.CreateCSEvent(userName, com.hostway.lib.SYNCmail.Database.CSEventCase.CSUserLogin, userName,
                                   "Logon", "Logon user");
                csDB.OnSubmit();
                return Redirect("/Home/Index");
            }
            else
            {
                return Redirect("/Logon/Index");
            }
        }

  

4. 인증이 필요한 controller, 또는 action에 attribute 적용

   [Authorize(Order=0)][AuthActionFilter(Order=1)]
    public class UserController : SYNCmailController
    [Authorize]
    public ActionResult List(int? pageNumber, int? eventPageNumber)

  

controller에 적용되는 경우에는 모든 action에 일괄적으로 적용되게 된다. 

이때에, Order 순서를 정해서 적용될 ActionFilter의 순서를 결정할 수 있다.

  

또한, 아래와 같이 user 또는 , Role에 대해서도 역시 같은 적용이 가능하다.

[Authorize(Users="email@address.co.kr")] 
[Authorize(Roles="admin, friend")]

  

  

  

  

  

Posted by Y2K
,

Action Result

.NET Framework 2009. 1. 7. 13:00

Controller에서 View에게 명령을 넘겨주는 Action에 대한 결과값

 

Method

  • View : return ViewResult instance
    • View를 호출하는 경우에는 Controller가 동작하지 않는다. View()가 되는 순간에 View가 호출이 되고, 단지 보여지는 방법을 공유할때 사용된다.(url이 변경되지 않는다.)
  • Redirect : redirects to the specified URL. Returns a RedirectResult result
    • Controller가 실행되고, url이 변경되게 된다.
  • RedirectToAction : Accepts an action and redirects to another controller action. Returns aRedirectToRouteResult instance,
  • RedirectToRoute : Redirects to a ULR that is determined by the routing API. this method lets you specify a named route. Returns a RedirectToRouteResult instance.
  • Json : Return JsonResult instance.
  • Content : send text context to the response. Returns a ContentResult instance.

 

ActionResult Type

  • ViewResult : Renders the specified view to the response.
  • EmptyResult : Does nothing. return null instance.
  • RedirectResult : Performs an HTTP redirect to the specified URL.
    • - controller가 있는 경우 controller method가 실행되고, 그 결과가 리턴되게 된다.
  • RedirectToRouteResult : Given some routing values, uses the routing API to determine tue URL and then redirects to that URL
  • JsonResult : Serializes the specified ViewData object to JSON format
  • ContentResult : Writes the specified text context to the response.

 

Posted by Y2K
,

Action Filter

.NET Framework 2009. 1. 7. 12:59

OnActionExecuting

 : just before the action method is called.

OnActionExecuted

 : just after the action method is called.

OnResultExecuting

 : occurs just before the result is executed. : before view is rendered.

OnResultExecuted

 : occurs after the result is executed. : after the view is rendered.

 

 public class AuthActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpCookie idCookie = filterContext.HttpContext.Request.Cookies.Get("id");
        HttpCookie passwordCookie = filterContext.HttpContext.Request.Cookies.Get("password");

        if ( filterContext.HttpContext.Session[ "Auth" ] == null || ( bool )filterContext.HttpContext.Session[ "Auth" ] == false )
        {
            if ( idCookie != null && passwordCookie != null )
            {
                HostwayMembership membership = new HostwayMembership();
                if ( membership.ValidateUser(idCookie.Value, passwordCookie.Value) )
                {
                    filterContext.HttpContext.Session[ "Auth" ] = true;
                    string authUserName = membership.GetUserName(idCookie.Value, passwordCookie.Value);
                    filterContext.HttpContext.Session["UserName"] = authUserName;
                    using(SYNCmailCSDatabase csDB = new SYNCmailCSDatabase())
                    {
                        csDB.CreateCSEvent(authUserName, 
                            com.hostway.lib.SYNCmail.Database.CSEventCase.CSUserLogin, authUserName,
                            "Logon", "Logon user");
                    }
                }
            }
        }
        
        if ( filterContext.HttpContext.Session[ "Auth" ] == null || (bool) filterContext.HttpContext.Session[ "Auth" ] == false)
        {
            filterContext.Cancel = true;
            filterContext.HttpContext.Response.Redirect("~/Logon/Index");
        }
        else
        {
            string userName = (string) filterContext.HttpContext.Session[ "UserName" ];
            string actionMethodName = filterContext.ActionMethod.Name;
            
            using(SYNCmailCSDatabase csDB = new SYNCmailCSDatabase())
            {
                string comment = string.Format("{0} user action method : {1}", userName, actionMethodName);
                csDB.CreateCSEvent(userName, CSEventCase.EnterPage, actionMethodName, filterContext.HttpContext.User.Identity.Name, comment);
            }
            base.OnActionExecuting(filterContext);
        }
    }
}

 

 

 

 


Posted by Y2K
,
데이터 맴버 대신에 항상 Property를 이용하라
  1. public data member를 줄이고, 이를 확립시키기 위한 방법으로 property를 주로 이용하라.
  2. IL에서 접근하는 방식상 Property로 작성이 될때에, 코드의 호환성이 좀더 더 유지된다. 

  

const보다는 readonly가 더 좋다.
  •  compile type : runtype 상수 보다는 다소 빠르지만 유연성이 떨어진다.  (const)
    • 수행 성능이 매우 중요할 때 사용.
    • 상수의 값이 절대로 바뀌지 않을 때에 사용.
    • 내장 자료형태, enum, string에서만 사용 가능하다. [DateTime에서는 사용 불가능]
    • Program의 버젼등을 적어놓는데에는 반드시 const가 되어야지 된다.
  • runtype : 프로그램의 수행시에 평가 된다.(readonly) 
    • 수행 성능의 개선 효과가 크다.
    • 유연성이 증가 된다.
  • const형으로 정의된 public 상수에 대한 갱신은 매우 신중히 고려되어야지 된다. 
    • 값이 바뀌는 경우에는 반드시 전체 컴파일을 해주어야지 된다.

  

cast 보다는 is와 as가 좋다
  • 좀더 안정적인 방법이다.
  • 사용자가 정의한 형변환 연산자의 존재를 고려하지 않기 때문에 runtime의 수행성능 효율도 올라간다.
  • 형 변환시에 어떤 상태로 동작하게 되는지를 결정하고, 이를 판단 가능하다. 
    • 변환이 되지 않을 때에는 null의 반환으로 편하게 확인이 가능하다.
  • value 형태에서는 동작하지 않는다. 
  •  형변환는 가능한한 피하는 것이 좋다

  

#if 대신 Condition Attribute를 이용하라.
  • #if~#endif문은 정의된 내용을 기반으로 Program의 코드를 제어한다.  
    • 가독성이 떨어지는 단점이 있다.
  • [Condition("DEBUG")] : DEBUG가 정의가 된 상태에서만 compile이 되는 구문으로 만들어진다.  
    • 다수의 Condition이 결정되는 경우, or로 움직이게 된다.

  

항상 ToString()을 작성하라.
  • 객체의 표현 방법을 쉽게 출력 가능하다.
  • System.Object의 override 형태로서, 다양한 방법으로 작성이 가능하다.
  • .NET Framework에서는 항상 자신의 형태를 ToString()을 통해서 표현하게 된다.
  • IFormattable interface의 작성 규칙 
    • 일반적인 출력 형태를 위해 "G" 문자열을 지원해야지 된다.
    • 비어있는 문자열과 null을 고려해줘야지 된다.
    • "G" 문자열과 비어있는 문자열, null의 반환 값은 항시 동일해야지 된다. 
value 타잎과 reference 타잎을 구분하라
  • value type : 다형적이지 않기 때문에 application이 직접 다루는 값을 정의하는데 주로 사용된다. 
    • struct 타잎으로 구성된다.
    • 값을 저장하는 용도로만 제한하는 것이 좋다.
    • 모든 struct type을 seal 형태로만 사용하는 것을 고려할 것 
    • 저 수준의 자료 저장소로만 생각하자

  

  • reference type : 다형적이기 때문에 application의 동작을 정의하는 데에 주로 사용한다. 
    • class 타잎으로 구성된다.
    • 배열의 형태시에 메모리 할당에서 시간이 더 많은 공간을 조각내게 된다. 
    • 객체 공간 (heap)을 조각내게 되는데, 속도가 전체적으로 떨어지게 된다. 

  

  •  Value 타잎을 사용해야지 되는 경우 판단 (4개가 모두 OK가 나오는 경우에만 사용할것!!) 
    • 데이터를 저장하는데에만 이용되는가?
    • 모든 public interface가 내부적인 값을 획득하거나 수정하기 위해서만 사용되는가?
    • 상속될 가능성이 전혀 없는가?
    • 다형적으로 다루어져야 할 필요가 없는가?

  

Immutable atomic value 타잎으로 작성하라
  • 생성된 이후에는 마치 상수와 같이 변경될 수 없는 타잎이다.
  • 단일의 요소로 분리할 수 있는 부분은 구조체로 작성하는 것이 좋다.
  • 타잎에 아무런 의미없는 get/set property를 만들지 말자.

  

value 타잎을 사용할 땐 0이라는 값이 의미를 가질 수 있도록 하라
  • 기본적으로 .NET Framework는 value 타잎으로 만들 때에, 0로 값을 초기화 한다.  
  • [Flags] : Bit 연산이 가능하게 하는 Attribute 
    • 이 때에는 특히 0의 값의 연산이 되지 않을 때에는 사용에 문제가 생긴다.

  

ReferenceEquals(), static Equals(), instance Equals(), operator==의 상호 연관성을 이해하라.
  • public static bool ReferenceEquals(object left, object right) 
  • public static bool Equals(object left, object right)
  • public virtual bool Equals(object right)
  • public static bool operator==(Myclass left, Myclass right)
  • ReferenceEquals()  : 반드시 재정의 하면 안된다.
    • 두 개의 변수가 동일 객체를 참조하는 경우 true를 반환한다.
    • value 형태에서는 반드시 false를 반환한다.
  • static Object.Equals() : 반드시 재정의 하면 안된다. 
    • 타잎을 명확하게 알기 힘든 변수들 간에 비교를 수행
    • Reference 타잎에서는 ReferenceEquals()와 동일하다.
    • value 타잎에서는 주어진 변수의 타잎이 같고, 내용이 일치하는 경우에서만 true가 반환된다.
  • instance에서의 Object.Equals() : 재정의가 필요할 때도 있다. 
    • 동일성의 의미를 확인한다.
    • 절대로 예외를 발생해서는 안된다.
    • 반드시 this.GetType()에서 타잎을 획득해야지 된다.(상속 받은 내용의 경우 예상 외의 결과가 나타날 수 있다.)
    • value 형태에서는 반드시 재정의 되어야지 된다. 
    • reference 형태에서는 동작 방식에 따라 재정의가 수행되어야지 된다. 
  •  operator== 
    • value 형태에서는 반드시 재정의 되어야지 된다. 
    • reference 형태에서는 동작 방식에 따라 재정의가 수행되어야지 된다. 
    • instance에서의 Object.Equals()가 재정의되는 경우에만 반드시 재정의 되어야지 된다.

  

GetHashCode()의 함정에 유의하라
  • 단 한가지 경우에만 재정의 해야지 된다. 
  • Dictionary와 같이 Hash code를 기반으로 하는 key로 활용될 때 이외에는 절대 재정의 되어서는 안된다. 
  • 재정의 하는 경우 다음의 규칙을 반드시 지켜야지 된다. 
    • 객체가 동일한 경우, 같은 Hash code를 반환하도록 만들어야지 된다.
    • 인스턴스가 생성된 후에, 변경되지 않아야지 된다.  : Type내의 불변의 값을 이용해서 만들어준다.
    • integer 형태에서 표현되어야지 된다. 
  • System.Object.GetHashCode() : 인스턴스의 생성, 삭제시에 증가/감소로 값이 만들어진다. 

  

foreach 루프가 더 유용하다.
  • 모든 collection에서 최고의 순회 코드를 만들어 낼 수 있다.
  • Length property를 밖으로 꺼내는 것은 가장 느린 코드를 만들어낸다!! 
  • 안정적이다. 
    • 읽기 전용으로 동작한다.
    • 올바른 형변환을 나타낸다.
  • 다차원 배열일때도 더 확실하게 동작한다. [영상처리에는 영 안좋을것 같다. -_-]
Posted by Y2K
,