Typecast для типа только из строкового представления имени типа - PullRequest
5 голосов
/ 15 апреля 2010
sTypeName = ... //do some string stuff here to get the name of the type

/*
The Assembly.CreateInstance function returns a type
of System.object. I want to type cast it to 
the type whose name is sTypeName.

assembly.CreateInstance(sTypeName)

So, in effect I want to do something like:

*/

assembly.CreateInstance(sTypeName) as Type.GetType(sTypeName);

Как мне это сделать? И что мне взять в левой части выражения присваивания, если предположить, что это C # 2.0. У меня нет ключевого слова var.

Ответы [ 3 ]

2 голосов
/ 15 апреля 2010

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

Assembly asm = Assembly.GetExecutingAssembly();
string classname = "MyNamespace.MyClass";
Type classtype = asm.GetType(classname);

// Constructor without parameters
IMyInterface instance = (IMyInterface)Activator.CreateInstance(classtype);

// With parameters (eg. first: string, second: int):
IMyInterface instance = (IMyInterface)Activator.CreateInstance(classtype, 
                        new object[]{
                            (object)"param1",
                            (object)5
                        });

Даже если у вас нет общего интерфейса, но вы знаете имя метода (в виде строки), вы можете вызывать свои методы следующим образом (очень похоже на свойства, события и т. Д.):

object instance = Activator.CreateInstance(classtype);

int result = (int)classtype.GetMethod("TwoTimes").Invoke(instance, 
                        new object[] { 15 });
// result = 30

Пример класса:

namespace MyNamespace
{
    public class MyClass
    {
        public MyClass(string s, int i) { }

        public int TwoTimes(int i)
        {
            return i * 2;
        }
    }
}
2 голосов
/ 30 ноября 2010

.

Определите универсальный метод в своем классе, и затем вы можете разыграть его следующим образом:

 public T Cast<T>(object obj)
 {
      return (T) obj;
 }

 string sTypename = "SomeClassName"; 
 MethodInfo cast = this.GetType().GetMethod("Cast");
 MethodInfo genericCast = cast.MakeGenericMethod(new Type[] { Type.GetType(sTypename) });
 Object castedValue = genericCast.Invoke(this, new object[] { instanceToBeCasted });

Но тогда я думаю, в чем смысл такого приведения, если вы не можете сохранить приведенное значение в переменной типа фактический , именно потому, что вы не знаете фактический тип во время писать код?

2 голосов
/ 15 апреля 2010

К сожалению, в .NET нет способа делать то, что вы хотите.

Возможные частичные решения:

  1. Если вы знаете тип во время компиляции (маловероятно, поскольку вы создаете его во время выполнения из строки), просто приведите к этому типу:

    YourType t = (YourType)Activator.CreateInstance(sTypeName);
    
  2. Если вы знаете, что все возможные типы будут реализовывать определенный, общий интерфейс, вы можете вместо этого привести к этому интерфейсу:

    IYourInterface i = (IYourInterface)Activator.CreateInstance(sTypeName);
    

Если вы не можете выполнить ни одно из перечисленных выше действий, то, к сожалению, вы застряли с object и отражением.

...