简体   繁体   English

C#:通过方法在构造函数中设置属性

[英]C#: Set property in constructor by method

I'm beginning to understand C# and OOP, and have a problem that I can't seem to get around. 我开始了解C#和OOP,并且遇到了一个我似乎无法解决的问题。 I have a class called DataSet that should hold several properties (in the form of System.Collections.Generic.Dictionary objects). 我有一个名为DataSet的类,该类应具有多个属性(以System.Collections.Generic.Dictionary对象的形式)。 Within the class I have methods that load data from a database and these methods should be used to initialize the DataSet. 在该类中,我具有从数据库加载数据的方法,这些方法应用于初始化DataSet。 Basically, I want the DataSet object to have all properties set, when I instantiate it from the Main method. 基本上,当我从Main方法实例化它时,我希望DataSet对象具有所有属性。

What I have is the following (leaving out the details): 我所拥有的是以下内容(省略了细节):

public class DataSet
{
    public IDictionary<string, MyClass1> Property1 { get; set; };
    public IDictionary<string, MyClass2> Property2 { get; set; };
    public IDictioanry<string, MyClass3> Property3 { get; set; };

    public DataSet()
    {
            Property1 = new Dictionary<string, MyClass1>();
            Property2 = new Dictionary<string, MyClass2>();
            Property3 = new Dictionary<string, MyClass3>();
        // Set Property1
        // Set Property2
        // Set Property3 (can only be done when Property1 is known)
    }

    private void GetProperty1(/* something? */)
    {
        // Loads the data from a database.
    }

    private static Dictionary<string, MyClass1> GetProperty1Alternative(DataSet dataSet)
    {
        // Same thing but static, so needs instance ref.
    }

    // Similarly for Property2 and Property3
}

What I would like is to have the properties set in the constructor. 我想要的是在构造函数中设置属性。 My questions are basically: 我的问题基本上是:

  1. Is what I am doing at all the right way to do it? 我在做什么是正确的方式吗?
  2. If yes, should I make my methods static (and pass an instance by reference to the methods), which would require the class DataSet to be static (and all its properties) or is there a way to do what I am doing without making DataSet static? 如果是,我应该将我的方法设为静态(并通过引用该方法传递实例),这将要求DataSet类为静态(及其所有属性),还是可以在不使DataSet不变的情况下做我正在做的事情静态的?
  3. An important issue is that Property3 can only be set once Property1 is known/set. 一个重要的问题是,只有在知道/设置Property1后才能设置Property3。 I have no idea if that is possible... 我不知道那是否可能...

Any help is greatly appreciated. 任何帮助是极大的赞赏。

There are a few issues in your code. 您的代码中有一些问题。 You have made the properties public so it doesn't really make sense to also have GetProperty1. 您已将属性公开,因此也没有GetProperty1确实没有任何意义。 An alternative would be to make the dictionaries private variables instead then you can have: 另一种选择是使字典成为私有变量,而不是这样:

public IDictionary<string,MyClass1> GetProperty1()
{
    if ( _property1 == null )
    {
        _property1 = LoadFromDatabase();
    }
    return _property1;
}

Likewise for property3, you can also check that proeprty1 is not null before you create and return it but you would also then need to decide what to do (automatically load property 1 first or otherwise return null for property3) 同样,对于property3,您还可以在创建和返回proeprty1之前先检查其是否为null,但同时还需要决定要做什么(首先自动加载property 1,否则为property3返回null)

You can use following code. 您可以使用以下代码。 It can solve you several issues. 它可以解决您几个问题。

public class DataSet
{
    private DataSet()
    {
    }

    public DataSet _instance = null;
    public static DataSet Instance
    {
       get{ if (_instance = null){_instance = new DataSet();}return _instance;}
    }


    private IDictionary<string, MyClass1> _property1 = null;
    public IDictionary<string, MyClass1> Property1
    {
        get
        {
           result = _property;
           if (result == null)
           {
             //read database
           } 
           return result;
        }
    }

Why not add a public function eg LoadData() that could be called after your object has been constructed. 为什么不添加一个公共函数,例如LoadData(),就可以在构造对象之后调用它。 This could load all your data in using the correct order. 这样可以使用正确的顺序加载所有数据。 I suppose you could have call it in the constructor even. 我想您甚至可以在构造函数中调用它。 I would also follow the advice of Lukos and make some private member variables with public get properties. 我还将遵循Lukos的建议,并使用public get属性创建一些私有成员变量。

It seems to me you need to load your dictionary and then want to cache it. 在我看来,您需要加载字典,然后再对其进行缓存。 You can do this lazily in the property getter: 您可以在属性获取器中懒惰地执行此操作:

public class DataSet
{
    private IDictionary<string, MyClass> property;

    public IDictionary<string, MyClass> Property
    {
        if (property == null)
        {
            property = LoadProperty();
        }
        return property;
    }
}

or eagerly in the constructor: 或渴望在构造函数中:

public class DataSet
{
    public IDictionary<string, MyClass1> Property { get; private set; }    

    public DataSet()
    {
        Property = LoadProperty();
    }
}

Also, having this method doesn make much sense: 同样,使用此方法没有多大意义:

private static Dictionary<string, MyClass1> GetProperty1Alternative(DataSet dataSet)

Instead of calling this like so: 而不是这样称呼:

DataSet.GetProperty1Alternative(anInstance);

you can simply do this: 您可以简单地做到这一点:

anIntance.Property;

Is what I am doing at all the right way to do it? 我在做什么是正确的方式吗?

You're not that far off. 距离您不远。 I think many people are confusing your Get functions to be the conventional 'getter', so you should rename it. 我认为许多人将您的Get函数混淆为常规的“ getter”,因此您应该对其进行重命名。

If yes, should I make my methods static (and pass an instance by reference to the methods), which would require the class DataSet to be static (and all its properties) or is there a way to do what I am doing without making DataSet static? 如果是,我应该将我的方法设为静态(并通过引用该方法传递实例),这将要求DataSet类为静态(及其所有属性),还是可以在不使DataSet不变的情况下做我正在做的事情静态的?

You could make the methods actually loading the data static, and you don't need to pass an instance - you can just return the data. 您可以将实际加载数据的方法设为静态,而无需传递实例-您只需返回数据即可。 (I've changed thefunction name). (我更改了功能名称)。 It's fine to call a static method from the instance/constructor, but not the other way around. 从实例/构造函数中调用静态方法很好,但反之则不行。

public DataSet()
{
        Property1 = LoadProperty1();
        Property2 = LoadProperty2();
        Property3 = LoadProperty3();//can only be done when Property1 is known
}

private static Dictionary<string, MyClass1> LoadProperty1()
{
    // load data
}

An important issue is that Property3 can only be set once Property1 is known/set. 一个重要的问题是,只有在知道/设置Property1后才能设置Property3。 I have no idea if that is possible... 我不知道那是否可能...

As you see, this is solved in the above code. 如您所见,以上代码已解决了这一问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM