通用<t>静态方法访问成员方法

时间:2015-05-05 00:36:09

标签: c# generics

我正在尝试使用通用静态函数Load()来调用虚拟函数,但显然C#编译器无法识别T中的PostLoad()。我想知道有没有办法以某种方式完成此操作。有什么想法吗?

public abstract class Model<T> where T : new()
{
    public virtual void PostLoad() { }
    public static T Load()
    {
        T bar;

        //assigning values to bar
        ....

        //compilation error: Type `T' does not contain a definition for `PostLoad' and no extension method
        bar.PostLoad();

        return bar;
    }
}

3 个答案:

答案 0 :(得分:3)

您的抽象类translate([0, 0, 25]){ linear_extrude(height = 50, center = true, convexity = 10, twist = 200) circle(r = 1); } translate([0, 0, 40]){cylinder(10, 1, 2);} translate([0, 0, 50]){rotate([0, 20, 0]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 20]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 40]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 60]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 80]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 100]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 120]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 140]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 160]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 180]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 200]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 220]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 240]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 260]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 280]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 300]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 320]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 20, 340]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 2, 0]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 0, 20]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 2, 40]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 0, 60]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 0, 80]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 2, 100]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 0, 120]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 2, 140]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 2, 160]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 2, 180]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 0, 200]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 2, 220]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 0, 240]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 2, 260]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 2, 280]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 0, 300]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 0, 320]){cube([10, 5, 1]);}} translate([0, 0, 50]){rotate([0, 0, 340]){cube([10, 5, 1]);}} 是定义Model<T>的类,但类型PostLoad不是。 T可以是任何东西,这就是编译器给你一个错误的原因。因此,在您的方法T中,如果要调用Load

,则需要创建一个Model<T>的新类
PostLoad

我认为你需要再看一下你的设计......你究竟想做什么?

答案 1 :(得分:0)

通过添加泛型约束并将虚函数移动到基类。编译器将识别PostLoad()

public abstract class Model
{
    public virtual void PostLoad() { }
}

public abstract class Model<T> : Model where T : Model, new()
{
    public static T Load()
    {
        T bar;

        //assigning values to bar
        ....

        //compilation error: Type `T' does not contain a definition for `PostLoad' and no extension method
        bar.PostLoad();

        return bar;
    }
}

答案 2 :(得分:0)

我不知道类级别Load()函数应该做什么。但是这里的一般规则是类级函数不能调用实例函数,除非它们可以访问对象本身,然后它们可以调用它的函数。

我假设Load()函数假设加载模型。在这种情况下,您需要将函数的返回类型从T更改为Model,将条形类型从T更改为Model。然后按照您喜欢的方式初始化并加载模型,然后调用后加载,就像这样。

public abstract class Model<T> where T : new()
    {
        public virtual void PostLoad() { }
        public static Model<T> Load()
        {
            Model<T> bar = null;
            //assigning values to bar


            //compilation error: Type `T' does not contain a definition for `PostLoad' and no extension method
            bar.PostLoad();
            return bar;
        }
    }

此外,您的代码中存在一个小错误,即您可以在T类型上调用PostLoad()函数,并且该函数在Model中定义。

如果你打算说T必须有一个PostLoad()函数并且Load()静态函数应该在初始化和加载后调用它,你应该执行以下操作:

public interface IModelLifeCycle
    {
        void PostLoad();
    }
    public abstract class Model<T> where T : IModelLifeCycle
    {
        public static T Load()
        {
            T bar = default(T);
            //assigning values to bar


            //compilation error: Type `T' does not contain a definition for `PostLoad' and no extension method
            bar.PostLoad();
            return bar;
        }
    }

正如您现在所看到的,因为where条件强制泛型类型实现IModelLifeCycle,Load()函数能够调用PostLoad()函数,该函数由接口定义强制而不是由模型强制执行(你不能需要在Model类中定义的PostLoad()。

希望得到这个帮助。