1

This is a very C# basic question but I don't know how to google it, cause I don't know how this classes are called. I want to define a class (called ContactType) which has two objects: ContactType.Internal & ContactType.External. And each of this objects can be instantiated only once during the application, so every time I define the Type property of a contact as ContactType.External or ContactType.Internal, it is a reference to the same object.

Furthermore, this ContactType class, needs to override the method ToString(), so when the object ContactType.Internal needs to be parsed to string it returns "Contact of type Internal", and similar for the External Object.

4
  • .Internal, .External can be solved with subclasses and inheritance, instead of "initiating them only once" use a static class, to override ToString() use public override. Commented Jan 8, 2017 at 12:28
  • You are probably looking for readonly properties, but your question isn't that clear. If your ContactType is a class, you can also override the ToString method to return your own implementation of it Commented Jan 8, 2017 at 12:28
  • 2
    I feel like your terminology is muddled here. Do you intend ContactType.Internal and ContactType.External to be properties within your ContactType class? Also, are you looking to create Internal and External as objects of the same class or different classes? Commented Jan 8, 2017 at 12:29
  • I feel that he's trying ask about enumerations, but doesn't know the term. Commented Jan 8, 2017 at 13:59

3 Answers 3

1

If I understand you correctly this basic principle should get you what you want. Important things to note are that the instances are static and can be accessed everywhere, and that the private constructor prevents any other code (barring reflection, you'll never prevent that) creating its own instances of ContactType.

sealed class ContactType
{
    public static ContactType Internal { get; } = new ContactType();
    public static ContactType External { get; } = new ContactType();

    private ContactType()
    {
    }
}

If you want more code involved in initialising the instances you may want to use a static constructor. This would look something like this:

sealed class ContactType
{
    public static ContactType Internal { get; }
    public static ContactType External { get; }

    private ContactType()
    {
    }

    static ContactType()
    {
        // More code can fit here if creating ContactType is complicated
        Internal = new ContactType();
        External = new ContactType(); 
    }
}

The static constructor will run once (right before the class is first used somewhere in your code) and set the static properties.

And here's an implementation that also handles the ToString() functionality:

sealed class ContactType
{
    private readonly string contactTypeName;

    public static ContactType Internal { get; } = new ContactType("Internal");
    public static ContactType External { get; } = new ContactType("External");

    private ContactType(string contactTypeName)
    {
        this.contactTypeName = contactTypeName;
    }

    public override string ToString()
    {
        // Note that these two ways of building this string are equivalent.
        // You may be more familiar with the old commented out way, but C# 6 added this new interpolation syntax.
        // Take your pick between the two, I prefer the interpolation.

        //return "Contact of type " + this.ContactTypeName;
        return $"Contact of type {this.contactTypeName}";
    }
}
Sign up to request clarification or add additional context in comments.

11 Comments

And each of this objects can be instantiated only once during the application. I believe static inheritance would solve this problem better than properties.
@devRicher Ahh yeah, I don't feel the question is very clear there. If you're going with this basic approach, the concepts here are still relevant though. Those classes would still likely want private constructors and to be assigned to a static property somewhere.
I could add details about the .ToString() to this as well, but I don't want to make the examples too messy or confusing. The basic principle would be to pass an argument to the constructor identifying the instance, store that in a field, then use it to determine what to return from .ToString(). Let me know if you want a full example of that.
I mean, I am not the question author, I can only suggest! ;) But yeah, I would suggest mentioning the override keyword there.
Also worth noting is that @john-wu is very much correct that dependency injection is often the better option here, but that adds a lot of complexity and likely requires project wide changes, my answer is just keeping things simple for now, John's answer is how I would choose to architect my own project.
|
1

Your question wasn't clear, but I think what you're looking for is an enum.

From your description, I understand that your class is Contact. ContactType.External or ContactType.Internal is defined only once. And the property is Type. ToString() should return the static Description of the enum value that is stored in Type.

Class Definition

using System.ComponentModel;

public class Contact
{
    public enum ContactType
    {
        [Description("Contact of type External")]
        External = 1,
        [Description("Contact of type Internal")]
        Internal = 2
    }
    public ContactType Type { get; set; }

    public override string ToString()
    {
        return ((DescriptionAttribute)typeof(ContactType).GetMember(Type.ToString())[0].GetCustomAttributes(typeof(DescriptionAttribute), false)[0]).Description;
    }
}

Usage

    Contact myContact = new Contact();

    myContact.Type = Contact.ContactType.External;
    txtOutput.Text = myContact.ToString();
    //Output: "Contact of type External"

    myContact.Type = Contact.ContactType.Internal;
    txtOutput.Text = myContact.ToString();
    //Output: "Contact of type Internal"

Comments

0

The old way of doing this would have been to use a static variable or a Singleton design pattern. And you can still do it that way. But those static members are terribly difficult to isolate out when writing unit tests.

For this reason, the more modern way to deal with this issue would be use Dependency Injection with something like InstancePerLifetimeScope. That way your object factory will always spit out the same instance of the Internal and External objects no matter how many times the code tries to create them.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.