serhio
serhio

Reputation: 28586

Limited Object type in .NET

Let's have a library of objects Person, Cat, Dog, Pencil and Byke.

Let's give to Person a FavoriteThing member, that can be of any of listed types.

Let's imagine that we have to save the Person's state using a serialization, so we make all of listed objects as Serializable.

How do we now protect the Person from "injecting" him a "FavoriteThing" like Cobra class, that does not comply the requirements (to be Serializable, or others, like to be inoffensive :).

Upvotes: 1

Views: 79

Answers (3)

Fredrik Mörk
Fredrik Mörk

Reputation: 158309

I am not sure exactly what you want to achieve, but if you in some way want to be able to define what types should be allowed to be assigned to FavoriteThing, you could create an empty interface (let's call it IFavorable), and declare FavoriteThing as being of that type;

public interface IFavorable { }

class Person
{
    public IFavorable FavoriteThing { get; set; }
}

Then you make the allowed types "implement" this interface:

class Dog : IFavorable
{
    // ...
}

That would work, though I am not a huge fan of such "meta interfaces" myself...

Upvotes: 3

Marc Gravell
Marc Gravell

Reputation: 1062600

Best on your related recent post, this relates to a List<object>, yes?

In this case, I wouldn't use object - I'd use a common base-class:

[Serializable]
public class FavoriteThing {} // this is probably a bad name...

[Serializable]
public class Dog : FavoriteThing {}

[Serializable]
public class Pencil : FavoriteThing {}

(and use a List<FavoriteThing> instead of List<object>)

Note that this doesn't enforce the [Serializable] - no compiler check can do that; but it does keep it to sane values - i.e. not (ranadomly) a HttpWebRequest

Additionally, multiple serializers will work happily with a base-class model, that won't work with random objects - for example DataContractSerializer, XmlSerializer, etc. Normally I prefer encapsulation over inheritance, but for serialization / DTO, a base-class is usually the simplest option.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500065

You might want to write a FavoriteThing type which acts as a tagged union. In other words, it has a property for each type (person, cat etc) but enforces that it only contains one value at a time. You may not explicitly need a tag field if these are all reference types; just make sure that only one of your strongly-typed fields is non-null at a time. You will need to provide a way of determining which type has a value though.

Another option is to make all of those types implement a common interface - but that may not be an appropriate design, if those types shouldn't really know about the "favorite" concept.

It's hard to be more concrete without knowing what you'd want to do with the favorite thing...

Upvotes: 2

Related Questions