ทำไม ReSharper ต้องการใช้ 'var' สำหรับทุกสิ่ง


214

ฉันเพิ่งเริ่มใช้ ReSharper กับ Visual Studio (หลังจากคำแนะนำมากมายใน SO) หากต้องการลองฉันเปิดโครงการ ASP.NET MVC เมื่อเร็ว ๆ นี้ หนึ่งในสิ่งแรกและบ่อยที่สุดที่ฉันสังเกตเห็นมันคือการแนะนำให้เปลี่ยน / ประกาศทั้งหมดของฉันชัดเจนที่สุดไปvarแทน ตัวอย่างเช่น:

//From This:
MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
//To This:
var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

และอื่น ๆ แม้จะมีประเภทง่ายๆเช่นint, boolฯลฯ

เหตุใดจึงมีการแนะนำนี้ ฉันไม่ได้มาจากวิทยาการคอมพิวเตอร์หรือพื้นหลัง. NET มี "ตกอยู่ใน" การพัฒนา. NET เมื่อเร็ว ๆ นี้ดังนั้นฉันชอบที่จะเข้าใจสิ่งที่เกิดขึ้นและไม่ว่าจะเป็นประโยชน์หรือไม่



27
ฉันเคยคิดเกี่ยวกับเรื่องนี้มาระยะหนึ่งแล้วและฉันก็สรุปได้ว่าฉันควรใช้อยู่เสมอvarแม้ว่าจะไม่ชัดเจนก็ตาม! เหตุผลก็เพราะมันบังคับให้ฉันเลือกชื่อที่มีความหมายมากที่สุดที่ฉันสามารถสร้างได้และท้ายที่สุดก็ทำให้โค้ดอ่านได้มากขึ้น ในที่สุดมันก็ช่วยแยกตรรกะออกจากการใช้งาน แน่นอนว่าเป็นเพียงความคิดเห็นของฉันฉันหวังว่ามันจะช่วยให้ใครบางคน;)
MasterMastic

คำตอบ:


189

เหตุผลหนึ่งที่ทำให้อ่านง่ายขึ้น ไหนดีกว่ากัน

Dictionary<int, MyLongNamedObject> dictionary = new Dictionary<int, MyLongNamedObject>();

หรือ

var dictionary = new Dictionary<int, MyLongNamedObject>();

260
ฉันจะบอกคนแรก ง่ายกว่าที่จะเห็นว่าเกิดอะไรขึ้น!
Mongus Pong

104
เชื้อรา: คุณชอบคุณชอบข้อความซ้ำซ้อนหรือไม่ข้อความซ้ำซ้อน? : D
Mark Simpson

73
ความชัดเจนในความคิดของฉันชัดเจนยิ่งขึ้น การใช้ var เพื่อสร้างความปวดหัวในบางสถานการณ์
user1231231412

172
ฉันเกลียดมันเมื่อนักพัฒนาใช้varสำหรับทุกอย่าง - ฉันทำจำนวนมากและจำนวนมากของการตรวจสอบรหัสการใช้ TFS (diffs web based) และมันทำให้งานของผมยากมาก: เช่นvar items = GetSomeItems();เทียบกับIDataReader dr = GetSomeItems();ที่ขาดหายไปโดยใช้คำสั่งทั้ง แต่ง่ายสำหรับผมที่จะจับเมื่อใช้VSIDataReader var
Chris Gessler

17
หากคุณเป็นนักพัฒนาที่ดีเขียนโค้ดที่ดีและคุณใช้ห้องสมุดอย่าง Resharper คุณก็ไม่จำเป็นต้องรู้ประเภทที่ชัดเจนที่คุณติดต่อด้วย เช่นเดียวกับเมื่อคุณใช้อินเทอร์เฟซเพื่อประกาศสัญญา แต่ไม่ใช่คลาสที่เป็นรูปธรรม var ช่วยให้คุณพูดได้ว่าคุณไม่สนใจว่า "type" return คืออะไรคุณสนใจสิ่งที่ทำและใช้ตัวแปรที่มีชื่อดีเท่านั้น ด้วยผู้ช่วย intelli-sense & resharper / VS (เช่น CTRL + คลิกเพื่อนำทางไปยังคำจำกัดความ) คุณจะได้รับ 99% ของวิธีการที่นั่น นอกจากนี้การใช้ var หมายความว่าฉันไม่จำเป็นต้องเขียนรหัสฐานใหม่หากฉันเปลี่ยนประเภทการคืนค่าวิธี
Joshua Barker

286

สิ่งที่ ReSharper แนะนำคือการใช้คำหลัก var มากเกินไปอย่างชัดเจน คุณสามารถใช้มันในกรณีที่ประเภทชัดเจน:

var obj = new SomeObject();

หากประเภทไม่ชัดเจนคุณควรเขียน:

SomeObject obj = DB.SomeClass.GetObject(42);

36
ในการเล่นผู้สนับสนุนปีศาจบางทีหากประเภทไม่ชัดเจนจากวิธีการหรือชื่อตัวแปรมันแสดงว่ามีปัญหากับการตั้งชื่อมากกว่าแล้วก็คือการใช้ var มากเกินไป ฉันเห็นด้วยในหลักการแม้ว่า, var ควรใช้เฉพาะเมื่อไม่ได้ลบความชัดเจน
Matt Briggs

33
ในกรณีนี้ฉันต้องการใช้ชื่อตัวแปรที่ดีกว่า โดยทั่วไปคุณเสนอว่าเราเงยหน้าขึ้นมองว่าตัวแปรนั้นถูกกำหนดให้หาประเภท - ฉันกำลังเสนอให้เราตั้งชื่อตัวแปรให้ดีขึ้นเพื่อที่เราจะได้ทราบถึงวัตถุประสงค์ของตัวแปรโดยทันที
Jaco Pretorius

18
@Jaco: +1 แต่ควรพูดถึงว่าไม่แนะนำให้ใช้ข้อมูลเกี่ยวกับประเภทในชื่อตัวแปร ตัวอย่างเช่นสัญกรณ์ฮังการีไม่ถือว่าเป็นแนวปฏิบัติที่ดี
โรมัน Boiko

8
การตั้งค่าเริ่มต้นของ ReSharper เป็นการใช้งานมากเกินไปหรือvarไม่เป็นเรื่องของความเห็นไม่ใช่สิ่งใด "ชัดเจน" ฉันไม่ต้องการพิมพ์สิ่งที่คอมไพเลอร์สามารถเข้าใจได้ ฉันชอบการอนุมานแบบ C # และมักจะหวังว่ามันดีเท่ากับการอนุมานแบบ F # ถ้าฉันทำได้ฉันจะออกจากประเภทที่ชัดเจนจากพารามิเตอร์วิธีการและประเภทผลตอบแทนเช่นเดียวกับบรรทัดฐานใน F # ไม่ใช่ทุกคนที่เห็นด้วยแน่นอน
Joel Mueller

15
@AnonymousType: คุณยังขาดประเด็น คุณบอกว่าชื่อเมธอดควรสะท้อนถึงเจตนาของเมธอดเสมอ แต่แม้ว่าชื่อนั้นจะไม่ได้หมายความว่าชื่อนั้นจะระบุชนิดของค่าที่ส่งคืน วิธีการอ่านจากการให้Streamวัตถุตัวอย่างเช่นการตั้งชื่อไม่ได้Read ReadAndReturnNumberOfBytesAsInt32
Guffa

99

ฉันชอบที่จะปิดคำแนะนำนี้เป็นการส่วนตัว การใช้varบ่อยครั้งสามารถปรับปรุงความสามารถในการอ่านได้ แต่ดังที่คุณกล่าวถึงบางครั้งก็ลดขนาดมันลง (ด้วยประเภทที่เรียบง่ายหรือเมื่อประเภทผลลัพธ์ที่ไม่ชัดเจน )

ฉันชอบที่จะเลือกเมื่อฉันใช้varและเมื่อฉันไม่ แต่นั่นเป็นเพียงฉัน


11
ฉันคิดว่า ReSharper นั้นฉลาดพอสมควร ไม่ควรฉลาดพอที่จะรู้ว่าประเภทผลลัพธ์นั้นชัดเจน (เช่นอะไรที่มีคำหลักใหม่) และเมื่อไม่ชัดเจน
DisgruntledGoat

3
ฉันไม่รู้ลักษณะเฉพาะของฟีเจอร์ แต่ฉันแน่ใจว่ารู้ว่าฉันได้รับคำแนะนำมากมาย และฉันก็ใช้varบ่อยเกินไป
ไบรอันเมนาร์ด

5
ฉันพบว่าเมื่อคุณใช้ var (เช่น resharper แนะนำ) เสมอมันบังคับให้คุณตั้งชื่อตัวแปรของคุณอย่างถูกต้อง
Sauleil

คุณสามารถปิดคำแนะนำได้หรือไม่
Chris S

@AngeDeLaMort: ประเด็นก็คือว่ามันบังคับให้คุณใช้ชื่อที่ไม่เหมาะสม var methodXYResultIntArrayfe int[] methodXYResultนั่นคือกับมาตรฐานการเข้ารหัสทั้งหมดและรัดกุมน้อยกว่า หากคุณต้องการส่งคืนbyte[]เมธอดจากวิธีการในอนาคตชื่อตัวแปรทั้งหมดของคุณผิด ด้วยประเภทที่ชัดเจนคุณสามารถ refactor นี้ได้อย่างง่ายดายมาก มีเหตุผลที่จะใช้var, fe Dictionary<string, List<SomeType<int>>>กับ แต่ถ้าชื่อเต็มประเภทไม่ยาวเกินไปและคุณไม่ได้ใช้งานnewโปรแกรมแก้ไขด้านขวา (หรือนักแสดงอย่างชัดแจ้ง) ด้านขวาไม่ควรแนะนำ
Tim Schmelter

69

varสามารถเพิ่มความสามารถในการอ่านของรหัสในขณะที่ลดความเข้าใจรหัสทันที เช่นเดียวกันมันสามารถลดความสามารถในการอ่านของรหัสสำหรับสถานการณ์อื่น ๆ บางครั้งการใช้มันเป็นกลาง การวัดความสามารถในการอ่านเพื่อความเข้าใจไม่ได้เป็นสัดส่วน แต่ขึ้นอยู่กับสถานการณ์ บางครั้งทั้งสองจะเพิ่มขึ้นหรือลดลงด้วยกัน

ปัจจัยคืออะไร varถูกนำไปใช้และเป้าหมายสนับสนุนการทำให้ข้อมูลประเภทนั้นสับสนกับผู้อ่านได้ทันทีหรือหากจำเป็นต้องใช้ข้อมูลประเภทนั้นในการทำความเข้าใจส่วนของโปรแกรมในมือ

ตัวอย่างเช่นการตั้งชื่อไม่ดีสามารถนำไปสู่การvarลดความเข้าใจรหัส นี่ไม่ใช่varความผิดของ:

var value1 = GetNotObviousValue(); //What's the data type? 
//vs. 
var value2 = Math.Abs(-3); // Obviously a numeric data type. 

บางครั้งมันก็ไม่สมเหตุสมผลที่จะใช้varกับชนิดข้อมูลอย่างง่าย ๆ เมื่อโค้ดอ่านได้ง่ายขึ้นในกรณีที่ไม่มี:

var num = GetNumber(); // But what type of number?
// vs. 
double num = GetNumber(); // I see, it's a double type. 

บางครั้งvarอาจมีประโยชน์ในการซ่อนข้อมูลประเภทข้อมูลที่คุณไม่ต้องการดูแลเพื่อดูความซับซ้อนของ:

    IEnumerable<KeyValuePair<string,List<Dictionary<int,bool>>>> q = from t in d where t.Key == null select t; // OMG! 
    //vs. 
    var q = from t in d where t.Key == null select t;

    // I simply want the first string, so the last version seems fine.  
    q.First().Key; 

คุณต้องใช้varเมื่อมีประเภทที่ไม่ระบุชื่ออยู่เนื่องจากไม่มีชื่อประเภทที่จะเรียกโดย:

var o = new { Num=3, Name="" };

เมื่อคุณมี Intellisense Visual Studio ที่ให้ข้อมูลประเภททั้งๆที่varคุณต้องพึ่งพาความเข้าใจของคุณน้อยลงผ่านการอ่านรหัสที่เข้มงวดโดยไม่ต้องให้ความช่วยเหลือ อาจเป็นการดีที่จะสมมติว่าไม่ใช่ทุกคนที่มีหรือใช้ Intellisense

โดยสรุปจากตัวอย่างข้างต้นฉันขอแนะนำให้ใช้แอปพลิเคชันตามสั่งของ blanchevarไม่ใช่ความคิดที่ดีเพราะสิ่งต่าง ๆ ส่วนใหญ่ทำได้ดีที่สุดในการกลั่นกรองและตามสถานการณ์ในมือดังที่แสดงไว้ที่นี่

เหตุใด Resharper จึงใช้ค่านี้โดยปริยาย ฉันขอแนะนำให้ใช้งานง่ายเพราะมันไม่สามารถแยกความแตกต่างของสถานการณ์ที่จะตัดสินใจได้ดีที่สุดว่าจะไม่ใช้เมื่อใด


5
IMHO ตัวอย่างของคุณเป็นเหตุผลที่ดีที่จะใช้varจริงมันจะบังคับให้คุณเขียนชื่อวิธีการที่เหมาะสม GetNumber() -but what type?- ทำไมคุณถึงสนใจ? ถ้ามันเป็นเรื่องที่สำคัญที่จะรู้วิธีการเรียกGetNumberAsDouble()แล้วมันเป็นเพียงเป็นที่ชัดเจนและจะทำงานหากคุณมีวิธีการหนึ่งที่กลับมาและกลับstring double
nicodemus13

10
@ nicodemus13 คุณมักจะรู้ว่าคุณสนใจฟังก์ชั่น return ของฟังก์ชั่นเมื่อคุณใช้ค่า return มากกว่าการเขียนฟังก์ชั่น รูปแบบการตั้งชื่อที่คุณแนะนำอาจนำไปสู่การละเมิดเช่น GetResultsAsIEnumerableOfDouble และทุกอย่างที่ทำได้คือเปลี่ยนข้อมูลประเภทที่คุณลบออกจากด้านซ้ายของการมอบหมายโดยใช้ var ไปทางด้านขวาของ assignemnt
Eric

var value2 = Math.Abs ​​(-3); // เห็นได้ชัดว่าเป็นข้อมูลประเภทตัวเลข ขออภัยฉันไม่เห็นด้วยกับวิธีนี้อย่างสมบูรณ์เนื่องจากวิธี Abs มี 7 โอเวอร์โหลดที่นำไปสู่อะไร แต่ความสับสนเมื่อมองดู imo
s1cart3r

var ยังสามารถนำไปสู่ข้อผิดพลาดเชิงตรรกะที่ละเอียดอ่อนเช่น: var counter = "0"; เมื่อสิ่งที่คุณต้องการคือจำนวนเต็ม
alaniane

42

ใน ReSharper (8.02 แต่รุ่นอื่น ๆ มีแนวโน้ม) ตัวเลือกสำหรับข้อเสนอแนะ "ใช้พิมพ์โดยปริยายประกาศตัวแปรท้องถิ่น" สามารถปรับให้คุณตั้งค่าสิ่งที่อาจจะโดยการเปิดตัวครั้งแรกเมนูตัวเลือกสำหรับ ReSharper:

เมนูตัวเลือก ReSharper

จากนั้นภายใต้ "การตรวจสอบรหัส" โดยปรับ "ความรุนแรงในการตรวจสอบ" ของภาษาที่คุณเลือกในกรณีของฉัน c #:

ปิดคำแนะนำตัวแปรท้องถิ่นที่พิมพ์โดยนัย

อย่างที่คุณเห็นมีตัวเลือกในการปรับคำแนะนำทั้งหมดที่ ReSharper ทำ ความหวังนี้จะช่วยให้คนอย่างฉันที่มีกลยุทธ์การใช้งาน 'var' อยู่แล้วและต้องการให้ ReSharper ให้ความเคารพ :)


นี่ตอบคำถามที่แตกต่างที่ไม่ได้ถามเลย
Carles Alcolea

9
แต่มันเกี่ยวข้องกับหลายคนที่มองหามันเมื่อมาถึงที่นี่ +1
Ori Nachum

24

ฉันประหลาดใจที่ไม่มีใครพูดถึงว่ามันง่ายกว่าที่จะเปลี่ยนประเภทของวัตถุที่สร้างอินสแตนซ์

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

เป็นรูปแบบของการทำซ้ำ ถ้าฉันต้องการที่จะเปลี่ยนAVeryLongTypeNameเป็นหนึ่งในชั้นเรียนที่ได้รับของมันฉันต้องเปลี่ยนเพียงครั้งเดียวเมื่อใช้varและยังคงสามารถเข้าถึงวิธีการของชั้นเรียนเด็ก

นอกเหนือจากนั้นความสามารถในการอ่านที่ดีขึ้นเป็นประเด็นสำคัญ แต่อย่างที่คนอื่นพูดว่าไม่ควรใช้ความแปรปรวนมากเกินไปดังนั้นฉันคิดว่าการปิดคำใบ้ใน Resharper นั้นทำได้อย่างสมบูรณ์


มีประโยชน์มากเมื่อเรียกวิธีการจากโรงงานแทนที่จะเป็น "ใหม่"
Ian Ringrose

หากคุณต้องการใช้ 'MyClass' เมื่อคุณเขียนรหัสในตอนแรกและใช้งานได้ เมื่อคุณต้องการเปลี่ยนแปลงคุณต้องไปและเปลี่ยนแปลงทุกที่โดยเฉพาะอย่างยิ่งเมื่อคุณมีอินเทอร์เฟซที่เกี่ยวข้อง รหัสไม่ควรได้รับการปฏิบัติเหมือนเรียงความมันควรมีความหมายและชัดเจน
Piotr Kula

24

'var' กำลังจะชัดเจน

การถกเถียงหลักเกี่ยวกับว่าจะใช้varคำหลักหรือไม่นั้นเป็นเรื่องเกี่ยวกับวิธีการอ่านรหัสที่มีต่อคุณและนักพัฒนาอื่น ๆ

ราวกับว่าคุณกำลังเขียนเรื่องราวไม่มีคำตอบที่ถูกต้องชัดเจน แต่ลองมาดูตัวอย่างของสิ่งนี้เป็นภาษาอังกฤษธรรมดา

เจคกล่าวทักทายกับบิล เขาไม่ชอบเขาดังนั้นเขาจึงหันไปทางอื่น

ใครไปทางอื่น เจคหรือบิล? ในกรณีนี้การใช้ชื่อ "Jake" และ "Bill" ก็เหมือนกับการใช้ชื่อประเภท และ "เขา" และ "เขา" ก็เหมือนกับการใช้varคำหลัก ในกรณีนี้อาจช่วยให้เฉพาะเจาะจงมากขึ้น ตัวอย่างต่อไปนี้ชัดเจนยิ่งขึ้น

เจคกล่าวทักทายกับบิล เจคไม่ชอบบิลดังนั้นเขาจึงหันไปทางอื่น

ในกรณีนี้การเจาะจงมากขึ้นทำให้ประโยคชัดเจนยิ่งขึ้น แต่นั่นไม่ได้เป็นกรณีเสมอไป ในบางกรณีความเฉพาะเจาะจงทำให้อ่านยากขึ้น

Bill ชอบหนังสือดังนั้น Bill จึงไปที่ห้องสมุดและ Bill เอาหนังสือที่ Bill ชอบมาตลอด

ในกรณีนี้มันจะง่ายต่อการอ่านประโยคถ้าเราใช้ "เขา" และในบางกรณีทำให้ชื่อของเขาหายไปด้วยกันซึ่งเทียบเท่ากับการใช้varคำหลัก

บิลชอบหนังสือดังนั้นเขาจึงไปที่ห้องสมุดและหยิบหนังสือที่เขาชอบมาตลอด

ตัวอย่างเหล่านั้นครอบคลุมส่วนสำคัญ แต่พวกเขาไม่ได้บอกเรื่องราวทั้งหมด ในตัวอย่างเหล่านั้นมีเพียงวิธีเดียวในการอ้างถึงบุคคลนั้น ทั้งโดยใช้ชื่อของพวกเขาหรือโดยใช้คำทั่วไปเช่น "เขา" และ "เขา"

ในกรณีของรหัสเรามี 3 วิธีที่เราช่วยเพิ่มความชัดเจน ชนิดชื่อตัวแปรและการกำหนด ใช้บรรทัดของรหัสนี้เช่น:

Person p = GetPerson();

ตอนนี้กลายเป็นคำถามมีข้อมูลเพียงพอในบรรทัดของรหัสนั้นเพื่อช่วยให้คุณทราบว่าเกิดอะไรขึ้น

แล้วโค้ดต่อไปนี้ล่ะ? คุณยังคงรู้pว่าในกรณีนี้มีความหมายอย่างไร:

var p = GetPerson();

ตอนนี้:

var p = Get();

หรือตอนนี้:

var person = Get();

หรืออันนี้:

var t = GetPerson();

หรือสิ่งนี้:

var u = Person.Get();

ไม่ว่าจะเป็นคำสำคัญ varทำงานในสถานการณ์ที่กำหนดหรือไม่นั้นขึ้นอยู่กับบริบทของรหัสเช่นวิธีการตั้งชื่อตัวแปรคลาสและวิธีการต่างๆ นอกจากนี้ยังขึ้นอยู่กับความซับซ้อนของรหัสและรหัสที่เหลือโดยรอบ

โดยส่วนตัวแล้วฉันชอบที่จะใช้varคำหลักมันครอบคลุมมากขึ้นสำหรับฉันตลอดเวลา แต่ฉันก็มักจะตั้งชื่อตัวแปรของฉันตามประเภทดังนั้นฉันจะไม่สูญเสียข้อมูลใด ๆ

ที่กล่าวว่าบางครั้งขึ้นอยู่กับบริบทที่ฉันทำข้อยกเว้นเช่นลักษณะของสิ่งที่ซับซ้อนและซอฟต์แวร์คืออะไรถ้าไม่ซับซ้อน


1
ฉันชอบคำตอบนี้ดีที่สุดเพราะฉันไม่มีอะไรจะต่อต้านvarตราบเท่าที่ฉันรู้ว่ามันคืออะไรในขณะที่อ่านหนึ่งบรรทัด หากฉันไม่ทราบว่าวิธีการใดจากโซลูชันอื่นที่ใช้โมเดลโดเมนที่แตกต่างกันกลับมาฉันควรกำหนดประเภทนั้นไว้อย่างชัดเจนทำให้อ่านง่าย +1
Piotr Kula

ในทุกกรณีของคุณที่ประเภทที่ส่งคืนไม่ชัดเจนฉันยอมรับว่าคุณไม่ควรใช้ var เนื่องจากคุณไม่เห็นข้อมูลที่เป็นประโยชน์
ม้วน

18

ฉันไม่ชอบสิ่งนี้เช่นกัน

ฉันไม่ต้องการให้สิ่งนี้กลายเป็นการอภิปรายเกี่ยวกับการใช้varมันมีประโยชน์ แต่ไม่ควรใช้ทุกที่

สิ่งสำคัญที่ต้องจำคือ ReSharper ถูกกำหนดค่าให้เป็นมาตรฐานการเข้ารหัสที่คุณต้องการ

แก้ไข: ReSharper และ var


13
หลังจากผ่านไปหนึ่งปีหรือต่อต้านฉันก็มักจะใช้ var ตอนนี้
เลียม

15

ฉันเห็นคำตอบที่ถูกต้องมากมาย แต่ไม่มีคำตอบเต็ม

มันเป็นความจริงที่ ReSharper overuses varโดยปริยาย ฉันคิดว่าคนส่วนใหญ่จะเห็นด้วยกับที่ นอกจากนี้ยังง่ายต่อการอ่านเมื่อvarมีการใช้งานและประเภทจะชัดเจนเช่นเมื่อคุณใช้newคำสั่ง ฉันเห็นหนึ่งโพสต์ที่แสดงวิธีการอัปเดตความรุนแรงของการตรวจสอบเพื่อแสดงเฉพาะคำแนะนำสำหรับการใช้งานvarผมเห็นโพสต์หนึ่งที่แสดงให้เห็นถึงวิธีการปรับปรุงการตรวจสอบความรุนแรงที่จะแสดงเฉพาะคำแนะนำสำหรับการใช้งานของ

ฉันพยายามแสดงความคิดเห็นในโพสต์อื่นก่อนเพื่อเพิ่มตำแหน่งที่จะตั้งค่าเหล่านี้ แต่ไม่มีชื่อเสียงสำหรับมัน เห็นได้ชัดว่าฉันยังไม่มีชื่อเสียงในการโพสต์ภาพหน้าจอของการตั้งค่า

ฉันจะอธิบายวิธีการเดินทาง

ใน Visual Studio> เมนูหลัก> Resharper> ตัวเลือก> การแก้ไขรหัส> C #> ลักษณะรหัส> การใช้ Var ในการประกาศ

  • สำหรับประเภทในตัวใช้ประเภทที่ชัดเจน
  • สำหรับประเภทง่าย ๆ ให้ใช้ 'var' เมื่อเห็นได้ชัด
  • ที่อื่น Use'var '

ป้อนคำอธิบายรูปภาพที่นี่

เอกสารวิธีใช้ ReSharper ใหม่: รูปแบบไวยากรณ์ของโค้ด: การพิมพ์โดยนัย / โดยชัดแจ้ง (คำหลัก 'var') - กำหนดค่าการกำหนดลักษณะการใช้คำหลัก 'var'


ควรทำเครื่องหมายเป็นคำตอบที่ถูกต้องนอกเหนือจากการอภิปราย var นี่คือวิธีการที่สมดุล
Brian Ogden

คุณสามารถยกตัวอย่างเกี่ยวกับวิธีการตัดสินใจที่ชัดเจนได้อย่างไร?
ม้วน


13

กฎของฉันคือ:

  • คุณกำลังประกาศชนิดดั้งเดิม (เช่นbyte, char, string, int[], double?, decimalฯลฯ )? -> ใช้ประเภท:

    string myStr = "foo";
    int[] myIntArray = [123, 456, 789];
    double? myDouble = 123.3;
  • คุณกำลังประกาศประเภทที่ซับซ้อน (เช่นList<T>, Dictionary<T, T>, MyObj)? -> การใช้งานvar:

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();

ฉันต้องการที่จะไม่เห็นด้วยเห็นstring myStr = "foo";ได้ชัดว่ามันเป็นสตริง ฉันจะยกตัวอย่างทั้งหมดของคุณในการใช้หมวดหมู่ var ... และการประกาศที่ส่งคืนจากวิธีการใช้ประเภทอธิบาย แต่ในตอนท้ายของวันมันเป็นสิ่งที่คุณและทีมงานของคุณรู้สึกดีขึ้นสำหรับโครงการเฉพาะ
Dean Meehan

12

ฉันต้องการจะชี้ให้เห็นว่าแนะนำให้ใช้ "var" ในข้อตกลงการเข้ารหัส C #

เมื่อชนิดของตัวแปรชัดเจนจากด้านขวาของการกำหนดหรือเมื่อชนิดที่แม่นยำไม่สำคัญ

ดังนั้นนั่นอาจเป็นสาเหตุที่ทิปเปิดอยู่ตามค่าเริ่มต้นใน ReSharper พวกเขายังให้บางกรณีที่จะไม่ปรับปรุงการอ่านด้านล่างขวาในเอกสารเดียวกัน


เป็นสิ่งที่ยอดเยี่ยมเมื่อคุณรู้ว่าประเภทนั้นมาจากSystem.Diagnostics.PerformanceCounter() - คุณสามารถบอกได้อย่างง่ายดายถึงความสมบูรณ์แบบจากคลาสวินิจฉัยในตัว แต่กลับมาที่นี่ประเภทใด var thingyMaBob = GetThatSpecialThing(18,null,(MyEnum)2)? ไม่มีเงื่อนงำการตอกบัตรโดยเฉพาะถ้าคุณมีโครงการมากกว่า 100 โครงการในโซลูชันของคุณ
Piotr Kula

"แนะนำเมื่อชนิดของตัวแปรชัดเจน" และ "พวกเขายังมีบางกรณีที่จะไม่ปรับปรุงความสามารถในการอ่านได้ด้านล่างในเอกสารเดียวกัน" สุจริตฉันคิดว่าฉันพลาดจุดของคุณ คำตอบของฉันพูดในสิ่งเดียวกันกับที่คุณพูด
jose

6

ReSharper แนะนำvarเพราะมันมีแนวโน้มที่จะกระจายการสร้างวัตถุ

เปรียบเทียบตัวอย่างทั้งสองนี้:

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

มันเป็นแค่ชวเลขที่ควรอ่านง่ายขึ้น

ฉันคิดว่าไม่เป็นไรเมื่อคุณสร้างวัตถุใหม่อย่างชัดเจนด้วย "ใหม่" ในตัวอย่างของคุณอาจไม่ชัดเจนว่าคลาสนั้นมีชื่อไม่ถูกต้องหรือไม่


6

BTW, ReSharper ดึงความแตกต่างระหว่าง 'คุณอาจต้องการใช้คำแนะนำนี้กับรหัสของคุณ' และ 'รหัสของคุณเสียต้องการให้ฉันแก้ไขหรือไม่' varคำหลักในหมวดหมู่คำแนะนำพร้อมกับสิ่งที่ชอบ "กลับถ้าจะลดการทำรัง"; คุณไม่ต้องทำตาม

คุณสามารถกำหนดค่าว่าการแจ้งเตือนแต่ละรายการนั้นน่ารำคาญแค่ไหนในกล่องโต้ตอบตัวเลือกหรือผ่านเมนูป๊อปอัพสำหรับการแจ้งเตือนนั้นโดยตรง คุณสามารถลดระดับสิ่งต่าง ๆ เช่นvarข้อเสนอแนะเพื่อให้พวกเขาโดดเด่นน้อยลงหรือคุณสามารถอัพเกรดสิ่งต่าง ๆ เช่นการแจ้งเตือน 'ใช้วิธีการขยาย' เพื่อให้มันปรากฏเป็นข้อผิดพลาดจริง


5

varคุณสมบัติของสุทธิ 3.0 เป็นเพียงการอนุมานชนิดซึ่งเป็นชนิดที่ปลอดภัยและมักจะทำให้รหัสของคุณให้อ่านง่ายขึ้น แต่คุณไม่จำเป็นต้องทำและสามารถปิดคำแนะนำนั้นเป็น resharper ได้หากต้องการ


4

Var เป็นสิ่งที่น่าทึ่ง! ฉันได้เจอนักพัฒนาหลายคนที่อยู่ภายใต้การแสดงผลที่varถูกผูกไว้กับประเภทไดนามิกมันไม่ได้เป็น มันยังคงพิมพ์แบบคงที่มันเป็นเพียงการตัดสินใจโดยคอมไพเลอร์

ต่อไปนี้เป็นข้อดีบางประการของการใช้ var

var ที่พิมพ์น้อยกว่านั้นสั้นกว่าและอ่านง่ายกว่าเช่น

Dictionary<int,IList<string>> postcodes = new Dictionary<int,IList<string>>()Yuk

var postcodes = new Dictionary<int,IList<string>>()\ o / \ o /

ชื่อตัวแปรอธิบายเพิ่มเติม - ผอมบาง แต่ฉันคิดว่ามันสำคัญที่จะปล่อยให้ธรรมชาติของvarแสงเปล่งปลั่งที่นี่ ในฐานะที่varเป็นบิตคลุมเครือจริงๆมันไม่ขอแนะนำให้ชื่อตัวแปร desciptive มากขึ้นมากกว่าการปล่อยให้ชนิดที่พูดสำหรับตัวเอง

การเปลี่ยนแปลงรหัสน้อยลง - หากประเภทการส่งคืนของการเรียกใช้เมธอดเปลี่ยนแปลง คุณต้องเปลี่ยนวิธีการโทรไม่ใช่ทุกที่ที่ใช้

ชนิดที่ไม่ระบุชื่อ - ประเภทที่ไม่ระบุชื่อเป็นแนวคิดที่มีประสิทธิภาพจริงๆโดยเฉพาะอย่างยิ่งในพื้นที่เช่น WebAPI ทรัพยากรบางส่วน หากไม่มี var จะไม่สามารถใช้งานได้

บางครั้งมันก็มีประโยชน์ในการประกาศประเภทอย่างชัดเจนและฉันพบว่ามีประโยชน์มากที่สุดในแบบดั้งเดิมหรือโครงสร้าง ตัวอย่างเช่นฉันไม่พบว่าไวยากรณ์นี้มีประโยชน์มาก:

for(var i = 0; i < 10; i++) 
{

}

VS

for(int i = 0; i < 10; i++) 
{

}

ทุกอย่างขึ้นอยู่กับความชอบส่วนบุคคล แต่การใช้งานvarจริง ๆ จะช่วยเร่งการพัฒนาของคุณและปลดล็อกโลกทั้งโลกของความดีงามประเภทนิรนาม


2

ไม่มีความแตกต่างทางเทคนิคถ้าคุณใช้ var ประเภทจะถูกแปลโดยคอมไพเลอร์ หากคุณมีรหัสเช่นนี้:

var x = 1;

x มีความหมายว่าเป็น int และไม่มีค่าอื่นใดที่สามารถกำหนดได้

คำหลัก var มีประโยชน์หากคุณเปลี่ยนชนิดของตัวแปร จากนั้นคุณจะต้องทำการเปลี่ยนแปลงเพียงครั้งเดียวแทนที่จะเป็นสอง:

var x = 1; --> var x = "hello";
int x = 1; --> string x = "hello";

1
@AlexKamburov รหัส 10 บรรทัดด้านล่างจะแตกอย่างไรก็ตามไม่เกี่ยวข้องกับ var
user3285954

1
@ user3285954 ในบางกรณี var สามารถซ่อนปัญหาและนั่นคือสิ่งที่อาจได้รับน่าเกลียด ปัญหาไม่ได้อยู่ในการเขียนรหัสปัญหาอยู่ในการบำรุงรักษา บางคนโต้แย้งว่ามันสะอาดกว่าด้วย var แต่ฉันเห็นว่าบางครั้งเป็นการทำให้งงงวย มันใกล้เคียงกับการถกเถียงทางศาสนา brad-smith.info/blog/archives/336 ฉันใช้ var เฉพาะสำหรับคำสั่ง Linq และสถานที่อื่น ๆ ที่การประกาศประเภทนั้นเป็นจริงมาก ฉันคิดว่า var เป็นสิ่งที่ดีและผู้คนจำเป็นต้องดูความคิดเห็นของ Anders Hejlsberg เกี่ยวกับสาเหตุของการแนะนำ
Alex Kamburov

2

varคำหลักที่ถูกนำมาใช้ใน C # 3.0 - มันช่วยให้เราสามารถลืมเกี่ยวกับการระบุชนิดของเราอย่างชัดเจน

ไม่มีความแตกต่างที่แท้จริงว่าคุณใช้

MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

หรือ

var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

ยกเว้นการอ่านอย่างแท้จริงและโอกาสน้อยกว่าสำหรับข้อผิดพลาด

ดูเหมือนว่าเป็นตัวอย่างโบราณ แต่การพูดต่อไปนี้อาจช่วยให้คุณเข้าใจ:

var myInt = 23;

ส่งคืนintชนิดในขณะที่

var myInt = "23";

ส่งคืนstringชนิด

การอ้างอิง MSDN


2

การระบุประเภทวัตถุที่ชัดเจนเป็นอย่างใดซ้ำซ้อน แม้จะแปลเป็นภาษาอังกฤษมันฟังดูซ้ำซ้อน: "ใส่อ็อบเจกต์ประเภท X ลงในตัวแปรประเภท X" vs "วางออบเจ็กต์ประเภท X ลงในตัวแปร"

อย่างไรก็ตามการใช้ 'var' มีของข้อ จำกัด มันป้องกันการใช้polymorphismด้านล่างซึ่งเป็นความงามที่บริสุทธิ์ :

สมมติว่าสุนัขขยายสัตว์; Cat ขยายลำดับชั้นของสัตว์:

Animal x = new Dog();
DoStuffWithDog(x as Dog);

x = new Cat();
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

รหัสเดียวกันกับ x ประกาศด้วย 'var' จะไม่ได้รวบรวม

var x = new Dog(); // from this point, x is a Dog
DoStuffWithDog(x as Dog);

x = new Cat(); // cannot assign a Cat instance to a Dog
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

ยังไงก็ตามกลับไปที่คำถามเดิมฉันไม่ได้ใช้ Resharper แต่ฉันคิดว่ามันฉลาดพอที่จะตรวจจับเวลาที่ไม่ใช้ 'var' :-)


4
การหล่อโดยไม่จำเป็น (ด้วยas) นั้นน่ากลัวอย่างยิ่ง คุณเปลี่ยนข้อผิดพลาดการคอมไพล์เป็นข้อผิดพลาดรันไทม์ถ้าคุณมีบางอย่างเช่นAnimal x = new Cat(); DoStuffWithDog(x as Dog); ทำไมใช้ซ้ำ x Dog x = new Dog (), Cat y = new Cat (), บูมไม่มีความคลุมเครือที่เป็นไปได้อีกต่อไป
Mark Sowul

การคัดเลือกนักแสดง (โดยมี 'เป็น' หรือไม่) อาจส่งผลให้เกิดข้อผิดพลาดในขณะทำงาน อะไร 'น่ากลัว' เกี่ยวกับการคัดเลือกนักแสดงเมื่อคุณรู้ว่าคุณกำลังทำอะไรอยู่? ทำไมต้องนำ x มาใช้ซ้ำ ตัวอย่างที่นี่เป็นตัวอย่าง เป้าหมายของตัวอย่างคือการแสดงให้เห็นว่าการใช้ 'var' สามารถส่งผลให้เกิดข้อ จำกัด เมื่อการอ้างอิงนั้นมีความหมายว่าเป็น polymorphic
xtrem

5
ไม่ไม่สามารถ: ความแตกต่างเป็นสิ่งที่ตรงกันข้ามกับสิ่งที่เกิดขึ้นที่นี่ นี้จะพยายามที่จะผ่านวัตถุชนิดAnimalเข้าไปในวิธีการที่ใช้เวลาและDog Catความแตกต่างคือย้อนกลับ: เพื่อให้คุณสามารถผ่านวัตถุชนิดDogและCatเข้าไปในวิธีการที่จะใช้Animalตัวอย่างเช่นvoid Walk(Animal a): Walk(new Cat()),Walk(new Dog())
มาร์ค Sowul

คุณไม่ควรใช้ตัวแปรซ้ำด้วยวิธีนี้นำไปสู่ข้อบกพร่องที่น่ารังเกียจมาก ไม่ชัดเจนในวิธีการสั้น ๆ แต่เมื่อคุณมีรหัส 15-20 บรรทัดคุณจะลืมว่า x คืออะไร อย่าขี้เกียจ: var dog = new Dog (); DoStuff (สุนัข); var cat = new Cat (); DoStuff (แมว);
user3285954

2
ไม่มีการต่อสู้ ฉันไม่มีความรู้สึกต่อการประกาศตัวแปร (โดยนัยหรือชัดเจน) จริง ๆ แล้วฉันใช้อย่างน้อยหนึ่งวันในแต่ละวัน ฉันเพียงแค่เน้นว่าเมื่อคุณเลือกวิธี implicit (var) คอมไพเลอร์จะตัดสินประเภทที่แคบที่สุดสำหรับคุณ ซึ่งอาจไม่ใช่สิ่งที่คุณต้องการเสมอไป นั่นคือทั้งหมดที่
xtrem

2

ในมุมมองของฉันvarควรใช้เมื่อชัดเจนทันทีประเภทคือเมื่อกำหนดค่าของตัวแปร

ตัวอย่าง:

var s = "string value";

เป็นที่ชัดเจนว่าเป็นsstring

ฉันเชื่อว่ามันก็เหมาะสมเมื่อชื่อประเภทตัวแปรนั้นซับซ้อนมาก

ตัวอย่าง:

Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>> dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

// This is a little easier to read than the above statement
var dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

นอกเหนือจากสถานการณ์เหล่านี้ฉันไม่เห็นกำไรใด ๆ ที่จะทำโดยใช้varแต่ฉันสามารถนึกถึงบางสถานการณ์ที่เป็นอันตราย:

ตัวอย่างเช่นชนิดที่ใช้แล้วทิ้งซึ่งมีค่าตัวแปรทางด้านขวาไม่แสดงประเภทอย่างชัดเจน การทิ้ง IDisposable นั้นสามารถลืมได้ง่ายๆ

ตัวอย่าง:

// returns some file writer
var wr = GetWriter();

wr.add("stuff");
wr.add("more stuff");

//...
//...

// Now `wr` needs to be disposed, 
// but there is no clear indication of the type of `wr`,
// so it will be easily overlooked by code writer and code reviewer.

1

'var' เพิ่มองค์ประกอบ "ไดนามิก" ลงในรหัสของคุณ (แม้ว่ารหัสจะยังคงพิมพ์อยู่อย่างแน่นอน) ฉันแนะนำให้ใช้กับมันในกรณีที่ประเภทไม่ชัดเจน ลองพิจารณาตัวอย่างนี้:

var bar = GetTheObjectFromDatabase();
bar.DoSomething();

ClassA {
  void DoSomething() {
  //does something
  }
}

ClassB {
  void DoSomething() {
  //does something entirely different
  }
}

หากการคืนค่าชนิดของ GetTheObjectFromDatabase () เปลี่ยนจาก Type A เป็น B เราจะไม่สังเกตเห็นเนื่องจากทั้งสองคลาสใช้ DoSomething () อย่างไรก็ตามรหัสอาจทำอะไรที่แตกต่างไปจากเดิมอย่างสิ้นเชิง

สิ่งนี้อาจจะบอบบางทั้งสองเขียนสิ่งต่าง ๆ ลงในบันทึกดังนั้นคุณอาจไม่สังเกตเห็นว่ายูนิตนั้นสายเกินไป

การใช้ var ต่อไปนี้ควรจะใช้ได้:

var abc = new Something();

1

สำหรับผู้ที่ไม่ชอบการใช้ "var" อย่างต่อเนื่องคุณสามารถหยุด ReSharper จากการตั้งค่าเริ่มต้นเป็น var เมื่อทำ "แนะนำตัวแปร" นี่เป็นสิ่งที่ทำให้ฉันหงุดหงิดเป็นเวลานานมันมักจะผิดนัด var และฉันก็เปลี่ยนมันทุกครั้ง

การตั้งค่าเหล่านี้อยู่ภายใต้การแก้ไขรหัส> C #> ลักษณะของรหัส

ป้อนคำอธิบายรูปภาพที่นี่


0

ไม่มีความแตกต่างทางเทคนิค (ตามที่ eWolf ชี้ให้เห็น) คุณสามารถใช้อย่างใดอย่างหนึ่งรหัส CLR ที่สร้างขึ้นจะมีลักษณะเดียวกัน

ในความคิดของฉันประโยชน์หลักคือมันบังคับให้คุณใช้การตั้งชื่อตัวแปรที่ดีกว่า ในตัวอย่าง 'foo' ของคุณเป็นตัวเลือกที่ไม่ดีนักสำหรับชื่อตัวแปร


0

ตาม JetBrains (ผู้เขียน ReSharper) พวกเขาสนับสนุนให้ใช้ var โดยค่าเริ่มต้น

จากเว็บไซต์ของพวกเขา :

การใช้ตัวแปรท้องถิ่นที่พิมพ์ไว้โดยนัย (หรือที่รู้จักกันว่าvarคำหลัก) ที่นำมาใช้ใน C # 3.0 ได้รับความนิยมอย่างมากเนื่องจากช่วยเพิ่มความสามารถในการอ่านในสถานการณ์ต่างๆ ตามค่าเริ่มต้น ReSharper ยังสนับสนุนให้ใช้varคำหลัก แต่การกำหนดลักษณะการใช้งานนั้นสามารถกำหนดค่าได้อย่างยืดหยุ่นตัวอย่างเช่นคุณสามารถเลือกใช้ประเภทที่ชัดเจนในบางกรณีหรือทุกที่และ ReSharper จะช่วยให้คุณบังคับใช้ค่ากำหนดของคุณ


ฉันจะกำหนดค่าได้เมื่อใดที่ต้องมีการประกาศอย่างชัดเจน?
user764754
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.