Как я могу реализовать интерфейс для обработки классов приведения типов?

Я хочу передать tType класса функции, а объект класса — универсальной функции.

Мне нужно иметь возможность приведения к этому типу (класса), чтобы я мог получить доступ к методам класса.

Что-то вроде:

void GenericFunction(Object obj, Type type)
{
    (type)obj.someContainer.Add(1);
}

Будет ли работать реализация интерфейса для этих классов, а затем приведение к этому интерфейсу? Если да, то может ли кто-нибудь привести пример?

Я гуглил последние несколько часов, и мне никогда не приходилось этого делать раньше.

Может кто-нибудь пролить свет?


person Michael G    schedule 25.11.2008    source источник


Ответы (6)


Вот три способа сделать то, о чем вы спрашиваете:

public interface ICanReport
{ void Report(); }

public class SomeThing : ICanReport
{
    public void Report()
    { Console.WriteLine("I'm SomeThing"); }
}

public class SomeOtherThing : ICanReport
{
    public void Report()
    { Console.WriteLine("I'm SomeOtherThing"); }
}

public class TestThings
{
    //#1 use safe downcasting
    public void TheMethod(object x)
    {
        ICanReport y = x as ICanReport;
        if (y != null)
          y.Report();
    }

    //#2 use generics
    //  100% safe, but a little complex
    public void AnotherMethod<T>(T x) where T : ICanReport
    {
        x.Report();
    }

    //#3 use an interface as the parameter type.
    //  simple and safe
    public void LastMethod(ICanReport x)
    {
        x.Report();
    }

    //sample calls
    public void Test1()
    {
        SomeThing a = new SomeThing();
        SomeOtherThing b = new SomeOtherThing();
        TheMethod(a);
        TheMethod(b);
        AnotherMethod(a);
        AnotherMethod(b);
        LastMethod(a);
        LastMethod(b);
    }
}
person Amy B    schedule 25.11.2008

Можете ли вы использовать дженерики в вызове вашего метода? Что-то вроде:

void GenericFunction<T>(Object obj)
  where T : class {
  obj.someContainer.Add(1) as T;
}

Надеюсь, это поможет!

person Zachary Yates    schedule 25.11.2008
comment
Я не думаю, что вы могли бы вызвать someContainer.Add() таким образом, поскольку тип неизвестен. Скорее всего, вам нужно будет вызвать этот метод с помощью Reflection. - person Adam Lassek; 25.11.2008
comment
Я действительно просто пытался использовать приведенный выше пример. - person Zachary Yates; 26.11.2008

Ознакомьтесь с System.ComponentModel.TypeConverter.

person Ben Collins    schedule 25.11.2008

хорошо

class A {
    public BindingList<int> addContainers;
}

class B {
     public BindingList<int> addContainers;
}

class C {
     Type type;
     Object senderObj;

     C(Object s, Type t)
     {
            senderObj = s;
            type = t;
     }

     private void AddBtn_Click(click sender, EventArgs e)
     {
            // Depending on the Type passed to the constructor, i need to cast to that type
            // so that i have access to the classes public addContainer member variable
      }
person Michael G    schedule 25.11.2008

Попробуйте этот код. Измените Class2 на Class1 в main, чтобы увидеть результаты.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ReflectionTest
{
    class Class1
    {
        public void helloWorld()
        {
            Console.WriteLine("Hello World 1");
        }
    }

    class Class2
    {
        public void helloWorld()
        {
            Console.WriteLine("Hello World Class 2");
        }
    }

    class Program
    {
        static void callCorrectClass(Object obj, Type type)
        {
            ConstructorInfo constructors = type.GetConstructor(System.Type.EmptyTypes);
            obj = constructors.Invoke(null);
            MethodInfo helloWorld = type.GetMethod("helloWorld");
            helloWorld.Invoke(obj, null);
        }
        static void Main(string[] args)
        {
            Type type = typeof(Class2);
            callCorrectClass(new Object(), type);
        }
    }
}
person Jaime Garcia    schedule 25.11.2008

То, что вы пытаетесь сделать, это динамический состав. Этого нет в С#.

Вы можете попробовать одно из следующих действий:

  • Объявите члены, которые вы хотите использовать в базовом классе или интерфейсе, и приведите к ним.
  • Используйте Generics, как в примере кода Zachary Yates:

    void GenericFunction<T>(Object obj) where T : class 
    {
      obj.someContainer.Add(1) as T;
    }
    
person Dirk Vollmar    schedule 25.11.2008