I'm interested in making an .ini file parser and I want it to have an internal list that can hold it's individual entries. The catch is I want to make one list to hold all the values. That means strings, boolean values and int types.

I have a class to hold key-value pairs that is a template.

public class KVPair<T>
{
    private string key;
    private T      value;
...
}

I'm interested to know if there's any way to make a list something like

List<KVPair> something;

without having to specify a certain type for the inner object, or a work-around.

Dani AI

Generated

The build error comes from how C# generics work: a closed generic type like KVPair<string> is a different, incompatible type from KVPair<object>. That’s why storing mixed KVPair<T> instances directly in one List<T> fails. is right that boxing everything as object works but forces external casts; is right to call out invariance and section semantics for INI files.

A practical pattern that keeps type info and avoids external casts is a non-generic abstraction plus a generic implementation. For example, expose a non-generic interface for consumers and implement it with your generic KVPair<T>; store a List of the interface. The interface provides an object Value and a Type (or a generic TryGet<T> helper) so callers can request a typed value without knowing the concrete T at compile time.

public interface IEntry {
  string Key { get; }
  object Value { get; }
  Type ValueType { get; }
  bool TryGet<T>(out T val);
}

public class Entry<T> : IEntry {
  public string Key { get; set; }
  public T Typed { get; set; }
  public object Value => Typed;
  public Type ValueType => typeof(T);
  public bool TryGet<TOut>(out TOut val) { ... } // use "is" or ChangeType
}

Alternative: keep the raw INI text and offer parsing accessors (e.g., TryGetInt, TryGetBool, TryGet<T> using TypeConverter/Convert.ChangeType). This is simplest for INI-style data and preserves the original string (useful for comments/round‑trips). Covariant interfaces (IKVPair<out T>) are possible but only help for reference types, not value types like int/bool.

Other practical tips: key your storage by section+key (nested dictionary), cache parsed values if parsing cost matters, and prefer Try-patterns to avoid exceptions when parsing fails. This keeps the API ergonomic while preserving type information and encapsulation.

Recommended Answers

All 3 Replies

Generally you could just do:

List<object> anything = new List<object>();

The issue is you'd need to know what the values are, so that you could cast them as specific types when you need to:

string name = (string)anything[0];

Hope that helps.

I don't want to sound pompous, but I was hoping for something more elegant, since casting to a key-value pair outside the file handler class defeats the whole purpose of encapsulating the data into a class.
For some reason this

List<KVPair<object>> something;

doesn't work. In the build errors it sais:
"Cannot convert type 'KVPair<object>' to 'KVPair<string>'"
when I try to add a KVPair<string>.

The user of your class will need to know what type is being returned, or else how are they going to use it? They will have to know to expect a string, boolean, int, etc. Sure, they could assign it to var, but then what good is it? Should you add something to it, or parse it as a string or test the true/false value?

You are going to have to cast (easy way) or use a struct to hold the values and create a 'union' type (like the one in C). is an article about creating a union type for C#.

As for your error, a KVPair<object> is a different type than a KVPair<string>, with no method defined to cast it, so you get an error. Don't be confused by the <object> part, remember it's a KVPair<T>.

You also need to consider that ini files have sections, and it's perfectly fine to have the same key in multiple sections. For example

[Standard]
User=Bob

[Specific]
User=Fred

So a simple dictionary of key/values won't work.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.