开发者

Unable to create property for a generic class

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 cla开发者_StackOverflow社区ss Person<A>
    where A : new()
{
    public A address;

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

when i compile the above code i get the following error: error CS1061: 'A' does not contain a definition for 'country' and no extension method 'country' accepting a first argument of type 'A' could be found (are you missing a using directive or an assembly reference?)

any ideas on how I can over come this issue?


Well, first you need to understand the error. What would you expect to happen if we wrote:

Person<string> x = new Person<string>();

That would create an object with an address field of type string. Now string doesn't have a country property, so it doesn't make sense.

It's not clear to me why you want it to be generic to start with, but you could add an extra constraint so that A has to be Address or a derived class (roughly speaking):

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

Now you'll just get a NullReferenceException - because you're not creating a new instance of the address... your constructor would need to change to:

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

Alternatively, for more flexibility you might want to create an IAddress interface and express the constraint in terms of that, instead of the class... but that's up to you. It's hard to recommend a concrete course of action without more details of what you're doing.


You cannot refer to specific properties of a generic type like that unless you've given a generic type constraint that has those properties. For example, if you declared your class like:

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

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

of course that might defeat the purpose if you only have that address class. It seems odd that this is a generic class where your generic type parameter is an address. Another approach would be to use the dynamic keyword:

public class Person
{
    public dynamic address;

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


You have to restrict your type to one that supports the country property. Since using the Address class directly is rather pointless consider using some type of base class /interface.

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();
    }
}


I probably submitted a bad example. This is closer to what I have:

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();
        }
    }
}

Please note the classes SomeXXX inherit from object and implement System.ComponentModel.INotifyPropertyChanged.

The reason I chose generics was there are many request,header,paramters,respons,data,error groups. Basically each type of request defines a family of these.

The worker classes - after having written 3 are exactly the same bar the request,header,paramters,respons,data,error.

I was unaware of the dynamic keyword - but it does sound like what i am after as i know exactly the properties that are needed to be called - they are exactly the same and of the same type.

However, my problem is, I am using .net 3.5 and vs 2008

I have considered interfaces and constraints, but they just dont seem to work for the current problem i am facing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜