Приведение типа к объекту с использованием объекта типа в C#

До сих пор это оказалось немного сложным для меня. Мне интересно, можно ли ввести объект с помощью объекта 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();

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


person Ryall    schedule 03.09.2009    source источник


Ответы (5)


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

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

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

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

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

person Jeff Sternal    schedule 03.09.2009
comment
Я не смог очистить пример, но два метода находятся в интерфейсе IDataAdapter. - person Ryall; 03.09.2009

Зачем усложнять, если вы уверены, что он возвращает строку?

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

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

var output = Convert.ChangeType(t.Transform(input), t.GetOutputType());
person shahkalpeshp    schedule 03.09.2009
comment
Потому что пример — это интерфейс — обновление сейчас. - person Ryall; 03.09.2009
comment
Я нажму 1 за это! Мне нравится идея Convert.ChangeType() и предоставление типа объекта в качестве второго аргумента, поэтому он будет изменен на этот тип. Я работаю над другой библиотекой и надеюсь, что это спасет мою ночь. Спасибо @shahkalpesh - person Allen Linatoc; 25.08.2015

Вам лучше использовать что-то вроде делегата 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));
}
person Marco M.    schedule 03.09.2009
comment
Как это позволяет объекту Type преобразовать другой объект? TInput и TOutput не являются объектами и должны быть известны во время компиляции. - person Despertar; 19.02.2012

Это то, с чем я пошел (на основе структуры 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();
    }
}
person Ryall    schedule 03.09.2009

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

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

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

    return output;
}

U output = t.Transform(input) as U;
person Kent Boogaart    schedule 03.09.2009
comment
Они выглядят как шаблоны из C++ - на самом деле они еще не описаны в C#. Спасибо! - person Ryall; 03.09.2009
comment
Я немного смущен тем, как вы используете «U» за пределами общего. Какой объем вам дан? - person Ryall; 03.09.2009
comment
@Kelix: U был бы вашим настоящим типом, вы бы не использовали U так. Посмотрите на ответ @Jeff и обратите внимание, что его T2 заменен строкой и совпадает таким же образом. - person Ahmad Mageed; 03.09.2009
comment
Я также мог бы использовать «вар» и вообще не использовать, если я не ошибаюсь? - person Ryall; 03.09.2009