2009-11-06 18 views
5
Hep böylece uygulayan sınıfın bir nesnesi döndüren bir yöntemi tanımlar C# bir arayüz yapmak istiyorum

:Bir uygulama sınıfını kendi türünde bir nesneyi döndürmeye zorlayabilir miyim?

public interface IParser { 
    IParser Parse(string s); 
} 

public class Parser : IParser { 
    public Parser Parse(string s) { 
     return new Parser(s); 
    } 
} 

Ben kendi türünde bir nesne döndürmek için bir uygulama sınıfıyla zorlayabilir miyim? Mümkünse nasıl olur? Yoksa buradaki cevap jenerik midir?

Not: kod sadece bir illüstrasyon, değil çalıştırmak gerekiyordu şeydir.

+0

Beni çok meraklı yaptık ... Eğer yaptıkları kaderimiz değil bir şey için arayüzleri kullanmaya çalışıyorsanız düşünüyorsun? Genel olarak, bir arabirimi tanımlama noktası, müşteri kodunun, belirli bir API'nin, o nesnenin somut tipini bilmeden veya bakımını yapmak zorunda kalmadan bir nesne üzerinde tanımlandığına güvenebileceği şekildedir. Bu, OOP'un en güçlü yanlarından biri. Bunu yaparak, yapmaya çalıştığınız şey nedir? –

+0

Eh, benim düşünce bu arayüze sahip olarak her zaman arabirimini uygulayan sınıflar bu yöntemi olacağı ve her zaman kendi türünü döneceğini inanabileceğimi oldu. Ama dediğiniz gibi, bu en iyi OO tasarımı olmayabilir ve bunun yerine arabirim türünü döndüren bir yöntem için onu terk edeceğim. – Cros

cevap

8

Jenerik cevaptır İşte.

public interface IParser<T> where T:IParser<T> { 
    T Parse(string s); 
} 

public class Parser : IParser<Parser> { 
    public Parser Parse(string s) { 
     return new Parser(s); 
    } 
} 
+0

İyi çalışma ... Sadece kodumu aynı şey için test ediyordum. +1 – jheddings

+0

Hemen deneyeceğim. – Cros

+0

Bu gibi genel arayüzü yaptığınızda, kullandığınız tür için bir belirteci olarak ISelection'ı kullandığınız her yerde T'yi belirtmeniz gerekir, örn. Şimdi sadece bir Liste yapamıyorum ama şimdi bir Liste > olmalıdır. Doğrumuyum? Sonra bu aradığım çözüm değil, ne yazık ki. – Cros

1

Evet ve bu the factory pattern olarak, sadece o genellikle bu örnek için, özel bir yapıcı kullanımı ile tamamlanmaktadır ve statik yöntemi dönen örneği yapıyor bilinmektedir:

public class Parser : IParser { 

    private Parser(string s) { 
     //Do something with s, probably store it in a field 
    } 

    public static IParser GetNewParser(string s) { 
     return new Parser(s); 
    } 
} 
+0

Ben anahtar ifade olduğunu düşünüyorum "... kendi türünde bir nesne döndürmek için bir uygulama sınıfıyla zorlamak ..." –

+0

Bu gerçekten bir 'evet/hayır' sorusu. Mümkünse bunun nasıl yapıldığını somut olarak bilmek istiyorum. – Cros

0

Bunu, Generics ile yapabilirsiniz, ancak büyük olasılıkla, arabirimin bir örneğini döndürmekle uğraşırdım. Sınıfın arayüzü uygulayacağından, bir örneğini döndürdüğünden, bu türün ve arabirimin de bir örneği olacağını unutmayın.

public class Parser : I Parser 
{ 
    public IParser Parser(string s) 
    { 
     return Parser(s); 
    } 
} 
5

Arabirim bildiriminde yok, no. Yönetmek gelebilecek en iyi jenerik ile geçerli:

public interface IParser<T> 
    where T: IParser<T> 
{ 
    T Parse(string s); 
} 

public class Parser 
: IParser<Parser> 
{ 
    public Parser Parse(string s) 
    { 
     return new Parser(s); 
    } 
} 

Bu değil kuvvet uygulaması kendi tip dönmek yok, ama en azından bunu yapmak için izin verir. Bu nedenle, IClonable arabirimi, belirli bir türden ziyade Clone yönteminden bir nesne döndürür.

---- Düzenleme ---- Bu soru üzerine hatırlamak

şey: Diyelim ki uygulama herhangi bir bilgiye sahip olmayan benim kod, bir IParser, ve kodunuzu döndüren diyelim Parse yöntemini çağırır. Döndürülmeyi bekleyen bir nesne olan IParser referansının somut türünü bilmeden hangi nesneyi iade etmeyi bekliyorsunuz? neden bunu yapmaya çalışıyorsun: Ben

+1

+1 talep edilen uygulamayı zorlamaz. Başka bir IParser uygulamasını kolayca iade edebilirsiniz. AFAIK, bu kontrolü dil seviyesinde uygulamak için hiçbir yol yoktur; Bu, ona ulaşacağınız en yakın şey. –

İlgili konular