Тип Задание объекта с использованием объекта "Тип" в С#

Этот покажется мне немного сложным. Мне интересно, можно ли набирать объект, используя объект System.Type.

Ниже я проиллюстрировал то, что я имею в виду:

public interface IDataAdapter
{
    object Transform(object input);
    Type GetOutputType();
}

public class SomeRandomAdapter : IDataAdapter
{
    public object Transform(object input)
    {
        string output;

        // Do some stuff to transform input to output...

        return output;
    }

    public Type GetOutputType()
    {
        return typeof(string);
    }
}

// Later when using the above methods I would like to be able to go...
var output = t.Transform(input) as t.GetOutputType();

Вышеприведенный общий интерфейс, поэтому я использую "объект" для типов.

Ответ 1

Типичный способ сделать это - использовать дженерики, например:

public T2 Transform<T, T2>(T input)
{
    T2 output;

    // Do some stuff to transform input to output...

    return output;
}

int    number = 0;
string numberString = t.Transform<int, string>(number);

Как вы упомянули в своем комментарии ниже, дженерики очень похожи на С++ Templates. Здесь вы можете найти документацию MSDN для Generics здесь, а статья " Различия между шаблонами С++ и С# Generics (Руководство по программированию на С#) ", вероятно, будут полезны.

Наконец, я мог бы не понимать, что вы хотите делать внутри тела метода: я не уверен, как вы преобразуете произвольный тип T в другой произвольный тип T2, если вы не укажете ограничения на общий типы. Например, вам может потребоваться указать, что они оба должны реализовать некоторый интерфейс. Ограничения на параметры типа (Руководство по программированию на С#) описывает, как это сделать на С#.

Изменить. Учитывая ваш пересмотренный вопрос, я думаю, этот ответ от Marco M. правильный (то есть, я думаю, вы должны использовать делегат Converter, где вы в настоящее время пытаетесь использовать ваш интерфейс IDataAdapter.)

Ответ 2

Почему это осложняется, когда вы уверены, что он возвращает строку?

var output = t.Transform(input) as string;

Если я неправильно понял то, что вы говорите, вот еще один способ

var output = Convert.ChangeType(t.Transform(input), t.GetOutputType());

Ответ 3

Вам лучше использовать что-то вроде делегата Converter

public delegate TOutput Converter<TInput, TOutput>(TInput input);

например, msdn

public static void Main()
{
    // Create an array of PointF objects.
    PointF[] apf = {
        new PointF(27.8F, 32.62F),
        new PointF(99.3F, 147.273F),
        new PointF(7.5F, 1412.2F) };

    // Display each element in the PointF array.
    Console.WriteLine();
    foreach( PointF p in apf )
        Console.WriteLine(p);

    // Convert each PointF element to a Point object.
    Point[] ap = Array.ConvertAll(apf, 
        new Converter<PointF, Point>(PointFToPoint));

    // Display each element in the Point array.
    Console.WriteLine();
    foreach( Point p in ap )
    {
        Console.WriteLine(p);
    }
}

public static Point PointFToPoint(PointF pf)
{
    return new Point(((int) pf.X), ((int) pf.Y));
}

Ответ 4

Вышеприведенный общий интерфейс, поэтому я использую "объект" для типов

Не имеет смысла использовать фактический общий интерфейс:

public U Transform<T, U>(T input)
{
    string output;

    return output;
}

U output = t.Transform(input) as U;

Ответ 5

Это то, с чем я пошел (основываясь на структуре IEnumerable):

public interface IDataAdapter
{
    object Transform(object input);
}

public interface IDataAdapter<OutT, InT> : IDataAdapter
{
    OutT Transform(InT input);
}

public class SomeClass : IDataAdapter<string, string>
{
    public string Transform(string input)
    {
        // Do something...
    }

    public object Transform(object input)
    {
        throw new NotImplementedException();
    }
}