(잡담) C# 업데이트에 바라는 것

C계열언어의 불편함과 var의 편리함과 과용으로 코드를 읽기 힘듭니다.

저는 코딩을 강타입 언어로 시작했습니다. (C, Obj-C, swift)
var를 처음본게 자바스크립트 였던거 같아요.

C#도 강타입인데 var가 있더라고요.
유니티 코딩할때는 var를 거의 안썼습니다. 그런데 웹개발 강의,코드, 예제에서 이 var를 참 많이 씁니다.
남들하는데로 따라쓰다보니 잘 모르는 코드도 그냥 var쓰면 되니까 무슨타입으로 선언해야하지? 고민이 사라져 좋더라고요.

var는 타입이 명시안되니까 IDE에서 살펴보지 않으면 결론적으로 이 변수에 뭐가 들어오는지 텍스트만으로 알수가 없을때가 많습니다.

뭔가 새로운거 배울 때, 모르는 예제 가져다 쓸 때 var를 타입이름으로 바꾸곤합니다.
타입을 명시하면 눈으로만 따라가도 딱딱 알아볼수 있으니까요.

그런데 제가 C계열 언어 마음에 안드는 점이 반환타입이 앞에 온다는 건데요.
이게 변수찾기가 안좋습니다. 타입이름이 먼저오다보니 글자수도 다르고 줄이 안 맞으니까요.

swift는 반환타임이 이름 뒤쪽에 오거든요. 앞에 예약어들이 붙을지언정 말이죠.

swift 사용할때는 당시 뭐 초보라서 객체지향 잘 몰랐고 C#에서 하듯이 접근제한자로 캡슐화 이런거 안했다보니 더 간결하게 썼죠.

지금은 캡슐화도 지켜가면서 하는데 C#은 예약어 키워드 덕지덕지 붙다 보면 가독성이 많이 떨어지더라고요.

변수 선언에 var를 쓰면 줄이 딱딱 맞아서 찾기가 쉬워요. 하지만 메서드는 그 조차도 안됩니다. 항상 이름앞에 타입이 길어지죠 특히 제네릭.

MS가 신텍스슈가 업데이트보다 이런 원초적인 가독성 문제를 뒤집으면 좋겠다는 바람이 있습니다.

그리고 메서드 매개변수 외부용/내부용 이름을 별도로 지을수 있으면 좋겠고요.
swift 기능인데, 이건 좀 변태적인 내용일 거 같지만 호출 할 때 명령문을 거의 자연어(영어)에 가깝게 작성할 수 있거든요.

이렇게 한다고할때 영문법은 전치사가 많다보니 매개변수를 전치사로 지을 일이 많거든요. 외부이름은 전치사로하고 {}블락안에서는 의미론적 변수이름을 사용을 하면 좋더라고요.

C#에선 안되니까 내부에서 바꿔줄순 있지만 좋지않은 코드가되니 안하긴 하는데요.
호출할때 영어로 말이 이어지지 않으니까 괜히 불편합니다. ㅎㅎ

1 Like

C#에서는 var 키워드의 사용을 강제하지도 않고 IDE에서 선호에 따라 사용할수 있도록 설정할 수 있는 기능을 제공해 주고 있죠.

위에서 언급하신 내용들은 개인적 취향의 문제이지 언어의 문제는 아닌것 같습니다.

C# 3.0이 나왔을 때 var 키워드의 지원은 많은 개발자들이 환호했었지만 C# 9.0에 와서는 Target typed new 문법의 지원으로 List<int> indices = new();와 같이 우리가 생각하는 순서와 동일하게 코드를 작성할 수 있기에, 혹자는 가독성 측면에서는 더 유리하다고 볼 수도 있을 것입니다.

또한, Visual Studio 에서는 암시적 변수의 타입을 표시해주는 기능도 제공합니다.

도구 - 옵션 - 텍스트 편집기 - C# - 고급 메뉴에서 아래 옵션을 켜면

이렇게 암시적 변수의 형식을 항상 보면서 작업할 수 있습니다.

10 Likes

C도 auto 가 있지요.

IDE가 성능이 좋아서 타입 추론이 매우 잘되므로 코드는 짧게 쓰고 도구를 사용하는 편이 좋습니다.

F#은 강형 타입의 화신 같지만 타입추론때문에 코드작성시 타입 명시를 거의 안해요.

F#은 존재만 아는데 언제 쓰게될일이 있을지 모르겠네요.

네. 취향의 문제는 맞습니다. 차라리 swift를 안썼더라면 불만없이 썼을거 같아요.

저 타입매칭 표시는 좋은기능이네요. Rider쓰는데 Rider도 있을 것같은 느낌이군요.

Rider의 경우 inline으로 명령문 끝 혹은 메서드체이닝 줄바꿈하면 반환타입이 줄줄이 나오는 설정이 있는데 처음다루는 것들은 도움이 되는데 이게 또 긴 코드를 읽어야할 때는 뭔가 덕지덕지 붙어서 가독성이 떨어지더라고요? ㅎㅎ

이 부분은 저도 동감합니다.

리턴 타입에 var를 쓰고, 본문에 return 이 있으면 그 형식으로 유추, 없으면 void 유추하는 게 어렵지는 않을 것 같은데 말이죠.

변수 라벨링이 자연어처럼 보이게 하는 장점이 있어도, 강제 사항이라는 점은 스위프트 진영에서도 논란이 있지 않나요?

CSharpHello("닷넷 히어로", "화이팅!!");
CSharpHello(to: "닷넷 히어로", msg: "화이팅!!");

swiftHello("닷넷 히어로",  "화이팅!!") // 에러
swiftHello(to:"닷넷 히어로", msg: "화이팅!!")

저는 잘 추상화된 OOP 구조와 적절하게 나눠진
매서드 스코프 내에서 var 의 타입을 추론하는건 어렵지 않으리라고 봅니다.
또한 추론해야할 필요가 없을 수도 있구요.

오히려 해당 스코프 내에서 변수가 실질적으로 숫자이냐, 문자이냐를 따지기 보다
명확한 변수명을 통해 OOP 관점에에서 무엇을 의미하느냐가 더 중요하지 않을까 싶습니다.

var 이슈 점화! ㅋㅅㅋ

1 Like

도구 - 옵션 - 텍스트 편집기 - C# - 고급 메뉴에서 아래 옵션

하나 배워 갑니다…

1 Like

var에 대해서는 호불호가 많나 보네요. 자주 얘기가 나오는 것 같아요 ㅋㅋ

저는 var를 엄청 많이 쓰고 변수를 볼 때 타입을 보는게 아니고 이름으로 보아서 큰 문제라고 생각하지 않았던 것 같아요

근데 만약 변수에 타입이 궁금하면 그때 마우스를 변수에 올려서 추론된 타입을 확인하는 방식으로 확인합니다.

1 Like

전 명확한게 좋아서 항상 타입을 정확히 지정 합니다.

그런데 var 를 쓰는게 더 나은 건가요 ?

1 Like

이 문제에 대해서 이 커뮤니티에서도 얘길 해보았는데 더 나은 방법과 아닌 방법으로 접근하시는 것보다 우선 다니시고 계신 회사의 코딩 컨벤션에 맞게 작업하시는게 우선인 것 같습니다. 이 문젠 그냥 개인의 취향이라고 생각합니다.:blush:

저는 개인적으로 var를 사용하면 변수를 선언할 때 중복적으로 들어가는 코드가 없어져서 좋은 것 같습니다.

3 Likes

참고로…

. >ㅁ</

5 Likes

(네임드)파라미터명 강제는 많은 언어들이 안그러는데 스위프트가 특이 케이스에 해당되긴하죠

이말씀하시니 처음 c#으로 전환했을때가 생각나네요.
c# 코드 짤때도 swift하던 습관으로 매개변수명을 꼬박꼬박써서 호출했거든요.

근데 다른 교육자료등 그러는데가 없대요? 길어지기도하고 불편점이 있긴한대다 결정적으로 본문에 얘기한 외부이름 별도로 못하니까 c#은 호출시 자연어처럼 작성이 안되니 영어말이 딱딱 맞게 할수가 없어서 마음이 불편한거예요.

지금은 그냥 c# 스타일로 합니다만 여전히 파라미터명 쓰는게 알아보기 좋다는 느낌입니다 이름고민도 적게하고요.

이게 혼자의 코드는 어차피 자신이 아니까 상관없는데 남의코드 보려면 변수가 뭐가 뭔지 모른다는 단점이 있죠. 당장 닷넥 프레임워크 api들만해도 그런것들이 있어요

파라미터가 많아지면 더욱 알아보기 힘들어지는데 js와 php에서도 그롷잖아요. 그누보드쪽 테마쪽은 php 매개변수명만 봐서는 알아먹기도 힘들더라고요 ㅎㅎ 이쪽은 그런 문제에 앞서서 작성자 작명에 동의 못하는 것에 지나지 않지많요.

1 Like

하나 배워 갑니다. 감사 합니다.

2 Likes

var 를 쓰면 변수의 타입에 포커스가 맞춰지는게 아닌 이름에 맞춰지다 보니 그 변수가 가지는 본질적인 의미를 파악하는데 도움이 되더라고요.

그리고 var사용을 통해 개발자의 실수를 방지할 수 있는 case가 하나 있는데요.
대표적으로 Linq to Sql

// Bad
IEnumerable<Blog> q1 = from b in db.Blogs
                       select b;
IEnumerable<Blog> blogs = q1.Where(b => b.BlogId == 1);

// GOOD
var q2 = from b in db.Blogs
         select b;
IQueryable<Blog> blogs2 = q2.Where(b => b.BlogId == 1);

// GOOD
IQueryable<Blog> q3 = from b in db.Blogs
                      select b;
IQueryable<Blog> blogs3 = q3.Where(b => b.BlogId == 1);
2 Likes