Yapmam gereken şey şu:Bir değişkeni başka bir değişkende depolanmış bir türe dökmek mümkün mü?
object foo = GetFoo();
Type t = typeof(BarType);
(foo as t).FunctionThatExistsInBarType();
Böyle bir şey yapılabilir mi?
Yapmam gereken şey şu:Bir değişkeni başka bir değişkende depolanmış bir türe dökmek mümkün mü?
object foo = GetFoo();
Type t = typeof(BarType);
(foo as t).FunctionThatExistsInBarType();
Böyle bir şey yapılabilir mi?
Hayır, yapamazsınız. C#, duck typing'u uygulamıyor.
Bir arabirim uygulayıp ona yayın yapmalısınız.
(Ancak bunu yapmak için girişimleri vardır. Örnek için Duck Typing Project bakın.)Evet yapabilirsin. GvS'nin cevabına bakın :-) –
Hala arayüzü (bu durumda IConvertible) uygulamanız ve önceden türetilmekte olan türü bilmeniz gerekiyor. – Quassnoi
Bu cevabı kabul edildi olarak işaretledim, çünkü Quassnoi'nin tavsiyesini kullandım ve ona bir arayüz hazırladım, ama GvS'nin ve shuggycouk'un cevapları da harika. –
Sen Convert.ChangeType yöntemi kullanabilirsiniz.
object foo = GetFoo();
Type t = typeof(string);
string bar = (string)Convert.ChangeType(foo, t);
Bu, yalnızca nesne IConvertible – Quassnoi
uygularsa kullanışlıdır, yalnızca bir örnek olarak dizeyi kullandım. Sorun hedef türünü bilmiyorum, bu yüzden xyz bar = (xyz) Convert.Change ... cast yapamıyorum. –
Convert.ChangeType, dönüştürme değil. yani belirtilen tipte yeni bir nesne yaratmak. ICollection söylemek için dökmek istiyorsanız bu işe yaramaz. – Hoots
Orijinal soru derleme zamanında bilinen ancak değişken bildirmek zaman sol tarafta tanımlanmış bir dize sahip olduğuna dikkat edilmeyen bir türü olarak bir değişken tedavi etmek sormak içinde hatalıydı. C# 3,5'den itibaren statik olarak yazılmıştır.
kez dinamik Böyle bir şey yapabileceğini daha mevcuttur: tip ne olduğunu bilmiyorum için
dynamic foo = GetFoo();
foo.FunctionThatExistsInBarType();
ama bunu her zaman) (Örnek yöntemi FunctionThatExistsInBarType destekleyeceğini biliyorum; Şimdilik yansıma (veya aynı şeyden çok ama aynı zamanda daha pahalı ve daha pahalı olan kod genini) kullanmak zorundasınız.
// 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);
Dize türü sadece bir örnekti (iyi değil); Kod snippet'ini düzenledim, şimdi umuyoruz. –
Doğru - bunun için (ön dinamik) yansımayı kullanmalısınız. Bunu – ShuggyCoUk
Eğer derleme sırasında gerekli tüm türlerini biliyor koşuluyla, duck typing (çeşit) mümkündür:
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)"; }
}
Çıktı: Eğer bir sürü uygulayan sonunda ise
Dostuff(Foo foo)
Dostuff(Bar bar);
DoStuff(object fb);
Temelde aynı şeyi yapan yöntemler, bir arayüzün uygulanmasını düşünün. dinamikleri C# eklendi yana
Uh hesaba katmak için düzenleyeceğim .. Dört yıl sonra .. Oh iyi. –
Bu, ördek yazmıyor. Bu polimorfizmdir ('DoStuff' işlevine uygulanır). –
, biz bu şekilde yapabiliriz düşünüyorum:
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));
}
}
Bu, diğer çözümlerin olmadığı bir çekicilik gibi çalıştı. – BrotherOdin
Mükemmel, teşekkürler! – Stark
bunu size son satırında eşitleri sol tarafında istediğiniz bir dizesi olduğunu nasıl anlarsınız örneğiniz Başka bir deyişle, "object bar = (object) foo" yu kullanamayacağınız anlamına gelen çubukla ne yapacaksınız? ? –
Yapamam, string sadece bir örnekti. Snippet'i düzenledim. –