繁体   English   中英

C#模仿Java通用?

[英]C# mimic Java generic?

在Java中,这是有效的:

class Class1<T extends OtherType> { T t; ... }

//Inside other class that has no relation to Class1
private Class1 class1; //No type needed

public void someOtherFunction (Class1 class1) //Works  
{  
    this.class1 = class1; //May warn about invalid type casting
    class1.someFunction();
}

C#在相同条件下需要一个类型:

class Class1<T> where T : OtherType { T t; ... }

//Inside other class that has no relation to Class1
private Class1<TYPE DEMANDED> class1; //I don't know generic what type, and honestly it doesn't matter.

public void someOtherFunction (Class1 class1) //This is the definition I want to use, but C# Demands a type to class1 
public void someOtherFunction<T> (Class1<T> class1) where T : OtherType //C# Demands a type to class1 so I must specify a T
{  
    this.class1 = class1;
    class1.someFunction();
} //This function is valid but then it still needs the type to store it.

有没有办法省略这种类型? 没有必要知道类型,为什么需要它? 我不能创建类型为OtherType Class1 ,因为泛型的要点是具有扩展OtherType基础的未知类型。 我可以解决它,但这绝对是最有效的解决方案,如果它是Java,我将不得不为多个对象输入一次帧,如果这不起作用,我担心会快速加起来。

每个请求的实际代码:

public abstract class Weapon { ... }

public abstract class WeaponProxy<T> : MonoBehaviour where T : Weapon
{
    protected T weapon;

    public virtual void Update()
    {
        ...
        holdingPlayer = player.getHUD().showPickup(player, this);
        ...
    } 

public abstract class GunProxy<T> : WeaponProxy<T> where T : Gun
{

}



public abstract class Weapon
{
    private string weaponName;
    private string weaponIdentifier;
    private Player isHolding;

    public string getWeaponName () { return weaponName; }
    public Weapon(string weaponName, string weaponIdentifier)
    {
        this.weaponName = weaponName;
        this.weaponIdentifier = weaponIdentifier;
    }

    public void playerPickedUp (Player player)
    {
        this.isHolding = player;
    }

    public void playerDropped ()
    {
        this.isHolding = null;
    }
}

public class Gun : Weapon
{
  ...
}

public class HUD : MonoBehaviour
{
    private WeaponProxy weapon; //C# Needs a type. Underlined in red as error   

    public PlayerProxy showPickup<T> (PlayerProxy player, WeaponProxy<T> weapon) where T : Weapon
    {
        this.weapon = weapon;
        textPickupWeapon.text = "Hold '" + player.getPlayer().getControlScheme().getControlText(ControlScheme.CONTROLS.Interact) + "' to pick up " + weapon.getWeapon().getWeaponName();
        ...
    }
}

你的java代码是“有效的”,因为java中的所有泛型实际上都是非泛型的,因为java的泛型只是编译时的技巧,没有任何运行时支持。

对于java运行时,类型A<T>实际上是A ,没有类型参数,因为java运行库实际上根本不支持泛型。

相比之下,.NET CLR内置了对运行时泛型类型的支持,因此它区分了类型A和泛型类型A<T>

在C#中,如果您想要类型为Class1的非泛型版本,只需声明它:

class Class1
{
    //Whatever members that don't require a type parameter,

    void SomeFunction() { /* ... */ } // Please use proper casing.
}

那么,如果你需要这个类的通用版本:

class Class1<T>: Class1
{
    T Content { get; set; }
}

现在,您将能够在任何其他类中拥有类型Class1的成员

class Example
{
    Class1 instance; // Valid

    public void someOtherFunction (Class1 class1) //Works  
    {  
        this.instance = class1; //Does not warn about anything because this is type safe.
        class1.SomeFunction(); // Works

        var content = class1.Content // Compile Error: type class1 does not have such member "Content"
    }
}

请注意C#方法如何更安全,如果您使用的是非泛型版本,则只能访问非泛型版本中定义的类成员,并且不需要类型参数。 相比之下,java完全不安全,并且由于在泛型中缺乏真正的类型安全性而可能产生可怕的运行时错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM