有以下一个泛型抽象基类,定义了一个供子类覆盖的静态方法,用于描述某个子类的一些信息,同时提供一个属性用来获取这个信息:public abstract class MembersBase<T> where T : new()
{
public static string Info
{
get
{
return typeof(T).InvokeMember("GetString",System.Reflection.BindingFlags.Static|System.Reflection.BindingFlags.InvokeMethod|System.Reflection.BindingFlags.Public,null,null,null) as string;
}
}
public static string GetString()
{
return "base";
}
} 之后在子类中重写方法:public class a : MembersBase<a>
{
public a():base(){}
public static new string GetString()
{
return "a class";
}
}
public class b : MembersBase<b>
{
public b():base(){}
public static new string GetString()
{
return "b class";
}
} 调用是这样的:a ai=new a();
b bi=new b();
Console.WriteLine(a.Info);
Console.WriteLine(b.Info);现在的目的是需要将a、b放入一个List集合,但使用
List<MemberBase> lm=new List<MemberBase>();
出现编译错误
求一个创建泛型抽象基类list的方法
{
public static string Info
{
get
{
return typeof(T).InvokeMember("GetString",System.Reflection.BindingFlags.Static|System.Reflection.BindingFlags.InvokeMethod|System.Reflection.BindingFlags.Public,null,null,null) as string;
}
}
public static string GetString()
{
return "base";
}
} 之后在子类中重写方法:public class a : MembersBase<a>
{
public a():base(){}
public static new string GetString()
{
return "a class";
}
}
public class b : MembersBase<b>
{
public b():base(){}
public static new string GetString()
{
return "b class";
}
} 调用是这样的:a ai=new a();
b bi=new b();
Console.WriteLine(a.Info);
Console.WriteLine(b.Info);现在的目的是需要将a、b放入一个List集合,但使用
List<MemberBase> lm=new List<MemberBase>();
出现编译错误
求一个创建泛型抽象基类list的方法
在我的知识结构中,静态方法是不可以继承的~所以也就没有什么 供子类覆盖的静态方法
public class MembersBase
{
public vir string GetString()
{
return "MembersBase class";
}
}
public class a : MembersBase
{
public override string GetString()
{
return "a class";
}
}
public class b : MembersBase
{
public override string GetString()
{
return "b class";
}
} ListMembersBase<T> : List<T> where T : MembersBase 大概思想如此~
还是说目的吧,现在有这样一个目的:
1.公开一个规范(基类)供开发拓展,这个规范需要有一个静态成员用于获取此类的描述符,用于代表此类已确定的、不改变的特性。
2.描述符可能是另一个类或结构体,所以不能用attribute描述
3.如果子类没有重写描述符,返回默认描述符
4.这个类实际上是一个完整的功能模块,所以用一个静态成员来描述是最简单的做法(不需要在注册拓展时进行大量配置或在加载拓展时进行额外的一次初始化)。
实在是想破了头才想出泛型基类+覆盖方法这个方式,自己也知道不合适,但一时间想不到其他方法了,还请赐教
另外静态方法可以在子类中继承访问吧,只是不能标记为虚方法供重写,所以才用了new关键字覆盖。
刚才看了msdn上的ReferenceEquals方法,说明是:确定指定的 Object 实例是否是相同的实例。 (从 Object 继承。)。这个不是继承么?
如果不是面向“对象”的问题就不要用面向对象的思想来解决。事实上针对你的这个问题,attribute恰恰是最适合的做法,却被你先否定了。
我对你的理解能力深感佩服,这一手偷换概念玩的真好,为你鼓掌。
好吧,不在这上面争论,只看具体事例:如果不用静态成员的话如何获取用于描述某个类特性的结构体?用一个特别长、特别复杂的attribute来符合所谓的“面向对象思想”真的比一个静态成员更为好用?
还有,现在说的是示例解决方案,不是什么面向对象思想,什么事都往XXX思想上面扯,阁下的思维逻辑也让在下大为惊讶。
我对你的理解能力深感佩服,这一手偷换概念玩的真好,为你鼓掌。
好吧,不在这上面争论,只看具体事例:如果不用静态成员的话如何获取用于描述某个类特性的结构体?用一个特别长、特别复杂的attribute来符合所谓的“面向对象思想”真的比一个静态成员更为好用?
还有,现在说的是示例解决方案,不是什么面向对象思想,什么事都往XXX思想上面扯,阁下的思维逻辑也让在下大为惊讶。
这不是静态成员不成员的问题,使用静态成员你就要考虑如何去取这个静态成员,如果是直接取的话,那相当于你需要认识每一个子类的,而且还要分别处理。所以只能是通过反射来获取。
既然是反射,那么attribute是比较正常的想法。当然,你的需求也许是信息很复杂,attribute写起来不方便,那你就做成静态成员反射去呗,毕竟没人拦着你。
再回到最初,你的a类和b类是一点关系都没有的两个类,就好像List<int>和List<String>除了继承相同的接口外其实是不相关的两个类型。
再重复一遍,继承是对象的概念,静态的东西没有继承的说法。所以不管你的需求最后如何解决,编译时的检查必然是用不上的,只能是运行时检查。
也可以List<>
我对你的理解能力深感佩服,这一手偷换概念玩的真好,为你鼓掌。
好吧,不在这上面争论,只看具体事例:如果不用静态成员的话如何获取用于描述某个类特性的结构体?用一个特别长、特别复杂的attribute来符合所谓的“面向对象思想”真的比一个静态成员更为好用?
还有,现在说的是示例解决方案,不是什么面向对象思想,什么事都往XXX思想上面扯,阁下的思维逻辑也让在下大为惊讶。
这不是静态成员不成员的问题,使用静态成员你就要考虑如何去取这个静态成员,如果是直接取的话,那相当于你需要认识每一个子类的,而且还要分别处理。所以只能是通过反射来获取。
既然是反射,那么attribute是比较正常的想法。当然,你的需求也许是信息很复杂,attribute写起来不方便,那你就做成静态成员反射去呗,毕竟没人拦着你。
再回到最初,你的a类和b类是一点关系都没有的两个类,就好像List<int>和List<String>除了继承相同的接口外其实是不相关的两个类型。
再重复一遍,继承是对象的概念,静态的东西没有继承的说法。所以不管你的需求最后如何解决,编译时的检查必然是用不上的,只能是运行时检查。
ReferenceEquals 确定指定的 Object 实例是否是相同的实例。 (从 Object 继承。)
摘自MSDN任何一个类型的成员页面。
在该例中,基类 BaseC 和派生类 DerivedC 使用相同的字段名 x,从而隐藏了继承字段的值。该示例演示了 new 修饰符的用法。另外还演示了如何使用完全限定名访问基类的隐藏成员。
public class BaseC
{
public static int x = 55;
public static int y = 22;
}public class DerivedC : BaseC
{
// Hide field 'x'.
new public static int x = 100; static void Main()
{
// Display the new value of x:
Console.WriteLine(x); // Display the hidden value of x:
Console.WriteLine(BaseC.x); // Display the unhidden member y:
Console.WriteLine(y);
}
}
摘自MSDN new 修饰符(C# 参考):http://msdn.microsoft.com/zh-cn/library/435f1dw2%28v=vs.90%29.aspx
原来微软都不理解面向对象的含义,居然能继承静态成员
我对你的理解能力深感佩服,这一手偷换概念玩的真好,为你鼓掌。
好吧,不在这上面争论,只看具体事例:如果不用静态成员的话如何获取用于描述某个类特性的结构体?用一个特别长、特别复杂的attribute来符合所谓的“面向对象思想”真的比一个静态成员更为好用?
还有,现在说的是示例解决方案,不是什么面向对象思想,什么事都往XXX思想上面扯,阁下的思维逻辑也让在下大为惊讶。
这不是静态成员不成员的问题,使用静态成员你就要考虑如何去取这个静态成员,如果是直接取的话,那相当于你需要认识每一个子类的,而且还要分别处理。所以只能是通过反射来获取。
既然是反射,那么attribute是比较正常的想法。当然,你的需求也许是信息很复杂,attribute写起来不方便,那你就做成静态成员反射去呗,毕竟没人拦着你。
再回到最初,你的a类和b类是一点关系都没有的两个类,就好像List<int>和List<String>除了继承相同的接口外其实是不相关的两个类型。
再重复一遍,继承是对象的概念,静态的东西没有继承的说法。所以不管你的需求最后如何解决,编译时的检查必然是用不上的,只能是运行时检查。
还有,取attribute有特定的方法GetCustomAttributes,用反射完全是多此一举
我对你的理解能力深感佩服,这一手偷换概念玩的真好,为你鼓掌。
好吧,不在这上面争论,只看具体事例:如果不用静态成员的话如何获取用于描述某个类特性的结构体?用一个特别长、特别复杂的attribute来符合所谓的“面向对象思想”真的比一个静态成员更为好用?
还有,现在说的是示例解决方案,不是什么面向对象思想,什么事都往XXX思想上面扯,阁下的思维逻辑也让在下大为惊讶。
这不是静态成员不成员的问题,使用静态成员你就要考虑如何去取这个静态成员,如果是直接取的话,那相当于你需要认识每一个子类的,而且还要分别处理。所以只能是通过反射来获取。
既然是反射,那么attribute是比较正常的想法。当然,你的需求也许是信息很复杂,attribute写起来不方便,那你就做成静态成员反射去呗,毕竟没人拦着你。
再回到最初,你的a类和b类是一点关系都没有的两个类,就好像List<int>和List<String>除了继承相同的接口外其实是不相关的两个类型。
再重复一遍,继承是对象的概念,静态的东西没有继承的说法。所以不管你的需求最后如何解决,编译时的检查必然是用不上的,只能是运行时检查。
还有,取attribute有特定的方法GetCustomAttributes,用反射完全是多此一举
你越说越可笑了,我现在已经怀疑你究竟对C#了解多少,也许基础知识还没弄明白吧。GetCustomAttributes就是反射啊,大哥,你究竟知道不知道什么叫做反射?找本正经的书好好看看吧,别这么丢人了好不。
还是说目的吧,现在有这样一个目的:
1.公开一个规范(基类)供开发拓展,这个规范需要有一个静态成员用于获取此类的描述符,用于代表此类已确定的、不改变的特性。
2.描述符可能是另一个类或结构体,所以不能用attribute描述
3.如果子类没有重写描述符,返回默认描述符
4.这个类实际上是一个完整的功能模块,所以用一个静态成员来描述是最简单的做法(不需要在注册拓展时进行大量配置或在加载拓展时进行额外的一次初始化)。
实在是想破了头才想出泛型基类+覆盖方法这个方式,自己也知道不合适,但一时间想不到其他方法了,还请赐教
另外静态方法可以在子类中继承访问吧,只是不能标记为虚方法供重写,所以才用了new关键字覆盖。
刚才看了msdn上的ReferenceEquals方法,说明是:确定指定的 Object 实例是否是相同的实例。 (从 Object 继承。)。这个不是继承么?(1)什么是描述符,它是干嘛的。如果你用的术语不是广泛意义上人们熟知的,请你在使用前先定义它。
(2、3)因为我不知道什么是描述符,我就更不知道为什么不能用Attribute定义,以及为什么要用Attrbiute定义。
(4)这个类实际上是一个完整的功能模块,所以用一个静态成员来描述是最简单的做法。什么是完整的功能,你用静态成员描述什么?用静态成员描述一个类?为什么是最简单的做法,和什么相比简单?
(5)不知道你提ReferenceEquals做什么。估计我之前没有说的很清楚。你当然可以从一个类的派生类去访问基类的静态成员。或许你把这个当作静态成员可以继承了。如果是这样,怪我没有说清楚。我想表达的是,你没有办法在派生类中编写一个方法去“覆盖”基类的静态方法。好比你举的例子,你new一个方法,基类如果不知道派生类中的这个GetString,它永远不可能调用到,我再用代码解释下:class A
{
public static string GetString() { return "a"; }
void foo()
{
string s1 = GetString(); // always pass "a"
string s2 = B.GetString(); // "b"
}
}class B : A
{
public new static string GetString() { return "b"; }
void foo()
{
string s1 = GetString(); // always pass "b"
string s2 = A.GetString(); // "a"
}
}