2016-03-08 6 views
0

У меня есть метод, который является чем-то вроде ниже, и я хочу установить его значение со строкой ввода.Метод с общим типом, значение set

Как я могу это сделать? Любые советы будут весьма благодарны

private static void QueueCheckNAdd<T>(ref T param, string input) 
    { 
     param.DoSomethingLikeSetValue(input); 
    } 

для справки, общий тип что-то вроде междунар или двойной

+1

Если 'T' будет только либо' int' или 'double', вы можете просто написать пару конкретных методов для выполнения преобразования с помощью' int.Parse() 'и' double.Parse() '. Ваш метод не является общим, если его можно использовать только с небольшим фиксированным набором типов. Использование конкретных методов также позволяет вам писать методы без приведения. – antiduh

+0

Замечание: нет действительно хорошего способа ограничить общий тип 'int' /' double' - поэтому, если вы пишете код, который может быть использован, вам нужно проверить, что он может работать со всеми разрешенными типами. –

+0

Я хотел подумать, что однажды мне придется приспособиться к разным типам. Я имел в виду, что прямо сейчас его привязаны только к типам данных int и double – CJC

ответ

1
param = (T)(object)Convert.ChangeType(input, typeof(T)); 

Брикеты необходимо убедить компилятор, что результат действительно типа T.

+0

Я получил его. Большое спасибо – CJC

2

Вы хотите, чтобы param был общим (например, любым типом), и, вы ожидаете, что сможете называть его каким-то методом, правильно? Ну, вы можете увидеть проблему там: если param может быть любого типа, нет способа гарантировать, что он будет иметь метод DoSomethingLikeSetValue (или что-то еще). Я уверен, что вы могли бы прикинуться интроспекцией или принуждением типа времени исполнения, но я думаю, что «чистый» способ сделать то, что вы ищете, - это ограничить тип T некоторым интерфейсом, который имеет необходимый метод (DoSomethingLikeSetValue). Как это:

private static void QueueCheckNAdd<T>(ref T param, string input) where T : IHasSomething { 
    param.DoSomethingLikeSetValue(input); 
} 

public interface IHasSomething { 
    void DoSomethingLikeSetValue(string s); 
} 

Затем вы можете вызвать QueueCheckNAdd обобщенно только если общий тип поддерживает интерфейс IHasSomething. Таким образом, вы могли бы использовать его как это:

public class Foo : IHasSomething { 
    public void DoSomethingLikeSetValue(string s) { 
     Console.WriteLine(s); 
    } 
} 

var f = new Foo(); 
QueueCheckNAdd<Foo>(f, "hello"); 
+0

В то время как хорошее предложение вы не можете сделать это для встроенных типов, поскольку вы не можете добавлять интерфейсы к существующим типам ... –

+0

Это правда, Алексей ... и это вызывает вопрос «если вы можете», Не делай этого, если ты это сделаешь? В конце концов, если безопасность типа такая огромная неудобства, вы, вероятно, должны подумать об использовании языка без шрифта. Да, эта проблема может быть решена RTTI или другими методами, но это указывает на то, что существует большая архитектурная проблема. –

+0

Это тоже очень хороший метод, я буду помнить об этом. Но я пойду с ответом Слэкса, потому что он еще чище. Хотя это может быть медленнее в производительности – CJC

1

Хорошая практика будет использовать интерфейс, как описано выше,

Но если вы хотите немного повеселиться, вы можете так же использовать объект как динамический объект, как показано ниже :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 
{ 
    class SMTHG 
    { 
     public void DoSomethingLikeSetValue(string input) 
     { 
      Console.WriteLine("HEYYYYY!!! DYNAMIC OBJECTS FTW!...\n" + input); 
     } 
    } 
    class Program 
    { 
     private static void QueueCheckNAdd<T>(ref T param, string input) 
     { 
      dynamic dynamicObject = (dynamic)param; 
      dynamicObject.DoSomethingLikeSetValue(input); 
     } 
     static void Main(string[] args) 
     { 
      SMTHG smthg = new SMTHG(); 
      QueueCheckNAdd(ref smthg, "yoyuyoyo"); 
     } 
    } 
} 
+0

Спасибо, интересно – CJC

Смежные вопросы