C # 'ta parametre olarak sadece bir tür geçirme


130

Varsayımsal olarak bunu yapmak benim için kullanışlı olurdu:

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

GetColumns yöntemi, geçirilen türe bağlı olarak içinde farklı bir yöntem çağırır.

Evet, bunu bir boole bayrağı veya benzeri olarak yapabilirdim, sadece bunu geçmenin bir yolu olup olmadığını merak ettim ve sonra sordum:

typeof (arg [1]) veya benzeri ...

Ayrıca yöntemi geçersiz kılabilir, jenerikler kullanabilir vb. - Bunu yapmanın farklı yolları olduğunu biliyorum, bunun mümkün olup olmadığını merak ettim.


Benim düşüncem, aslında ne olduğuna bağlı olarak. foo.GetColumnValues<int>(dm.mainColumn)gidecek yol olabilir.
Major Productions

1
Dediğim gibi, bunu yapmanın başka yolları da olduğunun farkındayım (boole bayrağı, jenerikler, yöntemi geçersiz kılma) Bir parametre olarak mümkün olup olmadığını merak ettim.
Mark Mayo

@MarkMayo: "Yöntemi geçersiz kılabileceğinizi, jenerik kullanabileceğinizi vb. Biliyorsanız ve bunu yapmanın farklı yolları olduğunu biliyorsanız, bunun mümkün olup olmadığını merak ettiniz " sorusunu anlamıyorum . Yani tüm bunları biliyorsunuz ama mümkün olup olmadığını merak ediyorsunuz?
Tim Schmelter

@TimSchmelter - açıkladığım biçimde. yani 2. parametre olarak iletmek. Görünüşe göre, Reed benim peşinde olduğum şeyi söyledi - nerede kullandığınızı (..., Tür türü). Ben de bunu arıyordum.
Mark Mayo

1
Güzel soru, olumlu oy verildi, MS'in Tip'i VB.NET'te yerleşik operatörler için bir parametre olarak kullandığını görüyorum, örneğin trycast ve bunu C # / VB'de - sizin tarif ettiğiniz şekilde - kendim yapabilmeyi diledim.
Chalky

Yanıtlar:


213

İki ortak yaklaşım vardır. İlk önce geçebilirsinSystem.Type

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

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

Bu şöyle adlandırılır: int val = (int)GetColumnValue(columnName, typeof(int));

Diğer seçenek jenerik kullanmak olacaktır:

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

Bu, kutudan kaçınma ve bir tür güvenlik sağlama avantajına sahiptir ve şöyle adlandırılır: int val = GetColumnValue<int>(columnName);


1
Ayrıca bir uzantı yöntemi de yapabilirsiniz, public static T GetColumnValue <T> (bu string columnName) {...} sonra foo.GetColumnValues ​​<string> (dm.mainColumn)
Joshua G

Ama birkaç argümanı olan ve bunlardan birinin genel olması gereken bir yöntemi nasıl tanımlıyorsunuz? Jenerik, yöntem bağımsız değişken listesinden önce tanımlandığından, hangisinin genel olması gerektiğini nasıl anlarsınız?
BadmintonCat

5
@BadmintonCat T Foo<T,U>(string arg1, U arg2)veya benzeri
Reed Copsey

İlk yaklaşımı kullanırken, yazmaya varsayılan bir değer atamanın bir yolu var mı? (örneğin object GetColumnValue(string columnName, Type type = object)? Bu benim için pek işe yaramıyor gibi görünüyor ama bilmek faydalı olacaktır.
Dave Cole

22

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

Alternatif olarak, genel bir yöntem de kullanabilirsiniz:

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

ve daha sonra şu şekilde kullanabilirsiniz:

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

13

Bir türü bağımsız değişken olarak iletebilirsiniz, ancak bunu yapmak için şunu kullanmalısınız typeof:

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

Yöntemin type ile bir parametreyi kabul etmesi gerekir Type.


GetColumns yöntemi, geçirilen türe bağlı olarak içinde farklı bir yöntem çağırır.

Bu davranışı istiyorsanız, türü bağımsız değişken olarak iletmemeli, bunun yerine bir tür parametresi kullanmalısınız.

foo.GetColumnValues<int>(dm.mainColumn)

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

Veya jenerik kullanarak:

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

3
Sana dv yoktu, ama bunu çağrılacak nasıl gösteriyoruz ve işlevi tanımı belirtmedi çünkü muhtemelen
JConstantine

3
İnsanların kaşıkla beslenmeye ihtiyaç duymasından nefret ediyorum. Cevap + gerçekten kısa bir MSDN okuması yeterlidir. Aşağı oy verenlerin, temsilcilerle rekabet eden cevaplayıcılar olduğundan şüpheleniyorum - ne kadar önemsiz.
Danny Varod

1

Bunu yapabilirsin, sadece sarın typeof()

foo.GetColumnValues(typeof(int))

public void GetColumnValues(Type type)
{
    //logic
}

0

Type - iow türünde bir argüman kullanabilirsiniz, pass typeof (int). Ayrıca (muhtemelen daha verimli) bir yaklaşım için jenerikleri de kullanabilirsiniz.


0

Genel türleri kullanın!

  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;
    }
}

Ve şöyle diyelim:

  DataExtraction<AdPerformanceRow> extractor = new DataExtraction<AdPerformanceRow>(dates, predicates , cids);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.