从Java到C# - Generic强制转换为BaseClass

时间:2014-08-08 17:02:10

标签: java c# generics

我目前在泛型方面存在问题。我想将现有的Java代码转移到c#中。任何人都可以告诉我,我怎样才能在c#中做到?

例如,我有一个名为module的类,它带有一个继承自basicdata的泛型参数。我想将许多这些对象添加到处理程序中,以便可以在单个方法中更新它们。

在java中我有这样的东西:

public class BasicData
{
}

public abstract class Modul<T extends BasicData> 
{
  T value;

  abstract void update(); // do something with the value
}

public class Handler
{
    LinkedList<Modul<?>> modulCollection = new LinkedList<Data<?>>();

    void add(Modul<?> m)
    {
        this.dataCollection.add(m);
    }

    void update(){
        for(Modul<?> d : this.modulCollection){
              d.update();
        }
    }
}

列表应该包含各种模块对象,其中value字段本身可以有各种类型,但它们都继承了BasicData。 我搜索了一会儿,但我只找到了异国情调的解决方案。有没有简单的方法在c#中做类似的事情?我不想改写我的整个设计。

起初我以为我可以在c#中声明这样的列表:

LinkedList<Modul<BasicData>> collection;

void add(Modul<BasicData> m)
{
     this.dataCollection.add(m);
}

然后添加如下所示的各种对象:

class DataImpl : Modul<int>
{
}

handler.add(new DataImpl());

但我发现你不能施放这个模块。 是否有解决办法做这样的事情?

提前谢谢, 米克

3 个答案:

答案 0 :(得分:2)

C#没有? Java具有的通配符机制 - What is the equivalent of Java wildcards in C# generics,因此没有针对此问题的直接原生解决方案。

可能的解决方案:

1。Modul使用基础非通用类或接口:

 public abstract class ModulBase : BasicData
 {
   abstract void update(); // do something with the value
 }

 public abstract class Modul<T> : ModulBase ...

public interface IUpdateable
{
    void Update();
}

public abstract class Modul<T> : BasicData, IUpdateable...

并使用它:

public class Handler
{
    LinkedList<IUpdateable> modulCollection = new LinkedList<IUpdateable>();

    void add<T>(Modul<T> m) // It is generic now
    {
        this.dataCollection.add(m);
    }

    void update(){
        foreach (IUpdateable d in this.modulCollection){
              d.update();
        }
    }
}

你的Handler.moduelCollection不再是这种方法的通用,但在任何情况下(即使在Java中)你都无法以简单的方式访问不同的泛型而不进行强制转换 - 这不是最好的处理放入一个集合的不同数据类型的方法。

答案 1 :(得分:1)

您可以在C#中尝试相同的内容,如下所示:

public abstract class Module<T> where T : BasicData
{

}

答案 2 :(得分:0)

我想我找到了一个解决方案。它有点使用别人和你所说的,并把它与这里没有提到的东西结合起来。

如果您有课程 Foo

class Foo {
    public virtual void Method1() {
        //Do something
    }

    public void Method2() {
        //Do something
    }
    //class code
}

现在,您有一个继承自 Foo

Bar
class Bar : Foo {
    public override void Method1() {
        //Do something
    }

    public new void Method2() {
        //Do something
    }
    //class code
}

如果您声明类 Bar 的变量并尝试将其转换为 Foo ,则完全可以接受并且您不会丢失任何数据。但是,下次要使用额外的属性,方法和变量时,需要将其转换回 Bar 。但是,如果普通成员是覆盖,它们的行为应该像是由 Bar 变量调用,否则,如果对象被克隆或向后转换,则公共成员的行为就像它们被调用一样通过 Foo 实例。

例如:

Bar myBar = new Bar();
Foo myFoo = myBar; //Now myFoo and myBar refer to the same memory address
Foo myFoo2 = myBar.Clone() as Foo; //myFoo2 and myBar do not refer to the same memory address

//These should do exactly the same thing because Method1 is an override
myBar.Method1();
myFoo.Method1();

//These should not do exactly the same thing unless Method2 was not changed in Bar
myBar.Method2();
myFoo.Method2();

//These should do exactly the same thing because Method1 is an override
myBar.Method1();
myFoo2.Method1();


//These should not do exactly the same thing unless Method2 was not changed in Bar
myBar.Method2();
myFoo2.Method2();

Bar myBarConvertedBack = (Bar)myFoo; //No data lost

现在回到这个问题。试试这个:

public abstract class Module<T> where T : BasicData {
    protected T value;

    public abstract void Update();

    public virtual T Value {
        get;
        set;
    }
}

public class Handler
{
    LinkedList<Modul<BasicData>> modulCollection = new LinkedList<Data<BasicData>>();

    pulic void Add(Modul<BasicData> m)
    {
        this.modulCollection.add(m);
    }

    public void Update() {
        foreach (Modul<BasicData> d in this.modulCollection)
              d.update();
    }
}

将此类视为 Module

中可能的派生类
public class Class1: Module<BasicData> {
    public Class1(BasicData val) {
        base.value = val;
    }

    public override void Update() {
        //Do something here
    }

    public override BasicData Value {
        get {
            return base.value;
        }
        set {
            base.value = value;
        }
    }
}

如果清楚,请参阅相关已链接 stackoverflow 中的更多案例。此外,如果我错了某地纠正我