views:

53

answers:

2

This is my problem:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public abstract class EntityMember<T>
    {
        public T Value { get; set; }
    }

    public class Int32EntityMember : EntityMember<int?>
    {
    }

    public class StringEntityMember : EntityMember<string>
    {
    }

    public class GuidEntityMember : EntityMember<Guid?>
    {
    }

    public class Entity 
    {
        public GuidEntityMember ApplicationId { get; private set; }
        public Int32EntityMember ConnectedCount { get; private set; }
        public GuidEntityMember MainApplicationId { get; private set; }
        public Int32EntityMember ProcessId { get; private set; }
        public StringEntityMember ProcessName { get; private set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Entity entity2 = new Entity();
            Guid empty = Guid.NewGuid();
            Guid applicationId = Guid.NewGuid();
            int Id = 10;
            string name = "koko";

            entity2.MainApplicationId.Value = new Guid?(empty);
            entity2.ApplicationId.Value = new Guid?(applicationId);
            entity2.ProcessId.Value = new int?(Id);
            entity2.ProcessName.Value = name;
            entity2.ConnectedCount.Value = 1;
        }
    }
}

The application has totally blocked on the line:

entity2.MainApplicationId. Value = new Guid? (empty); 

Why?

A: 

Try changing the line to a type cast:

entity2.ApplicationId.Value = (Guid?)(applicationId);
kbrimington
+2  A: 

The exception you're receiving is:

Object reference not set to an instance of an object.

This is because entity2.MainApplicationId is null. Your Entity class does not have a constructor to set MainApplicationId to be not null, hence the error you're seeing.

Adding a constructor to your Entity class as shown in the code below results in your code running without error:

public Entity()
{
    ApplicationId = new GuidEntityMember();
    ConnectedCount = new Int32EntityMember();
    MainApplicationId = new GuidEntityMember();
    ProcessId = new Int32EntityMember();
    ProcessName = new StringEntityMember();
}

Using Auto-Implemented properties does not result in the underlying fields (that are created and managed on your behalf by the compiler) being new'd when the instance is constructed. Thus the two properties that follow are not the same:

public MyClass MyProperty { get; private set; }

private MyClass _myOtherProperty = new MyClass();
public MyClass MyOtherProperty
{
    get
    {
        return _myOtherProperty;
    }
    set
    {
        _myOtherProperty = value;
    }
}
Rob
In fact all the fields of `entity2` are null
ChrisF
Thank you for the answer.But for the getter and setter I think that two is the same, public MyClass myProperty (get; set;)private MyClass = new MyClass _myOtherProperty ();public MyClass MyOtherProperty( get ( _myOtherProperty return; ) together ( _myOtherProperty = value; ))
Koka
@Koka, the two are clearly *not* the same, as I've explained in the answer, because in the first "auto-property", the backing field doesn't get an instance of `MyClass` new'd up, whereas in the second example, it does.
Rob
yes , you are right.thanks.
Koka