C# How to access static class List<> from anoth

2019-07-17 02:30发布

问题:

Using C#, I have a static class that has a static list of a custom type. Here is the custom type:

public class LanguageItem
{
    public Word.WdLanguageID Id { get; set; }
    public string Name { get; set; }

    public LanguageItem(string name, int id)
    {
        Id = (Word.WdLanguageID)id;
        Name = name;
    }
}

And here is the static class that uses this type:

public static class LanguageList
{            
    public static List<LanguageItem> _languageList;

    static LanguageList()
    {
        _languageList.Add(new LanguageItem("Arabic", 1025));
        _languageList.Add(new LanguageItem("Bulgarian", 1026));
        _languageList.Add(new LanguageItem("Catalan", 1027));
        _languageList.Add(new LanguageItem("TraditionalChinese", 1028));
        _languageList.Add(new LanguageItem("Czech", 1029));
        _languageList.Add(new LanguageItem("Danish", 1030));
        _languageList.Add(new LanguageItem("German", 1031));
        _languageList.Add(new LanguageItem("Greek", 1032));
        _languageList.Add(new LanguageItem("EnglishUS", 1033));
        _languageList.Add(new LanguageItem("Spanish", 1034));
        _languageList.Add(new LanguageItem("Finnish", 1035));
        _languageList.Add(new LanguageItem("French", 1036));
        _languageList.Add(new LanguageItem("Hebrew", 1037));
        _languageList.Add(new LanguageItem("Hungarian", 1038));
        _languageList.Add(new LanguageItem("Icelandic", 1039));
        _languageList.Add(new LanguageItem("Italian", 1040));
        _languageList.Add(new LanguageItem("Japanese", 1041));
        _languageList.Add(new LanguageItem("Korean", 1042));
        _languageList.Add(new LanguageItem("Dutch", 1043));
    }

    public static List<LanguageItem> LanguageListItems
    {
        get
        {
            return _languageList;
        }
        private set
        {
            _languageList = value;
        }
    }
}

What I am trying to do is to use this list from another class, to return the the items from the list. I want to specify the Name and I want to get the Id back.

I tried to use this:

using Word = Microsoft.Office.Interop.Word;

Word.Application oWord = new Word.Application();

oWord.Selection.LanguageID = LanguageList.Single(lang => lang.Name == strTgtLanguage).Id;

But I get a compile error that reads:

'LanguageList' does not contain a definition for 'Single'

I tried to look at other similar post, such as How to access all specific versions of a generic static class in C#? and How to access member of a static class which is inside another static class and others, but I can't figure it out based on these.

Also the reason I am using a hard coded enumeration because if I use the COM object Office.Interop.Word, then it takes forever (over 2 minutes) to add all the 250+ items to the list.

Can somebody help me a point out what I am doing wrong and why can't I access the list, or if there is a better approach? Thanks in advance.

回答1:

I think your approach is not appropriate.

If you're hard-coding the list, then why would you have a setter? Also, the list should then be immutable, correct?

I believe this would work better for your need:

    public static class LanguageList
{
    private static readonly List<LanguageItem> _languageList = new List<LanguageItem>(new[]
    {
        new LanguageItem("Arabic", 1025),
        new LanguageItem("Bulgarian", 1026),
        new LanguageItem("Catalan", 1027),
        new LanguageItem("TraditionalChinese", 1028),
        new LanguageItem("Czech", 1029),
        new LanguageItem("Danish", 1030),
        new LanguageItem("German", 1031),
        new LanguageItem("Greek", 1032),
        new LanguageItem("EnglishUS", 1033),
        new LanguageItem("Spanish", 1034),
        new LanguageItem("Finnish", 1035),
        new LanguageItem("French", 1036),
        new LanguageItem("Hebrew", 1037),
        new LanguageItem("Hungarian", 1038),
        new LanguageItem("Icelandic", 1039),
        new LanguageItem("Italian", 1040),
        new LanguageItem("Japanese", 1041),
        new LanguageItem("Korean", 1042),
        new LanguageItem("Dutch", 1043),
    });

      public static IEnumerable<LanguageItem> GetLanguages ()
    {
        return _languageList;
    }

    public static LanguageItem GetLanguageItem(string languageName)
    {
        return _languageList.SingleOrDefault(li => li.Name.Equals(languageName));
    }
}


回答2:

.Single(...) from System.Linq is an extension method, but you're trying to use it as a static method on LanguageList.

If you want to use the LINQ methods, you need to operate on the actual list object, not the class - LanguageList.LanguageListItems.

i.e. LanguageList.LanguageListItems.Single(...).

Furthermore, since it's a static class, the inheritance from List<T> is irrelevant and can probably be dropped.



回答3:

1) You can't use .Single() because LanguageList is a class, not an instance of a class which implements IEnumerable< T >. It should work if you do:

new LanguageList().GetLanguageList.Single();

But don't actually do that. There's no reason for GetLanguageList to be an instance member; it should be static.

2) You should not expose the language list, assuming it is intended to be immutable.

3) You should probably use a Dictionary< string, Word.WdLanguageID > for your language table. It will be a bit more efficient, and uniqueness is enforced during construction, not during each lookup.

4) Add a static language accessor to LanguageList (assuming a Dictionary<>):

public static bool TryGetLanguageId(string name, out Word.WdLanguageID id)
{
    return _languageList.TryGetValue(name, out id);
}