我發現了一個奇怪的行爲爲泛型和重載方法。看來, 泛型的重載機制不起作用:.net通用錯誤?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestGeneric1
{
class Program
{
class B
{
public void f()
{
Console.WriteLine("B.f() called!");
}
}
class D : B
{
public void g()
{
Console.WriteLine("D.g() called!");
}
}
class H
{
public static void over(B b)
{
b.f();
}
public static void over(D d)
{
d.g();
}
}
class Gen<T> where T : B
{
T _item;
public Gen(T item)
{
_item = item;
}
public void test()
{
H.over(_item);
}
}
class Gen2
{
public static void test<T>(T item) where T : B
{
H.over(item);
}
}
static void Main(string[] args)
{
B b = new B();
D d = new D();
Console.WriteLine("Direct Call");
H.over(b); // OK!
H.over(d); // OK;
Console.WriteLine("Call via Generics");
Gen<B> testGenB = new Gen<B>(b);
Gen<D> testGenD = new Gen<D>(d);
testGenB.test(); // OK
testGenD.test(); // Wrong !!!
Console.WriteLine("Call via Generics 2 chance...");
Gen2.test<B>(b); // OK !
Gen2.test<D>(d); // wrong
Console.ReadKey();
}
}
}
有沒有能夠解釋這個任何機構? 是否有解決方法。
我嘗試做的是實現一個通用的訪問者類(訪問者模式)與通用。 TIA
補充:
這個問題我真的盡力解決是雙重分派的問題。 假設你想要寫的,你必須 精靈之間處理衝突的一個小遊戲引擎:
interface ISprite
{
void Hit(ISprite sprite);
}
abstract class Sprite : ISprite
{
public void Hit(ISprite sprite)
{
Hit(sprite as Sprite);
}
}
class SpriteA : Sprite
{
}
class SpriteB : Sprite
{
}
我要做的就是實現這樣
interface IVisitorSprite
{
void Visit(SpriteA item);
void Visit(SpriteB item);
}
abstract class Sprite : ISprite
{
protected abstract void Accept(IVisitorSprite visitor);
}
class SpriteA : Sprite
{
protected override void Accept(IVisitorSprite visitor)
{
visitor.Visit(this);
}
}
class SpriteB : Sprite
{
protected override void Accept(IVisitorSprite visitor)
{
visitor.Visit(this);
}
}
訪問者模式的命中方法調用訪問模式兩次:
abstract class Sprite : ISprite
{
public void Hit(ISprite sprite)
{
Hit(sprite as Sprite);
}
public void Hit(Sprite sprite)
{
HitResoverBuilder hitBuilder = new HitResoverBuilder();
Accept(hitBuilder);
sprite.Accept(hitBuilder.HitResolver);
}
protected abstract void Accept(IVisitorSprite visitor);
}
class HitResoverBuilder : IVisitorSprite
{
public IVisitorSprite HitResolver { get; private set; }
void IVisitorSprite.Visit(SpriteA item)
{
HitResolver = new HitResolver<Penguin>(item);
}
void IVisitorSprite.Visit(SpriteB item)
{
HitResolver = new HitResolver<Flame>(item);
}
}
class HitResolver<T> : IVisitorSprite
{
public HitResolver(T spriteOne)
{
_spriteOne = spriteOne;
}
T _spriteOne;
void IVisitorSprite.Visit(SpriteA item)
{
HitHelper.Hit(_spriteOne, item);
}
void IVisitorSprite.Visit(SpriteB item)
{
HitHelper.Hit(_spriteOne, item);
}
}
class HitHelper
{
public static void Hit(SpriteA a, SpriteB b)
{
// manage hit between spriteA and SpriteB
}
public static void Hit(SpriteB b, SpriteA a)
{
Hit(a,b);
}
public static void Hit(SpriteB b, SpriteB b1)
{
// manage hit between 2 SpriteB
}
public static void Hit(SpriteA a, SpriteA a1)
{
// manage hit between 2 SpriteA
}
}
你是什麼意思的「不工作」和「錯誤的」?你期望什麼行爲,你看到了什麼行爲? – 2011-04-08 13:03:04
你應該包括輸出。我可以猜測問題是什麼,但不能確定。 – 2011-04-08 13:03:56
將D.g類更改爲「override f」,並使B.f virtual成爲可能,它將按預期工作。哦和H.over(D)電話需要更改爲d.f()。 – asawyer 2011-04-08 13:11:52