继承自匿名类型T.

时间:2017-12-03 10:13:13

标签: c# .net

是否可以从匿名类型继承,例如,我有一些类和接口,如

public interface IFoo{
     int A { get; set;}
     string B { get; set;}
}

public interface IBoo : IFoo{
     decimal C { get; set;}
}

public class Foo: IFoo {...}

public class Boo: IBoo {...}

现在我想通过添加一些以相同方式应用于所有类的新属性来定义扩展现有类的类:

public class Extended<T> : T where T: IFoo
{
    bool D { get; set;}
}

因此Extended<Foo>的结果是Extended<Foo>内的属性为:

 public int A { get; set;}
 public string B { get; set;}
 public bool D { get; set;}

我知道这会产生编译错误:

  

CS0689:无法导出表格&#39; T&#39;因为它是一个类型参数

但为什么这不适用?只要我在声明中加入约束

当前的解决方案:我应该创建一个实现ExtendedFoo的类IFoo和实现ExtendedBoo的{​​{1}},我关心的是如果有方法或解决方法是能够定义一个继承所有这些类的类的泛型类,它们实现了接口Foo。

希望我的问题很清楚

3 个答案:

答案 0 :(得分:1)

也许这就是你想要的:

public interface IFoo 
{
    int A { get; set; }
    string B { get; set; }
}

public class Extended<T> : IFoo where T : IFoo, new()
{
    IFoo foo = new T();

    public int A 
    {
        get { return foo.A; }
        set { foo.A = value; }
    }

    public string B
    { 
        get { return foo.B; }
        set { foo.B = value; }    
    }

    public bool D { get; set; }
}

答案 1 :(得分:1)

不,不可能在C#中继承泛型类型参数。事实上也不可能从匿名类型继承,但这是一个独特的概念(见MS Docs Anonymous Types entry)。

C#泛型的工作方式是class Generic<T> {}编译器生成单个不完整类型Generic<>,然后在运行时使用它来生成代码实现和类型(例如Generic<string>,{{ 1}},...)。引用类型的代码实现共享相同的生成代码:Generic<int>List<string>是不同的类型,但使用相同的代码。 (对于相同大小的值类型也是如此,但在这种情况下这与我们讨论的继承无关。)

您的要求是使用通用类型List<object>。我可以想象有一种从那里生成不完整类型class Generic<T> : T的方法。但是,每个类型Generic<>都可以有不同的成员,虚方法表等。因此,每个T实例化的代码都需要单独生成,其方式与C ++模板的工作方式类似。 / p>

目前C#编译器无法做到这一点。原因可能是没有人发现用例如此有价值,可以设计语言解决方案,解决与现有功能的所有冲突,并实现它。

我建议你重新考虑你的设计。一旦你开始混合通用类型和功能(业务逻辑),你就可能无论如何都要远离惯用的C#。我希望进一步详细说明,但从这个角度来看,你的问题似乎非常像xy problem

答案 2 :(得分:0)

你不能做你要求的,泛型类不会继承或实现泛型类型,它只会给你变量T中的类型,以便你可以使用它

解决方法是做一些事情:

public interface IFoo {
     int A { get; set;}
     string B { get; set;}
}

public interface IBoo : IFoo{
     decimal C { get; set;}
}

public class Foo: IFoo {...}

public class Boo: IBoo {...}

public class Extended<T> where T : IFoo
{
    T Foo { get; set; } // Work with this property
    bool D { get; set;}
}