C# 在c中继承泛型#

C# 在c中继承泛型#,c#,.net,generics,inheritance,decorator,C#,.net,Generics,Inheritance,Decorator,我继承了一个很大的代码库,并试图在框架中实现一些新功能。基本上,为了以“正确”的方式完成,我必须修改框架的整个结构。因为我不是设计框架的人,也不是读心术的人,所以这样做可能不会发生(尽管我真的很想自己从头开始重新设计它) 所以为了做我想做的事,我尝试实现一个装饰模式。表明我下面所做的是完全正确的。然而,mono似乎不喜欢它;它抱怨当我声明happedCorator时,T不能派生自 请原谅这个过于简单化的例子,但它能让人明白重点 public class HappyObject { pub

我继承了一个很大的代码库,并试图在框架中实现一些新功能。基本上,为了以“正确”的方式完成,我必须修改框架的整个结构。因为我不是设计框架的人,也不是读心术的人,所以这样做可能不会发生(尽管我真的很想自己从头开始重新设计它)

所以为了做我想做的事,我尝试实现一个装饰模式。表明我下面所做的是完全正确的。然而,mono似乎不喜欢它;它抱怨当我声明happedCorator时,
T
不能派生自

请原谅这个过于简单化的例子,但它能让人明白重点

public class HappyObject
{
    public virtual void print()
    {
        Console.WriteLine ("I'm happy");
    }
}

public class VeryHappyObject : HappyObject
{
    public override void print()
    {
        Console.WriteLine ("I'm very happy");
    }

    public void LeapForJoy()
    {
        Console.WriteLine("Leaping For Joy!");
    }
}

public class SuperHappyObject : VeryHappyObject
{    
    public override void print()
    {
        Console.WriteLine ("I'm super happy!");
    }

    public void DieOfLaughter()
    {
        Console.WriteLine("Me Dead!");
    }
}

public class HappyDecorator<T> : T where T : HappyObject
{
    public string SpecialFactor { get; set; }

    public void printMe()
    {
        Console.WriteLine (SpecialFactor);
        print();
    }
}
公共类HappyObject
{
公共虚拟作废打印()
{
Console.WriteLine(“我很高兴”);
}
}
公共类VeryHappyObject:HappyObject
{
公共覆盖无效打印()
{
Console.WriteLine(“我很高兴”);
}
公众假期
{
控制台。WriteLine(“高兴得跳起来!”);
}
}
公共类超级应用程序对象:VeryHappyObject
{    
公共覆盖无效打印()
{
Console.WriteLine(“我非常高兴!”);
}
公共法律无效
{
控制台。WriteLine(“我死了!”);
}
}
公共类HappyCorator:T其中T:HappyObject
{
公共字符串特殊因子{get;set;}
public void printMe()
{
Console.WriteLine(特殊因素);
打印();
}
}
class类main类
{
公共静态void Main(字符串[]args)
{
HappedCorator obj=新的HappedCorator();
obj.SpecialFactor=Console.ReadLine();
对象printMe();
}
}

您正在将HappyDecorator键入T,但在该类中没有可使用的T实例

public class HappyDecorator<T> where T : HappyObject
{
    private readonly T _instance;

    public HappyDecorator(T instance)
    {
        _instance = instance;
    }

    public string SpecialFactor { get; set; }

    public void printMe()
    {
        Console.WriteLine(SpecialFactor);
        _instance.print();
    }
}

我想这就是你想要做的:

    public interface IhappyObject
    {
        void Print();
    }

    public class HappyObject : IhappyObject
    {
        private IhappyObject obj;

        public HappyObject(IhappyObject obj)
        {
            this.obj = obj;
        }

        public void Print()
        {
            obj.Print();
        }
    }

    public class VeryHappyObject : IhappyObject
    {
        public void Print()
        {
            Console.WriteLine("I'm very happy");
        }
    }

    public class SuperHappyObject : IhappyObject
    {
        public void Print()
        {
            Console.WriteLine("I'm super happy!");
        }
    }

    static void Main(string[] args)
    {
        HappyObject obj = new HappyObject(new SuperHappyObject());
        obj.Print();
    }

你有错误吗?或者它如何表现得不符合预期?这不是遵循装饰器模式的方法。obj obect应该在其构造函数中获得HappyDecorator。您不能继承泛型类型参数,这正是代码示例的错误消息所说的。你不明白其中的哪一部分?听起来你应该摆脱所有的错误,改用
System.Action
。创建类来保存这样的函数被称为“名词王国中的执行”,这是一种疾病,影响到大多数设计糟糕的古语言,如java,而C#有适当的功能来处理这一问题,而不必创建无休止的类层次结构。你不能继承
t
。要么继承
HappyObject
,要么注入并包装
T
。我会选择后者。
HappyDecorator
继承了OPs代码示例中的
T
,因此它是实例本身。除了语法不正确且不编译之外。那么它应该继承HappyObject吗?在这种情况下,泛型的优点就消失了。我知道它不是一种有效的语法。我希望你的回答能说明,在你提出解决方法之前:)第二个肯定不是我想要做的,对象必须以某种方式继承
HappyObject
,并且必须能够这样使用。第一个解决方案带来了一个问题,因为如果我将
VeryHappyObject
SuperHappyObject
传递给构造函数,我将无法访问这两个对象中包含的特殊字段。不幸的是,我的例子没有正确地反映这一点;我将对其进行编辑,使其更加清晰。放弃HappyDecorator类,将SpecialFactor和printMe移动到基类,然后创建您关心的正确实例怎么样?否则,decorator类将需要公开T,以便调用它的方法。我之所以没有选择传统的装饰模式,是因为我想避免显式包装方法。当然,实际的代码(我拒绝将这个讨厌的东西称为我自己的作品)比我提供的示例复杂得多。因此,例如,假设
VeryHappyObject
SuperHappyObject
的接口
ihappyObject
中没有包含参数。如果我正确地理解了您的实现,具体地说,假设他们分别有
LeapForJoy()
DieOfLaughter()
(但不是两者都有)。然后我必须在接口中定义这两个函数,这并不是我想要做的,因为事实上,这些对象比我想象的要复杂得多,这样做是一个真正的PITA。
public class HappyDecorator
{
    public string SpecialFactor { get; set; }

    public void printMe<T>(T instance) where T : HappyObject
    {
        Console.WriteLine(SpecialFactor);
        instance.print();
    }
}
        HappyDecorator obj = new HappyDecorator();
        obj.SpecialFactor = Console.ReadLine();
        obj.printMe(new HappyObject()); 
    public interface IhappyObject
    {
        void Print();
    }

    public class HappyObject : IhappyObject
    {
        private IhappyObject obj;

        public HappyObject(IhappyObject obj)
        {
            this.obj = obj;
        }

        public void Print()
        {
            obj.Print();
        }
    }

    public class VeryHappyObject : IhappyObject
    {
        public void Print()
        {
            Console.WriteLine("I'm very happy");
        }
    }

    public class SuperHappyObject : IhappyObject
    {
        public void Print()
        {
            Console.WriteLine("I'm super happy!");
        }
    }

    static void Main(string[] args)
    {
        HappyObject obj = new HappyObject(new SuperHappyObject());
        obj.Print();
    }