谈谈泛型要求子类必须继承自当前类的事情-后续

幽幽有悠悠呦 2018-04-13 11:17:26
对之前发布的帖子补充,之前的帖子 谈谈泛型要求子类必须继承自当前类的事情

用了几天后,发现不方便,引发了其他新的问题



//问题一:
//C#不能像java包结构一样,类不写public就是对其他包隐藏该类,C#没隐藏功能?还是我孤陋寡闻?
//C# 甚至还强制要求父类必须跟子类修饰符一致或者更大的可访问权限,好操蛋设计,我想对外隐藏父类都做不到,会被其他人直接实例化父类,SuperClass<T>满足了T,但是T已经不是this了。真的不能隐藏这个类吗?还是我孤陋寡闻?
public class SuperClass{

}

public class SuperClass<T> : SuperClass where T : SuperClass, new(){//无视掉new()约束吧。只是为了举例Instance需要用到而已
private static T m_Instance;

public static T Instance {
get{
if(m_Instance == null){
m_Instance = new T();
}
return m_Instance;
}
}


//
//问题二:T不能代表SuperClass<T>,跟我之前的帖子初衷不符合
// 假设个环境:
// 插件模式开发的话,不能用new实例化对象,而是被引擎实例化后,通知某个方法,当前以OnInstance模拟该环境
//
protected void OnInstance(){
m_Instance = this;//错误,此时。this已经跟T不是类型直接关系了。。。无法赋值。
//Instance 的返回类型是禁止从T改变成
}
}


public class A : SuperClass<A>{ }
public class B : SuperClass{ }

public class Test{
public void MyTest(){
A a = A.Instance;//这种通过
B b = B.Instance;//这种不通过。不存在这个属性。没法通过T直接限制为子类为自身类,因为父类也被要求SuperClass访问权限必须同SuperClass<T>一样,会被直接继承实例化,无法有效管理
}
}
...全文
972 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
幽幽有悠悠呦 2018-04-16
  • 打赏
  • 举报
回复
囧。看来没法解决了
引用 15 楼 xuzuning 的回复:
如果泛型限定于类型本身或子类,那就不是泛型。不需要限定,因为本来就是如此 Java 可能有 C++ 的模板类 概念(我不确认),但 C# 没有,T 在他们中间的含义是不同的
xuzuning 2018-04-14
  • 打赏
  • 举报
回复
如果泛型限定于类型本身或子类,那就不是泛型。不需要限定,因为本来就是如此 Java 可能有 C++ 的模板类 概念(我不确认),但 C# 没有,T 在他们中间的含义是不同的
幽幽有悠悠呦 2018-04-14
  • 打赏
  • 举报
回复
囧。其实我的需求就一点。简单而言,就是想告诉编译器。当前泛型类的子类、以及泛型类里中泛型的类型。两个都是继承自当前的泛型类。
cheng2005 2018-04-13
  • 打赏
  • 举报
回复
1,你把SuperClass类做成抽象类,可以从根源阻止基类的实例化,因为从逻辑角度来说,SuperClass没有实例化的意义。 2,隐藏父类,开放子类对外可见,我不知道JAVA是否真的如你所说可以做到这点,但是从面向对象的角度来看,这种需求绝对是反面向对象的,因为你都见不到你的爷爷,还怎么从爷爷那继承东西? 3,个人建议,做支持插件的系统,最起码的要素是你要对所使用的语言有比较深刻的理解,从你的帖子看出来,你对C#连熟悉都算不上,基本语法都还没学明白,还是先安心学学语言,再去做东西吧,不然害人害己啊。
xuzuning 2018-04-13
  • 打赏
  • 举报
回复
this 是当前类的实例化对象的代词 子类的对象中,不存在父类对象,只存在父类可继承的成员
幽幽有悠悠呦 2018-04-13
  • 打赏
  • 举报
回复
希望能当前泛型类这种类型的变量声明,在当前泛型类实例中把this赋值过去无需强制类型转换(意味着编译器已经明确知道this 是当前泛型类,T是当前泛型类的子类。根据多态性原理,父类声明里存放子类是绝对可行的)。
引用 8 楼 xuzuning 的回复:
不知道楼主打算要做什么 C# 和 Java 虽然长的差不多,但他们并不是一个东西,不能把 Java 的概念套用在 C# 上
cheng2005 2018-04-13
  • 打赏
  • 举报
回复
看清楚,我上面说的是“类型”,不是“对象”。
幽幽有悠悠呦 2018-04-13
  • 打赏
  • 举报
回复
额。这个如果我没记错的话,不应该是所有层级的父类(父类的父类的父类……)的内存地址都==this吗?如果是同一个实力对象的话。他们的地址是一致的才对啊。方便内存寻址不是么? 子类变量开辟的内存空间貌似应该是紧跟在N级父类所需的空间之后不是吗?难道我记错了? 我记得对象在内存中,不论是private 还是public。他们所占用的内存是不变的。不会因为任何修饰符而改变。更不会因为修饰符的原因抽出到其他地方去。因为编译到机器语言后,方便EBP+内存偏移寻址。所以一个对象实例他们所有变量应该是连续的不是吗?
引用 7 楼 wddw1986 的回复:
最后讲讲继承,子类继承父类,不是说子类把父类里的定义都搬到了自己这里。而是子类通过继承链,可以获取和访问父类的成员。 比如以下代码 ....
幽幽有悠悠呦 2018-04-13
  • 打赏
  • 举报
回复
引用 6 楼 wddw1986 的回复:
    public abstract class A{
        internal A() { }
    }
.....
囧了。如果涉及到T的部分都要靠子类自行实现,那么T约束貌似作用微乎其微了啊。就成为跟接口、抽象类里的抽象方法一样的存在了。都是强制子类来实现了。如果都这么做。那么泛型的作用变得可有可无了呢。 难道不能在父类中就实现呢?
xuzuning 2018-04-13
  • 打赏
  • 举报
回复
不知道楼主打算要做什么 C# 和 Java 虽然长的差不多,但他们并不是一个东西,不能把 Java 的概念套用在 C# 上
cheng2005 2018-04-13
  • 打赏
  • 举报
回复
最后讲讲继承,子类继承父类,不是说子类把父类里的定义都搬到了自己这里。而是子类通过继承链,可以获取和访问父类的成员。 比如以下代码,X里有一个成员字段a,Y继承自X,Y当然也拥有了一个成员字段a,问题是,这个a,是从X交给了Y吗?X和Y里各有一个a吗? 实际情况是,Y没有a,Y只是通过继承链可以访问到属于父类的a而已。 举个例子,假如Y有a,Y有X的一切信息,那我将X和Y放到两个不同的程序集里去编译,编译之后丢掉X所在的程序集,只留Y所在的程序集,理论上应该可以再构造一个Z继承自Y,拥有Y的一切。事实正好相反,新构建的Z类,如果访问不到X,那就无法继承,因为X作为Z在继承链的上级,拥有着Z必须知道的信息。
public class X { public int a; } public class Y : X { }
cheng2005 2018-04-13
  • 打赏
  • 举报
回复
    public abstract class A
    {
        internal A() { }
    }

    public abstract class B<T> : A where T : A
    {
        public static T Obj { get; private set; }


        protected abstract T instance { get; }

        public B()
            : base()
        {

        }

        private void SetObj()
        {
            Obj = this.instance;
        }
    }


    public class C : B<C>
    {
        protected override C instance
        {
            get
            {
                return this;
            }
        }
    }
幽幽有悠悠呦 2018-04-13
  • 打赏
  • 举报
回复
对第二点补充: 继续引用这句:第二:重孙从未见过祖宗,但是重孙基因难道不是祖宗那边继承过来的? 接上去,如果当前程序集和跨程序集认为是大家族的主脉和支脉,主脉血统纯正。能继承更多核心基因,支脉存在上门女婿等导致部分核心基因丢失(继承丢失部分主程序集某些核心方法)。 重孙不需要看到祖宗。因为它不需要祖宗所有技能,重孙只要有他的老爸、老妈将他生下来(实例化),能进族谱(继承性、无视跨程序集丢失的那部分基因),那么条件还是合理的!
引用 4 楼 huangfu6long 的回复:
第一个: 虽然成功限制了T必须是A的子类。但是依旧还是没法限制是B的子类,因为在B的实例中 this != A,跟谈谈泛型要求子类必须继承自当前类的事情 此帖子中的主题一样,仅仅是限制了父类。但是依旧没法限制T是B的子类(两次主题核心还是这句,怎么限制泛型里的类必须继承子当前类。使得T实例 == 当前类this)。 第二个: 跑题了,不考虑多程序集问题,因为多程序集访问权限是权限修饰符的问题,跟是否隐藏父类无关(跟隐藏方法更无关了) 第三个: 再次保留意见 [quote=引用 3 楼 wddw1986 的回复:] 第一:
    public abstract class A
    {
        internal A() { }
    }

    public abstract class B<T> : A where T : A
    {
        public B()
            : base()
        {

        }
    }
第二:
    internal class A
    {

        public void func1()
        { }
    }
你的基类里假设有一个public 方法,由于你的基类是internal 的,假如允许如下代码
    
//同一程序集的B
public class B : A
    { }

//另一程序集的C
    public class C : B
    { }
你的C里面想要调用func1方法的话,怎么调用?你的C连A类型长什么样都不知道,更和谈去调用里面的func1。 第三: 自信是好事,盲目的自信就是自大。推荐你踏踏实实学学语言的语法和特性,再来研究这种问题,是因为觉得你有思考能力,而不只是会抄代码。
[/quote]
幽幽有悠悠呦 2018-04-13
  • 打赏
  • 举报
回复
第一个: 虽然成功限制了T必须是A的子类。但是依旧还是没法限制是B的子类,因为在B的实例中 this != A,跟谈谈泛型要求子类必须继承自当前类的事情 此帖子中的主题一样,仅仅是限制了父类。但是依旧没法限制T是B的子类(两次主题核心还是这句,怎么限制泛型里的类必须继承子当前类。使得T实例 == 当前类this)。 第二个: 跑题了,不考虑多程序集问题,因为多程序集访问权限是权限修饰符的问题,跟是否隐藏父类无关(跟隐藏方法更无关了) 第三个: 再次保留意见
引用 3 楼 wddw1986 的回复:
第一:
    public abstract class A
    {
        internal A() { }
    }

    public abstract class B<T> : A where T : A
    {
        public B()
            : base()
        {

        }
    }
第二:
    internal class A
    {

        public void func1()
        { }
    }
你的基类里假设有一个public 方法,由于你的基类是internal 的,假如允许如下代码
    
//同一程序集的B
public class B : A
    { }

//另一程序集的C
    public class C : B
    { }
你的C里面想要调用func1方法的话,怎么调用?你的C连A类型长什么样都不知道,更和谈去调用里面的func1。 第三: 自信是好事,盲目的自信就是自大。推荐你踏踏实实学学语言的语法和特性,再来研究这种问题,是因为觉得你有思考能力,而不只是会抄代码。
cheng2005 2018-04-13
  • 打赏
  • 举报
回复
第一:
    public abstract class A
    {
        internal A() { }
    }

    public abstract class B<T> : A where T : A
    {
        public B()
            : base()
        {

        }
    }
第二:
    internal class A
    {

        public void func1()
        { }
    }
你的基类里假设有一个public 方法,由于你的基类是internal 的,假如允许如下代码
    
//同一程序集的B
public class B : A
    { }

//另一程序集的C
    public class C : B
    { }
你的C里面想要调用func1方法的话,怎么调用?你的C连A类型长什么样都不知道,更和谈去调用里面的func1。 第三: 自信是好事,盲目的自信就是自大。推荐你踏踏实实学学语言的语法和特性,再来研究这种问题,是因为觉得你有思考能力,而不只是会抄代码。
幽幽有悠悠呦 2018-04-13
  • 打赏
  • 举报
回复
第一:SuperClass抽象,被继承实现抽象方法。突破。。根源解决?无效 第二:重孙从未见过祖宗,但是重孙基因难道不是祖宗那边继承过来的? 第三:保留意见
引用 1 楼 wddw1986 的回复:
1,你把SuperClass类做成抽象类,可以从根源阻止基类的实例化,因为从逻辑角度来说,SuperClass没有实例化的意义。 2,隐藏父类,开放子类对外可见,我不知道JAVA是否真的如你所说可以做到这点,但是从面向对象的角度来看,这种需求绝对是反面向对象的,因为你都见不到你的爷爷,还怎么从爷爷那继承东西? 3,个人建议,做支持插件的系统,最起码的要素是你要对所使用的语言有比较深刻的理解,从你的帖子看出来,你对C#连熟悉都算不上,基本语法都还没学明白,还是先安心学学语言,再去做东西吧,不然害人害己啊。

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧