ส่งผ่านเพียงประเภทเป็นพารามิเตอร์ใน C #


130

โดยสมมุติว่าเป็นประโยชน์สำหรับฉันที่จะทำสิ่งนี้:

foo.GetColumnValues(dm.mainColumn, int)
foo.GetColumnValues(dm.mainColumn, string)

โดยที่เมธอด GetColumns จะเรียกใช้เมธอดอื่นภายในขึ้นอยู่กับประเภทที่ส่งผ่าน

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

typeof (arg [1]) หรือคล้ายกัน ...

ฉันยังสามารถลบล้างวิธีการใช้ยาชื่อสามัญ ฯลฯ - ฉันรู้ว่ามีหลายวิธีในการทำเช่นนี้ฉันแค่อยากรู้ว่าเป็นไปได้หรือไม่


ความคิดของฉันขึ้นอยู่กับสิ่งที่ foo เป็นจริง foo.GetColumnValues<int>(dm.mainColumn)อาจเป็นหนทางไป
Major Productions

1
อย่างที่ฉันพูดไปฉันรู้ว่ามีวิธีอื่นในการทำเช่นนี้ (แฟล็กบูลีนยาสามัญการแทนที่เมธอด) ฉันแค่สงสัยว่ามันเป็นไปได้ในฐานะพารามิเตอร์หรือไม่
Mark Mayo

@MarkMayo: ฉันไม่เข้าใจคำถามถ้าคุณ"รู้ว่าคุณยังสามารถแทนที่วิธีการใช้ยาชื่อสามัญ ฯลฯ และคุณรู้ว่ามีวิธีการที่แตกต่างกันในการทำเช่นนี้คุณเป็นเพียงแค่อยากรู้ว่านี้เป็นไปได้" คุณรู้ทั้งหมดนี้แล้ว แต่อยากรู้ว่าเป็นไปได้หรือไม่ ??
Tim Schmelter

@TimSchmelter - ในรูปแบบที่ฉันอธิบาย กล่าวคือส่งผ่านเป็นพารามิเตอร์ที่ 2 ปรากฎว่า Reed ได้พูดในสิ่งที่ฉันเป็นหลังจากนั้น - ที่คุณใช้ (... , Type) นั่นคือสิ่งที่ฉันกำลังมองหา
Mark Mayo

1
เป็นคำถามที่ดีฉันเห็นว่า MS ใช้ Type เป็นพารามิเตอร์สำหรับตัวดำเนินการในตัวใน VB.NET เช่น trycast และมักจะหวังว่าฉันจะทำแบบนั้นด้วยตัวเองใน C # / VB - ตามที่คุณอธิบาย
Chalky

คำตอบ:


213

มีสองแนวทางร่วมกัน ขั้นแรกคุณสามารถผ่านได้System.Type

object GetColumnValue(string columnName, Type type)
{
    // Here, you can check specific types, as needed:

    if (type == typeof(int)) { // ...

สิ่งนี้จะเรียกว่า: int val = (int)GetColumnValue(columnName, typeof(int));

อีกทางเลือกหนึ่งคือการใช้ generics:

T GetColumnValue<T>(string columnName)
{
    // If you need the type, you can use typeof(T)...

สิ่งนี้มีข้อดีในการหลีกเลี่ยงการชกมวยและให้ความปลอดภัยบางประเภทและจะเรียกว่า: int val = GetColumnValue<int>(columnName);


1
คุณยังสามารถใช้เมธอดส่วนขยายสาธารณะ T GetColumnValue <T> แบบคงที่ (คอลัมน์สตริงนี้) {... } จากนั้นคุณสามารถพูดว่า foo.GetColumnValues ​​<string> (dm.mainColumn)
Joshua G

แต่คุณจะกำหนดวิธีการที่มีข้อโต้แย้งหลายข้อได้อย่างไรและหนึ่งในนั้นควรเป็นวิธีการทั่วไป? เนื่องจาก generic ถูกกำหนดไว้ก่อนรายการอาร์กิวเมนต์ของวิธีการคุณจะรู้ได้อย่างไรว่าอันไหนควรเป็นแบบทั่วไป?
BadmintonCat

5
@BadmintonCat T Foo<T,U>(string arg1, U arg2)หรือคล้ายกัน
Reed Copsey

เมื่อใช้แนวทางแรกมีวิธีกำหนดค่าเริ่มต้นให้พิมพ์หรือไม่? (เช่นอะไรเช่นobject GetColumnValue(string columnName, Type type = object)นั้นดูเหมือนจะไม่ค่อยได้ผลสำหรับฉัน แต่มันจะมีประโยชน์ที่จะรู้
Dave Cole

22

foo.GetColumnValues(dm.mainColumn, typeof(string))

หรือคุณสามารถใช้วิธีการทั่วไป:

public void GetColumnValues<T>(object mainColumn)
{
    GetColumnValues(mainColumn, typeof(T));
}

จากนั้นคุณสามารถใช้มันได้เช่น:

foo.GetColumnValues<string>(dm.mainColumn);

13

คุณสามารถส่งประเภทเป็นอาร์กิวเมนต์ได้ แต่คุณต้องใช้typeof:

foo.GetColumnValues(dm.mainColumn, typeof(int))

Typeวิธีการที่จะต้องยอมรับพารามิเตอร์ที่มีประเภท


โดยที่เมธอด GetColumns จะเรียกใช้เมธอดอื่นภายในขึ้นอยู่กับประเภทที่ส่งผ่าน

หากคุณต้องการพฤติกรรมนี้คุณไม่ควรส่ง type เป็นอาร์กิวเมนต์ แต่ใช้พารามิเตอร์ type แทน

foo.GetColumnValues<int>(dm.mainColumn)

8
foo.GetColumnValues(dm.mainColumn, typeof(int));
foo.GetColumnValues(dm.mainColumn, typeof(string));

หรือใช้ยาชื่อสามัญ:

foo.GetColumnValues<int>(dm.mainColumn);
foo.GetColumnValues<string>(dm.mainColumn);

3
ฉันไม่ได้ dv คุณ แต่อาจเป็นเพราะคุณกำลังแสดงว่าจะเรียกอย่างไรและไม่ได้ระบุนิยามฟังก์ชัน
JConstantine

3
ฉันเกลียดเวลาที่มีคนต้องการช้อนป้อนอาหาร คำตอบ + การอ่าน MSDN สั้น ๆ ก็เพียงพอแล้ว ฉันสงสัยว่าผู้ลงคะแนนเป็นผู้ตอบที่แข่งขันกันของตัวแทน - น้อยเพียงใด
Danny Varod



0

ใช้ประเภททั่วไป!

  class DataExtraction<T>
{
    DateRangeReport dateRange;
    List<Predicate> predicates;
    List<string> cids;

    public DataExtraction( DateRangeReport dateRange,
                           List<Predicate> predicates,
                           List<string> cids)            

    {
        this.dateRange = dateRange;
        this.predicates = predicates;
        this.cids = cids;
    }
}

และเรียกแบบนี้ว่า

  DataExtraction<AdPerformanceRow> extractor = new DataExtraction<AdPerformanceRow>(dates, predicates , cids);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.