2012-04-09 5 views
6

Böyle bir arayüze sahip. Yukarıdaki arabirimini uygulamak DEĞIL bir temel sınıfC# arayüzünde T Tipi nasıl dönülür? işte ben başarmak çalıştığım şey,</p> <pre><code>public interface IUser{ //some properties here T ToDerived(User u); } </code></pre> <p>Ben gelişimini arayüz yeniyim:

public class User 

sahip olacaktır. Sonra SalesUser sınıfında Türetilmiş sınıf I ToDerived için işlevini yazmak istiyorum

SalesUser : User, IUser 
{ 
    //no properties needed because they exist in the User class 

    SalesUser ToDerived(User u) 
    { 
     //code for converting a base User to a derived SalesUser 
    } 
} 

(Kullanıcı u) sahip olacak, fakat arayüzde, ben ToDerived yöntem bildirimi olarak bu tanımlamaya nasıl bilmiyorum Şu anda arayüzde var derleme değil.

Umarım bu mantıklıdır. İstediğin bu, ama genel tür User veya ondan devralan sağlamak için arabirimde bir genel tür sınırlaması eklendi

+1

[Buradan] (http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx), Eric'in bu soruyla ilgili bir blogun bağlantısıdır. Bu, aşağıdaki cevaba çok benzeyen bir örneği ve bu tasarım mekanizmasını kullanmanın tuzaklarını da içerir. – Servy

cevap

14
public interface IUser<T> where T : User 
{ 
    //some properties here 

    T ToDerived(User u); 
} 

SalesUser : User, IUser<SalesUser> 
{ 
    //no properties needed because they exist in the User class 

    SalesUser ToDerived(User u) 
    { 
     //code for converting a base User to a derived SalesUser 
    } 
} 

emin değilim.

+0

Beni bunun üstüne çektim, ama 'T: User' yerine ben ekleyebilirim. –

+0

@JimSchubert - Bunu düşündüm ve yorum yaparken ekledim;) – Oded

+0

sen beni iki kez yendin :( –

0

Bir arabirimin, herhangi bir uygulama sağlamadan bir sınıfı ve üyelerini tanımladığını unutmayın, ancak bir arabirim oluşturabilir ancak arabirimin uygulama sınıfına sahip olması gerekir.

+0

Bu soruya nasıl cevap veriyor? – Oded

+0

SalesUser sınıfında ToDerived (Kullanıcı u) işlevini yazmak istiyorum, ancak arabirimde bunu ToDerived yöntem bildirimi olarak nasıl tanımlayacağımı bilmiyorum, yanlış mı bilmiyorum. –

3

Oded yanıtı, derleme sorununu çözerek arabirimi karşılayan ToDerived yöntemini tanımlamanıza olanak tanır. Ancak, yorumda belirttiğim gibi, bunun en iyi uygulama olduğundan emin değilim.

İçinde bulunduğum temel sorun, normal olarak statik bir bağlamda bunun gibi dönüştürme yöntemlerinin gerekli olmasıdır. SalesUser örneğiniz yok; Birini istiyorsanız ve bir Kullanıcı var, bu nedenle yöntemi statik bağlamda (SalesUser.ToDerived(myUser)) çağırırsınız ve bir SalesUser (yöntem daha uygun olarak FromUser() veya benzeri olarak adlandırılır) alırsınız. Arabirimde belirttiğiniz yöntem, bir Kullanıcı'yı SalesUser'a dönüştürmek için zaten bir SalesUser'a sahip olmanızı gerektirir. Önceden var olan bir SalesUser'a ihtiyaç duyacağınız düşünebildiğim tek durum bir "kısmi klon" için; Yöntemi çağırdığınız SalesUser içinden ve içinden geçen Kullanıcıdan bilgileri kullanarak yeni bir SalesUser örneği oluşturuyorsunuz. Diğer tüm durumlarda, bir SalesUser'a (söz konusu statik olması gereken dönüşümler) gerek duymazsınız veya bir Kullanıcıya (yeni bir örnek oluşturan bir "klon" veya "derin kopya" yöntemine ihtiyacınız yoktur. yöntemi çağırdığınız örnekle aynı veri). Ayrıca, sınıfınızın tüketicileri, bir Kullanıcıdan bir SalesUser'a dönüştürme işlemini gerçekleştirmek için ToDerived() yöntemini çağırmaları gerektiğini bilmelidirler. Normalde, bir C# programcı açık veya örtülü bir dönüşüm kullanılabilir olması beklenir:

:

public class SalesUser 
{ 

    public static explicit operator (User user) 
    { 
     //perform conversion of User to SalesUser 
    } 

} 

//the above operator permits the following: 
mySalesUser = (SalesUser)myUser; 

... YA, bir dönüşüm operatörü başarısız, tek bir kullanıcı kullanarak bir SalesUser inşa edebilmek için beklenir

public class SalesUser:IUser 
{ 
    public SalesUser(User user) 
    { 
     //initialize this instance using the User object 
    } 
} 

//the above allows you to do this: 
mySalesUser = new SalesUser(myUser); 

//and it also allows the definition of a method like this, 
//which requires the generic to be an IUser and also requires a constructor with a User 
public void DoSomethingWithIUser<T>(User myUser) where T:IUser, new(User) 
{ 
    //...which would allow you to perform the "conversion" by creating a T: 
    var myT = new T(myUser); 
} 

Artık, statik üyeler arabirim tanımlarını karşılamıyor ve arabirimler statik üyeleri veya yapıcı imzalarını tanımlayamıyor. Bu bana, IUser arabiriminin dönüştürme yöntemini tanımlamaya çalışmaması gerektiğini söyler; bunun yerine, bir tür bir IUser'e gereksinim duyan yöntemler basitçe bunu belirleyebilir ve kullanıcı, kendi kendine dönüşebileceğini bilmesi gereken uygulama olmadan gerekli bir uygulamayı sağlayabilir.

+0

Haklısınız, Oded sorunu çözdü ve sorumu tam olarak aradığım şekilde yanıtladı. Bununla birlikte, bu konudaki açıklamanızı ve bu tasarım modelini neden kullanmamam gerektiğini, çünkü bu özel yöntemin tipik olarak statik bir yöntem olduğunu kabul ediyorum (ki buna katılıyorum). Örneğinizi oluşturmaya çalıştığımda, temel Kullanıcı sınıfını devralması için SalesUser sınıfına ihtiyacım olduğunu lütfen unutmayın. Genel sınıf SalesUser: Kullanıcı, IUser Bunu yapmaya çalıştığımda, açık yönteminiz çalışmaz. "bir taban sınıfına veya kullanıcı sınıfından kullanıcı tanımlı dönüşümlere izin verilmiyor." – jaressloo

+0

Yapıcı tabanlı "dönüşüm" hala çalışmalıdır. – KeithS

+0

Evet, yapıcı tabanlı sürüm şimdilik almak için tercih edilen yoldur. Temel Kullanıcıdan türetilmiş SalesUser ürününe açık bir dönüşüm sağlamak için diğer yolu anlamaya çalışın. Yardım ettiğin için teşekkür ederim. – jaressloo