English 中文(简体)
抽象函数和数据类型 -- -- 是否有优雅的方法做到这一点?
原标题:Abstract functions and data types -- is there any elegant way to do this?
  • 时间:2012-05-23 22:43:33
  •  标签:
  • c#
  • generics

我有一个庞大的天体大家族, 全部来自单亲家庭。 这些天体都知道如何辨别它们是否已经修改过, 但我也需要看看是否已经修改过一个天体的新实例, 和我记忆中已经修改过的对象相比( 测试是否在编辑该天体时有其他人更新过数据库 ) 。

结果是,每个儿童阶层都必须采用同样的方法:

public new bool Changed()
{
    return Changed(this);
}

这真的粘住了我的阴毛,但我看不到任何办法,因为真正的工作需要用一个函数来完成,而这个函数需要的参数与它所处的类别相同——因此它不可能是虚拟的。 (当然,我可以定义它,它可以每次带父子并抛出它,但这样比较功能就接受树上的任何物体,而不仅仅是正确的物体,它需要每个例子的守卫代码,同样是丑陋的东西。 )

这当然有用 但我不喜欢丑陋的代码

更新: 至于 changed 函数,每个对象在装入时保留其状态的副本。

问题回答

只要基本类为 abstract , 您可以做类似的事情 :

abstract class Base
{
    public abstract bool Changed<T>(T obj) where T : Base;

    public bool Changed()
    {
        return Changed(this);
    }
}

class Subclass : Base
{
    public override bool Changed<Subclass>(Subclass obj)
    {
        // Do stuff here
    }
}

基本结构:

public abstract class Base<T> where T : Base<T>
{
    public T Original { get; private set; }

    public abstract bool Changed(T o);

    public bool Changed()
    {
        return this.Changed(Original);
    }
}

public class DerivedA : Base<DerivedA>
{
    public override bool Changed(DerivedA o)
    {
        throw new NotImplementedException();
    }
}

public class DerivedB : Base<DerivedB>
{
    public override bool Changed(DerivedB o)
    {
        throw new NotImplementedException();
    }
}

虽然它有其阴谋(reability),但在这种情况下可能是正确的选择,因为在古典动物/Dog/Cat意义上,你的问题不是类型保护,而是代码共享。

为防止出现这种情况:

public class DerivedC : DerivedB
{
}
new DerivedB().Changed(new DerivedC()); // compiles

您可以密封 DerivedB

或者你可以继续疯狂(我建议不要这样,绝对不能超过这个水平):

public abstract class DerivedE<T> : Base<DerivedE<T>> where T : DerivedE<T>
{
}

public class DerivedF : DerivedE<DerivedF>
{
}

public class DerivedG : DerivedE<DerivedG>
{
}

new DerivedF().Changed(new DerivedG()); // does not compile
new DerivedF().Changed(new DerivedF()); // does compile

http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx” rel=“nofollow”。我从文章中得到灵感,他讨论了阴谋和主张。

EDIT:清洁清洁,根据评论调整

答案和迷你科技一样, 所以他应该得到信用, 但是在这个例子中, SubslevelA的变迁 通过投给完全命名的阶级, 可以看到它的属性。

namespace ConsoleApplication1
{

    abstract class Base 
    {     
        protected abstract bool Changed<T>(T obj) where T : Base;      
        public bool Changed()     
        {         
            return Changed(this);     
        }

        public String PropBase { get; set; }
    }  

    class SubclassA : Base 
    {
        public String PropA { get; set; }

        protected override bool Changed<SubclassA>(SubclassA obj)     
        {
            ConsoleApplication1.SubclassA myInstance = obj as ConsoleApplication1.SubclassA;
            // Now can see PropA
            myInstance.PropA = "A";
            return true;
        }


    }

    class SubclassB : Base
    {
        protected override bool Changed<SubclassB>(SubclassB obj)
        {
            // can t see prop B here 
            // obj.PropB = "B";
            return true;
        }

        public String PropB { get; set; }
    } 


    class Program
    {
        static void Main(string[] args)
        {

            SubclassB x = new SubclassB();

            x.Changed();

            Base y = new SubclassA();

            y.Changed();
        }
    }
}




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签