无法为泛型类创建属性

时间:2010-09-29 05:25:39

标签: c# generics

public class Address
{
    public string streetno;
    public string streetname;
    public string suburb;
    public string postcode;
    public Country country;
}
public class Country
{
    public string name;
}

public class Person<A>
    where A : new()
{
    public A address;

    public Person()
    {
        address.country = new Country();
    }
}

当我编译上面的代码时,我得到以下错误: 错误CS1061:'A'不包含'country'的定义,并且没有可以找到接受类型'A'的第一个参数的扩展方法'country'(你是否缺少using指令或汇编引用?)

关于如何解决这个问题的任何想法?

4 个答案:

答案 0 :(得分:7)

嗯,首先你需要了解错误。如果我们写下:

,你会发生什么?
Person<string> x = new Person<string>();

这将创建一个address字段string的对象。现在string没有country属性,因此没有意义。

我不清楚为什么你希望它从一开始就是通用的,但你可以添加一个额外的约束,以便A必须是Address或者派生类(粗略地说):

public class Person<A> where A : Address, new()

现在你只得到一个NullReferenceException - 因为你没有创建一个新的地址实例......你的构造函数需要改为:

public Person()
{
    address = new A();
    address.country = new Country();
}

或者,为了获得更大的灵活性,您可能需要创建一个IAddress 界面并表达约束,而不是类......但这取决于您。如果没有更多关于你正在做的事情的详细信息,很难推荐一个具体的行动方案。

答案 1 :(得分:0)

除非您已经给出了具有这些属性的泛型类型约束,否则不能像这样引用泛型类型的特定属性。例如,如果您将类声明为:

public class Person<T> where T : Address, new()
{
    public T address;

    public Person()
    {
        this.address.Country = new Country();
    }
}
当然,如果你只有那个地址类,这可能会破坏目的。奇怪的是,这是一个泛型类,其泛型类型参数是一个地址。另一种方法是使用动态关键字:

public class Person
{
    public dynamic address;

    public Person()
    {
        this.address.Country = new Country();
    }
}

答案 2 :(得分:0)

您必须将类型限制为支持country属性的类型。因为直接使用Address类是非常没有意义的,所以考虑使用某种类型的基类/接口。

public interface IAddress
{
    public string streetno { get; set; }
    public string streetname { get; set; }
    public string suburb { get; set; }
    public string postcode { get; set; }
    public Country country { get; set; }
}

public class Person<A>
    where A : IAddress
{
    public A address;

    public Person()
    {
        address.country = new Country();
    }
}

答案 3 :(得分:0)

我可能提交了一个不好的例子。这更接近我所拥有的:

namespace SomeNamespace
{
    public class SomeHeader
    {

    }

    public class SomeParamaters
    {

    }

    public class SomeRequest
    {
        public SomeHeader Header;
        public SomeParamaters Parameters;
    }
}

using SomeNamespace;

namespace MyNamespace
{

    public class Worker<A>
        where A : new()
    {
        public A req;

        public void DoSomeMeaningfulWork()
        {
            req.Header = new SomeHeader();
            req.Parameters = new SomeParamaters();
        }
    }
}

请注意,类SomeXXX继承自对象并实现System.ComponentModel.INotifyPropertyChanged

我选择泛型的原因是有很多请求,标题,参数,响应,数据,错误组。基本上每种类型的请求都定义了这些类型的一族。

工作者类 - 在写完3之后完全相同的条形,请求,标题,参数,响应,数据,错误。

我没有意识到动态关键字 - 但它听起来像我所追求的,因为我确切地知道需要调用的属性 - 它们完全相同且属于同一类型。

但是,我的问题是,我使用的是.net 3.5和vs 2008

我已经考虑了接口和约束,但它们似乎对我当前遇到的问题不起作用。