famle
famle

Reputation: 491

Cannot use constructor for public class within same namespace due to protection level?

I am currently trying to map alot of channel, and have thus for convenient sake, made a class that can contain the channel properties and a dictionary, that maps an ID to a channel. The dictioanary is on one class and the channel definition is in their own classes but, within the same namespace.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ParentId = System.String;
using ChildIds = System.Collections.Generic.List<int>;
using ChannelName = System.String;
using CatalogEntry = System.Tuple<System.String, System.Collections.Generic.List<int>, System.String>;


namespace example
{
    public class ChannelHandler
    {
        public ChannelName channelname { get; set; }
        public ParentId parentid { get; set; }
        public ChildIds list_of_childs { get; set; }
        public int id;

        ChannelHandler(ChannelName name, int id)
        {
            this.channelname = name;
            this.id = id;
        }

        ChannelHandler(ChannelName name, int id, ParentId parentid)
        {
            this.channelname = name;
            this.id = id;
            this.parentid = parentid;
        }

    }

    public class Class1
    {
        private Dictionary<int?, ChannelHandler> dictionary = new Dictionary<int?, ChannelHandler>();
        public void inser_into_dictionary(string path)
        {
            string[] separatingChars = { "  " };
            string[] splittedPath = path.Split(separatingChars, StringSplitOptions.RemoveEmptyEntries);
            int parentId = 0;
            ChannelName parentName = string.Empty;
            foreach (string channel_id in splittedPath)
            {

                ChannelName name = channel_id.Split('_').ElementAt(0);
                string id = channel_id.Split('_').ElementAt(1);
                int int_id = 0;
                if (int.TryParse(id, out int_id))
                {
                    int_id = int.Parse(id);
                }

                Tuple<string, int> pair_of_channel_and_id = new Tuple<string, int>(name, int_id);
                if (this.dictionary.ContainsKey(int_id))
                {
                    // Key exist, meaning this is a parent. 
                    // Child entry has to be updated. 
                    parentId = int_id;
                    parentName = name;
                }
                else
                {
                    if (parentId == 0)
                    {
                        ChannelHandler channel = new ChannelHandler(name, int_id); //ChannelHandler.ChannelHandler is inaccesible due to protection level. 
                        this.dictionary.Add(int_id, channel);

                    }
                }
            }
        }
    }
}

I seem to be unable to create the object channel as the constructor for the class seem to inaccesible due to protection level? but what protection level - everything is public?

Upvotes: 1

Views: 346

Answers (4)

Peter Smith
Peter Smith

Reputation: 5550

It could look like:

public class ChannelHandler
{
    public ChannelName ChannelName { get; set; }
    public ParentId ParentId { get; set; }
    public List<ChildId> ChildIds { get; set; }
    public int Id;

    public ChannelHandler(ChannelName name, int id)
    {
        ChannelName = name;
        Id = id;
    }

    public ChannelHandler(ChannelName name, int id, ParentId parentid)
    {
        ChannelName = name;
        Id = id;
        ParentId = parentid;
    }

By default, the access level of any element of a class is private. You need to make the constructors either public or internal so that can be accessed externally to the class itself. If you look at this article here it explains how access modifiers affect the accessibility levels of your code.

The other change I made was to change the case of your members to meet c# coding conventions. See here

Upvotes: 2

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 61912

You:

ChannelHandler(ChannelName name, int id)
{
    this.channelname = name;
    this.id = id;
}

ChannelHandler(ChannelName name, int id, ParentId parentid)
{
    this.channelname = name;
    this.id = id;
    this.parentid = parentid;
}

All members of classes (and structs) are private per default. In C#, everything has the strictest possible accessibility level if you specify nothing. For direct members of classes or structs (including nested types in the class or struct), that is private.

private means accessible only from within the class/struct itself.

Try this:

internal ChannelHandler(ChannelName name, int id)
{
    channelname = name;
    this.id = id;
}

internal ChannelHandler(ChannelName name, int id, ParentId parentid)
    : this(name, id)
{
    this.parentid = parentid;
}

Here, internal on the instance constructors (non-static constructors) means the same internal always means: Accessible to everybody in the same project/assembly.

Upvotes: 2

Zaiyang Li
Zaiyang Li

Reputation: 102

The class ChannelHandler constructors cannot be called from outside the class because they are private. When you don't specify an access level modifier for methods or fieds, by default, C# compiler will assume it is private. Just add keyword public before constructor definitions:

public class ChannelHandler
{
    public ChannelName channelname { get; set; }
    public ParentId parentid { get; set; }
    public ChildIds list_of_childs { get; set; }
    public int id;

    public ChannelHandler(ChannelName name, int id)
    {
        this.channelname = name;
        this.id = id;
    }

    public ChannelHandler(ChannelName name, int id, ParentId parentid)
    {
        this.channelname = name;
        this.id = id;
        this.parentid = parentid;
    }

}

Upvotes: 1

Robertcode
Robertcode

Reputation: 1001

You declared your class name as public but that is not enough. Every function, including constructors, inside the Class definition that is to be accessible by other classes must be declared public as well. Constructors and methods inside a class without an access modifier is defaulted to to either private or internal depending on the circumstances. More information at this link:

Access modifiers

Upvotes: 1

Related Questions