2009-06-13 13 views
1

私はC#の完全な初心者ですので、これが奇妙に見える場合は私を許してください。 C#サブクラスから詳細を取得する

は、私は私の問題

namespace Klasasafn 
{ 
    public abstract class vefHlutur 
    { 
     public abstract List<String> columnNames(); 
     public abstract List<String> toStringList(); 
    } 
} 

//Here is an object that inherits from this abstract class:

namespace Klasasafn 
{ 
    [Table(Name="Users")] 
    public class User: vefHlutur 
    { 
     public override List<String> columnNames() 
     { 
      List<String> p = new List<String>(); 
      p.Add("Nafn"); 
      p.Add("Email"); 
      p.Add("Lýsing"); 
      return p; 
     } 
     public override List<String> toStringList() 
     { 
      List<String> p = new List<String>(); 
      p.Add(name); 
      p.Add(email); 
      p.Add(descr); 
      return p; 
     } 
    ... more stuff here 
    } 

} 

//And here is the code I'm trying to run, Item, User and Category all inherit from vefHlutir:

List<Klasasafn.Item> hlutir; 
List<Klasasafn.User> notendur; 
List<Klasasafn.Category> flokkar; 
void Page_Init(object sender, EventArgs e) 
{ 
    hlutir = Fac.getItemList(); 
    notendur = Fac.getUserList(); 
    flokkar = Fac.getCategoryList(); 

    prenta(notendur, Table1); 
} 

protected void Page_Load(object sender, EventArgs e) 
{ 

} 
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) 
{ 

} 
protected void Button1_Click(object sender, EventArgs e) 
{ 
    if (DropDownList1.SelectedIndex == 0) 
    { 
     prenta(notendur, Table1); 
    } 
    else if (DropDownList1.SelectedIndex == 1) 
    { 
     prenta(hlutir, Table1); 
    } 
    else 
     prenta(flokkar, Table1); 
} 
private void prenta(List<vefHlutur> foo, Table f) 
{ 
    List<String> columnNames = foo[0].columnNames(); 
    TableRow tRow1 = new TableRow(); 
    f.Rows.Add(tRow1); 
    foreach (String i in columnNames) 
    { 
     TableCell columnNameCell = new TableCell(); 
     tRow1.Cells.Add(columnNameCell); 
     columnNameCell.Controls.Add(new LiteralControl(i)); 
    } 
    foreach (vefHlutur j in foo) 
    { 
     TableRow tRow = new TableRow(); 
     f.Rows.Add(tRow); 
     List<String> töfluHlutir = j.toStringList(); 
     foreach (String k in töfluHlutir) 
     { 
      TableCell tCell1 = new TableCell(); 
      tRow.Cells.Add(tCell1); 
      tCell1.Controls.Add(new LiteralControl(k)); 
     } 
    } 
} 

vefHlutir と呼ばれる私は、メソッドprentaを使用することができないということである抽象クラスを持っています。

私は常にこれらのエラーを取得:「Forsíða.prenta(System.Collections.Generic.List、System.Web.UI.WebControls.Table)」の最良のオーバーロードされたメソッドの試合は、いくつかの無効な引数を持っている1

エラー

エラー2引数 '1':私はこの問題を解決するにはどうすればよい「System.Collections.Generic.List

に 'System.Collections.Generic.List' から変換することはできませんか?

+0

これを機能させる方法があります。私のポストを参照してください。 – johnnycrash

答えて

8

問題は、C#でList<ParentClass>のメソッドを入力したときにタイプList<ChildClass>を使用できないことです。このタイプの変換は共分散と呼ばれ、4.0まではC#では使用できず、その後はインターフェースやイベントでのみ使用できます。

あなたができることは、メソッドを汎用化して制約を追加することです。

private void prenta<T>(List<T> foo, Table f) 
    where T : vefHlutur 
{ 
    ... 
} 

何このコードはそのprentaがTであるか、またはタイプvefHluturからderivecsどのような場合のための最初のパラメータとしてList<T>を受け入れる言ってやっています。また、タイプTを、メソッド、プロパティなどの呼び出しに関してvefHlutur型であるかのように扱うこともできます。これにより、シナリオが機能するようになります。

+0

ありがとう、それは私を助けてくれました! :) – Haffi112

0

キャストを行う方法があります。少し安全でないコード!この投稿を恐れてはいけません。そのほとんどが動作することを示すテストコード。すべての作業はここに起こる:

static unsafe List<A> CastBasAIL(List<B> bIn) { 

    DynamicMethod dynamicMethod = new DynamicMethod("foo1", typeof(List<A>), 
    new[] { typeof(List<B>) }, typeof(void)); 
    ILGenerator il = dynamicMethod.GetILGenerator(); 
    il.Emit(OpCodes.Ldarg_0);      // copy first argument to stack 
    il.Emit(OpCodes.Ret);       // return the item on the stack 
    CCastDelegate HopeThisWorks = (CCastDelegate)dynamicMethod.CreateDelegate(
    typeof(CCastDelegate)); 

    return HopeThisWorks(bIn); 

} 

このソリューションでは、限り、あなたはキャストしようとしている事は、あなたがそれをキャストしているものと同じインスタンスフィールドのレイアウトを持っているとして働く(相続の状況はよく働きます)。注:Listに共変量の状況でベースタイプを作成しようとすると、タイプミスマッチエラーが発生することがあります。これを実行した後にテストしてください。

私はこのために純粋に謝罪しますが、私は回復するc/C++ vb/aseemblyプログラマーです!

namespace Covariant { 

    class A { 
    public virtual string Name() { return "A"; } 
    } 

    class B : A { 
    public override string Name() { return "B"; } 
    } 

    delegate List<A> CCastDelegate(List<B> b); // be used in the cast 

    class Program { 

    static unsafe List<A> CastBasAIL(List<B> bIn) { 

     DynamicMethod dynamicMethod = new DynamicMethod("foo1", typeof(List<A>), new[] { typeof(List<B>) }, typeof(void)); 
     ILGenerator il = dynamicMethod.GetILGenerator(); 
     il.Emit(OpCodes.Ldarg_0);      // copy first argument to stack 
     il.Emit(OpCodes.Ret);       // return the item on the stack 
     CCastDelegate HopeThisWorks = (CCastDelegate)dynamicMethod.CreateDelegate(typeof(CCastDelegate)); 

     return HopeThisWorks(bIn); 

    } 

    static void Main(string[] args) { 

     // make a list<B> 
     List<B> b = new List<B>(); 
     b.Add(new B()); 
     b.Add(new B()); 

     // set list<A> = the list b using the covariant work around 
     List<A> a = CastBasAIL(b); 

     // at this point the debugger is miffed with a, but code exectuing methods of a work just fine. 
     // It may be that the debugger simply checks that type of the generic argument matches the 
     // signature of the type, or it may be that something is really screwed up. Nothing ever crashes. 

     // prove the cast really worked 
     TestA(a); 

     return; 

    } 

    static void TestA(List<A> a) { 

     Console.WriteLine("Input type: {0}", typeof(List<A>).ToString()); 
     Console.WriteLine("Passed in type: {0}\n", a.GetType().ToString()); 

     // Prove that A is B 
     Console.WriteLine("Count = {0}", a.Count); 
     Console.WriteLine("Item.Name = {0}", a[0].Name()); 

     // see if more complicated methods of List<A> still work 
     int i = a.FindIndex(delegate(A item) { return item.Name() == "A"; }); 
     Console.WriteLine("Index of first A in List<A> = {0}", i); 
     i = a.FindIndex(delegate(A item) { return item.Name() == "B"; }); 
     Console.WriteLine("Index of first B in List<A> = {0}\n", i); 

     // can we convert a to an array still? 
     Console.WriteLine("Iterate through a, after converting a to an array"); 
     foreach (var x in a.ToArray()) 
     Console.WriteLine("{0}", x.Name()); 

    } 
    } 
} 
関連する問題