-2

I'm probably not asking the correct question.

static void GetEveryThing<t>(string Token)
{
    t x = JsonConvert.DeserializeObject<t>(GetData("Original API Query", Token));
    string NextLink = x.nextLink;
    while (NextLink != null)
    {
        t z = JsonConvert.DeserializeObject<t>(GetData(NextLink, Token));
        x.value.AddRange(z.value);
        NextLink = z.nextLink;
    }
}

I have seven different classes that need to use the above code. All the classes have properties 'count', 'value', and 'nextLink'. Value is a List<T> that holds the actual returned data. nextLink is returned from the API query and just has the next Query Link to keep getting information.

The error is, I can't get x.nextLink, z.count, z.nextLink, x.value, z.value, or z.nextLink. Error Code CS1061. I don't know how to use the <t> to make this work.

I can add the classes in question, GetData, or anything else that may help. I feel that this is something fundamental and I just don't know how to do it or ask the correct question.

How do I make this work?

Edit:

Here are two classes I'm trying to use;

class OfficeData
{
    [JsonProperty("@odata.context")]
    public string context { get; set; }
    public List<OfficeAssocDataRows> value { get; set; }
    [JsonProperty("@odata.count")]
    public int count { get; set; }
    [JsonProperty("@odata.nextLink")]
    public string nextLink { get; set; }
}

class MembersData
{
    [JsonProperty("@odata.context")]
    public string context { get; set; }
    public List<MemberAssocDataRows> value { get; set; }
    [JsonProperty("@odata.count")]
    public int count { get; set; }
    [JsonProperty("@odata.nextLink")]
    public string nextLink { get; set; }
}

--- This question has been closed, so leaving here as a note.

Second Edit:

I've almost got the interface setup;

interface IAPIDataInterface
{
    [JsonProperty("@odata.context")]
    public string context { get; set; }
    //public List<T> value { get; set; } <-- How do I get this to pass through?
    [JsonProperty("@odata.count")]
    public int count { get; set; }      
    [JsonProperty("@odata.nextLink")]
    public string nextLink { get; set; }
}

class OfficeData : IAPIDataInterface
{
    [JsonProperty("@odata.context")]
    public string context { get; set; }
    public List<OfficeAssocDataRows> value { get; set; }
    [JsonProperty("@odata.count")]
    public int count { get; set; }
    [JsonProperty("@odata.nextLink")]
    public string nextLink { get; set; }
}

class MembersData : IAPIDataInterface
{
    [JsonProperty("@odata.context")]
    public string context { get; set; }
    public List<MemberAssocDataRows> value { get; set; }
    [JsonProperty("@odata.count")]
    public int count { get; set; }
    [JsonProperty("@odata.nextLink")]
    public string nextLink { get; set; }
}
Kayot
  • 582
  • 2
  • 20
  • 2
    is `t` a well known type? perhaps you can define a interface which allows for a type constraint. – Daniel A. White Nov 13 '20 at 20:31
  • I'm trying to avoid using 7 copies of the same function with just the Class type being the difference. I've seen it done. JsonConvert.DeserializeObject does it. – Kayot Nov 13 '20 at 20:38
  • https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters# – Daniel A. White Nov 13 '20 at 20:40
  • 2
    `where t : ISomeInterface` or `where t : BaseClass` – Daniel A. White Nov 13 '20 at 20:41
  • I've updated the question. I am unable to use 'static void GetEveryThing(string Token) where T : MembersData, OfficeData', but I can use just one class or the other. If possible, how would I go about getting this to work? – Kayot Nov 13 '20 at 20:58
  • There are a couple of different approaches. The ideal one is to have the types inherit a common base class or interface, then constrain the generic type parameter to that. See duplicate. An alternative approach uses `dynamic` as the type, rather than making the method generic. This works if you simply cannot change the type hierarchy. – Peter Duniho Nov 13 '20 at 21:47

2 Answers2

2

You need your things to be deserialized to inherit from a common interface. Then you can set a constraint on your generic method to constrain it to accepting classes that implement that interface. At that point you'll have access to the common members you need. See below for a contrived example.

class Program
    {
        static void Main(string[] args)
        {
            var bar = new Bar
            {
                Count = 10,
                Value = "Bar",
                NextLink = "Bleh"
            };
            var fooBar = new FooBar
            {
                Count = 20,
                Value = "FooBar",
                NextLink = "Meh"
            };
            var serializedBar = JsonConvert.SerializeObject(bar);
            var serializedFooBar = JsonConvert.SerializeObject(fooBar);
            GetEverything<Bar>(serializedBar);
            GetEverything<FooBar>(serializedFooBar);
        }

        static void GetEverything<T>(string thingToDeserialize) where T : IFoo
        {
            T x = JsonConvert.DeserializeObject<T>(thingToDeserialize);
            Console.WriteLine(x.Value);
            Console.WriteLine(x.NextLink);
            Console.WriteLine(x.Count);
        }
    }

    public interface IFoo
    {
        public int Count { get; set; }
        public string Value { get; set; }
        public string NextLink { get; set; }
    }

    public class Bar : IFoo
    {
        public int Count { get; set; }
        public string Value { get; set; }
        public string NextLink { get; set; }
    }

    public class FooBar : IFoo
    {
        public int Count { get; set; }
        public string Value { get; set; }
        public string NextLink { get; set; }
    }
gilliduck
  • 2,762
  • 2
  • 16
  • 32
  • Optionally (and it's so complicated I'm not gonna bother with an example) you can do some crazy reflection and make assumptions about types and properties. But I wouldn't do that without an amazing reason. – gilliduck Nov 13 '20 at 21:16
-1

Convert "t" to the Object you need.

YourObject yourObject = t as YourObject