Вот что мне нужно сделать:
object foo = GetFoo();
Type t = typeof(BarType);
(foo as t).FunctionThatExistsInBarType();
Можно ли что-то подобное сделать?
Вот что мне нужно сделать:
object foo = GetFoo();
Type t = typeof(BarType);
(foo as t).FunctionThatExistsInBarType();
Можно ли что-то подобное сделать?
Нет, ты не можешь. C # не поддерживает утиный ввод.
Вы должны реализовать интерфейс и привести к нему.
(Однако попытки сделать это есть. Посмотрите Duck Typing Project для примера.)
Вы можете использовать метод Convert.ChangeType.
object foo = GetFoo();
Type t = typeof(string);
string bar = (string)Convert.ChangeType(foo, t);
var bar = (string) foo;
будет делать то же самое ... вы не использовали Convert.ChangeType
, но вы использовали тот момент, когда использовали (string)...
- person derHugo; 12.07.2018
Поскольку в C # была добавлена динамика, я думаю, что мы можем сделать это следующим образом:
class Program {
static void Main(string[] args) {
List<int> c = new List<int>();
double i = 10.0;
Type intType = typeof(int);
c.Add(CastHelper.Cast(i, intType)); // works, no exception!
}
}
class CastHelper {
public static dynamic Cast(object src, Type t) {
var castMethod = typeof(CastHelper).GetMethod("CastGeneric").MakeGenericMethod(t);
return castMethod.Invoke(null, new[] { src });
}
public static T CastGeneric<T>(object src) {
return (T)Convert.ChangeType(src, typeof(T));
}
}
В вашем исходном вопросе был недостаток в том, что вы просили рассматривать переменную как тип, который неизвестен во время компиляции, но обратите внимание, что у вас есть строка, определенная с левой стороны, когда вы объявляете свою переменную. C #, начиная с версии 3.5, имеет статическую типизацию.
Как только динамический станет доступен, вы можете сделать что-то вроде этого:
dynamic foo = GetFoo();
foo.FunctionThatExistsInBarType();
Когда вы не знаете, что это за тип, но знаете, что он всегда будет поддерживать метод экземпляра FunctionThatExistsInBarType ();
на данный момент вы вынуждены использовать отражение (или генерацию кода, что на самом деле представляет собой то же самое, но сначала дороже, а позже - быстрее).
// any of these can be determined at runtime
Type t = typeof(Bar);
string methodToCall = "FunctionThatExistsInBarType";
Type[] argumentTypes = new Type[0];
object[] arguments = new object[0];
object foo;
// invoke the method -
// example ignores overloading and exception handling for brevity
// assumption: return type is void or you don't care about it
t.GetMethod(methodToCall, BindingFalgs.Public | BindingFlags.Instance)
.Invoke(foo, arguments);
Если вы знаете все необходимые типы во время компиляции, утиный ввод возможен (вроде):
class BarFoo {}
class Foo {}
class Bar {}
class Program
{
static void Main( )
{
var foo = new Foo( );
var bar = new Bar( );
var barfoo = new BarFoo( );
Console.WriteLine(DoStuff(foo));
Console.WriteLine(DoStuff(bar));
Console.WriteLine(DoStuff(barfoo));
}
static string DoStuff(Foo foo) { return "DoStuff(Foo foo)"; }
static string DoStuff(Bar bar) { return "DoStuff(Bar bar)"; }
static string DoStuff(Base fb) { return "DoStuff(object fb)"; }
}
Вывод:
Dostuff(Foo foo)
Dostuff(Bar bar);
DoStuff(object fb);
Если вы в конечном итоге реализуете множество методов, которые в основном делают то же самое, подумайте о реализации интерфейса.
DoStuff
).
- person Tomas Aschan; 24.10.2014