Solved

C# cannot access non-static property in static context from base class

Posted on 2016-09-09
5
52 Views
Last Modified: 2016-09-12
I do not understand what I am doing wrong:

Base Class:
using System;

namespace Common
{
    public class CommonBase
    {
        public DateTime DateTimeNullValue { get; set; }
        public Guid GuidNullValue { get; set; }
        public int IntNullValue { get; set; }
        public float FloatNullValue { get; set; }
        public decimal DecimalNullValue { get; set; }
        public string StringNullValue { get; set; }
    }
}

Open in new window


Derived class:
namespace Common
{
    public abstract class DtoBase : CommonBase
    {
        public bool IsNew { get; set; }
    }
}

Open in new window


Abstract class:
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace DAL
{
    public abstract class DalBase
    {
        // CreateParameter - uniqueidentifier
        protected static SqlParameter CreateParameter(string name, Guid value)
        {
            if (value.Equals(Common.DtoBase.GuidNullValue)) // Error at GuidNullValue
            {
                // If value is null then create a null parameter
                return CreateNullParameter(name, SqlDbType.UniqueIdentifier);
            }
            else
            {
                var parameter = new SqlParameter
                {
                    SqlDbType = SqlDbType.UniqueIdentifier,
                    ParameterName = name,
                    Value = value,
                    Direction = ParameterDirection.Input
                };
                return parameter;
            }
        }
    }
}

Open in new window


Get error trying to use GuidNullValue in the method.  Why can I not call it through the derived class?
0
Comment
Question by:Tim Word
  • 2
  • 2
5 Comments
 
LVL 74

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 100 total points
ID: 41791342
This syntax:

Common.DtoBase.GuidNullValue

...doesn't make sense. Your classes are not static. They have to be instantiated. You can only refer to your properties by way of an instance. Either that, or you need to change your properties to be static, which wouldn't make sense to me..at least from what I see above.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 41791343
Also, what is the goal here?
0
 

Author Comment

by:Tim Word
ID: 41791419
protected static SqlParameter CreateParameter is static.  CommonBase and DtoBase is creating a null for each type to be used in DAL, BAL, GUI, etc. So, the DalBase (Data Access Layer Base) class is using the null reference of the type GUID to test if the passed GUID value is null return Null Parameter else create a returned parameter.

        // CreateNullParameter
        protected static SqlParameter CreateNullParameter(string name, SqlDbType paramType)
        {
            SqlParameter parameter = new SqlParameter
            {
                SqlDbType = paramType,
                ParameterName = name,
                Direction = ParameterDirection.Input
            };
            return parameter;
        }

        // CreateNullParameter - with size for nvarchars
        protected static SqlParameter CreateNullParameter(string name, SqlDbType paramType, int size)
        {
            SqlParameter parameter = new SqlParameter
            {
                SqlDbType = paramType,
                ParameterName = name,
                Size = size,
                Value = null,
                Direction = ParameterDirection.Input
            };
            return parameter;
        }

Open in new window

0
 
LVL 32

Accepted Solution

by:
it_saige earned 400 total points
ID: 41791631
What Kaufmed is saying is that the classes you have presented (Base, Derived and Abstract) are not static, therefore in order to use their non-static members you have to instantiate the class; e.g. -
namespace Common
{
	public class CommonBase
	{
		public DateTime DateTimeNullValue { get; set; }
		public Guid GuidNullValue { get; set; }
		public int IntNullValue { get; set; }
		public float FloatNullValue { get; set; }
		public decimal DecimalNullValue { get; set; }
		public string StringNullValue { get; set; }
	}

	public class DtoBase : CommonBase
	{
		public bool IsNew { get; set; }
	}
}

namespace DAL
{
	public abstract class DalBase
	{
		// CreateParameter - uniqueidentifier
		protected static SqlParameter CreateParameter(string name, Guid value)
		{
			if (value.Equals(new Common.DtoBase().GuidNullValue)) // Error at GuidNullValue
			{
				// If value is null then create a null parameter
				return CreateNullParameter(name, SqlDbType.UniqueIdentifier);
			}
			else
			{
				var parameter = new SqlParameter
				{
					SqlDbType = SqlDbType.UniqueIdentifier,
					ParameterName = name,
					Value = value,
					Direction = ParameterDirection.Input
				};
				return parameter;
			}
		}
	}
}

Open in new window

Get's rid of your error.

I believe that I understand what you want to accomplish, this (unfortunately) will not give you the results that you want.

Why?

Well because you state (in your code) that these will be null values and the only one that is actually nullable (by default) and therefore can contain a null value is *string*.

Proof?

Consider the following:
using System;
using System.Reflection;

namespace EE_Q28968768
{
	class Program
	{
		static void Main(string[] args)
		{
			var defaults = new Defaults();
			defaults.PrintPropertyInformation();
			Console.ReadLine();
		}
	}

	class Defaults
	{
		public DateTime DateTime { get; set; }
		public Guid Guid { get; set; }
		public short Short { get; set; }
		public ushort UShort { get; set; }
		public int Integer { get; set; }
		public uint UInteger { get; set; }
		public long Long { get; set; }
		public ulong ULong { get; set; }
		public double Double { get; set; }
		public float Float { get; set; }
		public decimal Decimal { get; set; }
		public char Character { get; set; }
		public string String { get; set; }
		public IntPtr IntPtr { get; set; }
	}

	static class Extensions
	{
		public static bool IsNullOrDefault<T>(this T source)
		{
			if (source == null) return true;
			if (object.Equals(source, default(T))) return true;
			Type methodType = typeof(T);
			if (Nullable.GetUnderlyingType(methodType) != null) return false;
			Type argumentType = source.GetType();
			if (argumentType.IsValueType && argumentType != methodType)
			{
				object o = Activator.CreateInstance(source.GetType());
				return o.Equals(source);
			}
			return false;
		}

		public static bool IsNullable(this object source)
		{
			if (source == null) return true; // No need to go any further, since the source equals null we know it supports null.
			Type type = source.GetType();
			if (!type.IsValueType) return true; // Reference types are nullable by default.  Value types are not.
			if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T> or ? has been declared for this type implementation.
			return false; // Standard value type, not made nullable.
		}

		public static void PrintPropertyInformation<T>(this T source)
		{
			if (source != null)
			{
				Console.WriteLine("Displaying properties for {0}", typeof(T).Name);
				foreach (PropertyInfo property in typeof(T).GetProperties())
				{
					var value = property.GetValue(source, null);
					Console.WriteLine("Name: {0}; Value: {1}; IsNullOrDefault: {2}; IsNull: {3}; IsNullable: {4}", property.Name, value, value.IsNullOrDefault(), (value == null), value.IsNullable());
				}
			}
		}
	}
}

Open in new window

Which produces the following output -Capture.JPGIn order to change this behaviour so that you can support your nullable values, you must either use 'Nullable<T>' or the nullable operator, '?'; e.g. -
class Defaults
{
	public Nullable<DateTime> DateTime { get; set; }
	public Nullable<Guid> Guid { get; set; }
	public Nullable<short> Short { get; set; }
	public Nullable<ushort> UShort { get; set; }
	public Nullable<int> Integer { get; set; }
	public Nullable<uint> UInteger { get; set; }
	public Nullable<long> Long { get; set; }
	public Nullable<ulong> ULong { get; set; }
	public Nullable<double> Double { get; set; }
	public Nullable<float> Float { get; set; }
	public Nullable<decimal> Decimal { get; set; }
	public Nullable<char> Character { get; set; }
	public string String { get; set; }
	public Nullable<IntPtr> IntPtr { get; set; }
}

Open in new window

-Or-
class Defaults
{
	public DateTime? DateTime { get; set; }
	public Guid? Guid { get; set; }
	public short? Short { get; set; }
	public ushort? UShort { get; set; }
	public int? Integer { get; set; }
	public uint? UInteger { get; set; }
	public long? Long { get; set; }
	public ulong? ULong { get; set; }
	public double? Double { get; set; }
	public float? Float { get; set; }
	public decimal? Decimal { get; set; }
	public char? Character { get; set; }
	public string String { get; set; }
	public IntPtr? IntPtr { get; set; }
}

Open in new window

Each of which change the output accordingly -Capture.JPG
But why try to reinvent the wheel.  .NET already has methods with which to determine the if the type supports null-ability and retrieving the underlying value type.  In reality, I believe you are probably trying to do something like:
static class Extensions
{
	public static bool IsNullOrDefault<T>(this T source)
	{
		if (source == null) return true;
		if (object.Equals(source, default(T))) return true;
		Type methodType = typeof(T);
		if (Nullable.GetUnderlyingType(methodType) != null) return false;
		Type argumentType = source.GetType();
		if (argumentType.IsValueType && argumentType != methodType)
		{
			object o = Activator.CreateInstance(source.GetType());
			return o.Equals(source);
		}
		return false;
	}

	public static bool IsNullable(this object source)
	{
		if (source == null) return true; // No need to go any further, since the source equals null we know it supports null.
		Type type = source.GetType();
		if (!type.IsValueType) return true; // Reference types are nullable by default.  Value types are not.
		if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T> or ? has been declared for this type implementation.
		return false; // Standard value type, not made nullable.
	}

	public static SqlParameter CreateParameter<T>(this T value, string name, int size = -1)
	{
		SqlParameter result = default(SqlParameter);
		try
		{
			result.Direction = ParameterDirection.Input;
			result.ParameterName = name;
			if (size > -1)
				result.Size = size;
			if (!value.IsNullable())
			{
				result.SqlDbType = DbTypeMapper.ToSqlDbType(typeof(T));
				result.Value = value;
			}
			else
			{
				result.SqlDbType = DbTypeMapper.ToSqlDbType(value.GetType());
				result.Value = null;
			}
		}
		catch (Exception)
		{
			// Exception thrown.  Log it?
			result = default(SqlParameter);
		}
		return result;
	}
}

public sealed class DbTypeMapper
{
	/// <summary>Struct DbTypeMapEntry</summary>
	private struct DbTypeMapEntry
	{
		/// <summary>Gets the Type.</summary>
		/// <value>The Type.</value>
		public Type Type { get; private set; }

		/// <summary>Gets the DbType.</summary>
		/// <value>The DbType.</value>
		public DbType DbType { get; private set; }

		/// <summary>Gets the SqlDbType.</summary>
		/// <value>The SqlDbType.</value>
		public SqlDbType SqlDbType { get; private set; }

		/// <summary>Initializes a new instance of the <see cref="DbTypeMapEntry"/> struct.</summary>
		/// <param name="type">The Type.</param>
		/// <param name="dbType">The DbType.</param>
		/// <param name="sqlDbType">The SqlDbType.</param>
		public DbTypeMapEntry(Type type, DbType dbType, SqlDbType sqlDbType) : this()
		{
			Type = type;
			DbType = dbType;
			SqlDbType = sqlDbType;
		}

		/// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary>
		/// <returns>A <see cref="System.String" /> that represents this instance.</returns>
		public override string ToString()
		{
			return string.Format("Type: {0}; DBType: {1}; SqlDbType: {2}", Type.FullName, DbType, SqlDbType);
		}
	}

	private static readonly List<Nullable<DbTypeMapEntry>> TypeMapEntries;
	public static void PrintEntries()
	{
		foreach (var entry in TypeMapEntries)
			Console.WriteLine(entry);
	}

	#region "Constructors"
	/// <summary>Initializes static members of the <see cref="DbTypeMapper" /> class.</summary>
	static DbTypeMapper()
	{
		if (TypeMapEntries == null)
		{
			TypeMapEntries = new List<Nullable<DbTypeMapEntry>> 
			{
				new DbTypeMapEntry(typeof(bool), DbType.Boolean, SqlDbType.Bit),
				new DbTypeMapEntry(typeof(byte), DbType.Double, SqlDbType.TinyInt),
				new DbTypeMapEntry(typeof(byte[]), DbType.Binary, SqlDbType.Image),
				new DbTypeMapEntry(typeof(DateTime), DbType.DateTime, SqlDbType.DateTime),
				new DbTypeMapEntry(typeof(Decimal), DbType.Decimal, SqlDbType.Decimal),
				new DbTypeMapEntry(typeof(double), DbType.Double, SqlDbType.Float),
				new DbTypeMapEntry(typeof(Guid), DbType.Guid, SqlDbType.UniqueIdentifier),
				new DbTypeMapEntry(typeof(Int16), DbType.Int16, SqlDbType.SmallInt),
				new DbTypeMapEntry(typeof(Int32), DbType.Int32, SqlDbType.Int),
				new DbTypeMapEntry(typeof(Int64), DbType.Int64, SqlDbType.BigInt),
				new DbTypeMapEntry(typeof(object), DbType.Object, SqlDbType.Variant),
				new DbTypeMapEntry(typeof(string), DbType.String, SqlDbType.VarChar),
				new DbTypeMapEntry(typeof(string), DbType.String, SqlDbType.NVarChar)
			};
		}
	}

	/// <summary>Prevents a default instance of the <see cref="DbTypeMapper"/> class from being created.</summary>
	private DbTypeMapper() { ;}
	#endregion

	#region "Methods"
	/// <summary>Convert db type to .Net data type</summary>
	/// <param name="dbType">The DbType to find.</param>
	/// <returns>Type.</returns>
	public static Type ToNetType(DbType dbType)
	{
		return Find(dbType).Type;
	}

	/// <summary>Convert TSQL type to .Net data type</summary>
	/// <param name="sqlDbType">The SqlDbType to find.</param>
	/// <returns>Type.</returns>
	public static Type ToNetType(SqlDbType sqlDbType)
	{
		return Find(sqlDbType).Type;
	}

	/// <summary>Convert TSQL type to .Net data type</summary>
	/// <param name="name">The name of the SqlDbType to find.</param>
	/// <returns>Type.</returns>
	public static Type ToNetType(string name)
	{
		return Find(name).Type;
	}

	/// <summary>Convert .Net type to Db type</summary>
	/// <param name="type">The type to find.</param>
	/// <returns>DbType.</returns>
	public static DbType ToDbType(Type type)
	{
		return Find(type).DbType;
	}

	/// <summary>Convert TSQL data type to DbType</summary>
	/// <param name="sqlDbType">The SqlDbType to find.</param>
	/// <returns>DbType.</returns>
	public static DbType ToDbType(SqlDbType sqlDbType)
	{
		return Find(sqlDbType).DbType;
	}

	/// <summary>Convert TSQL data type to DbType</summary>
	/// <param name="name">The name of the SqlDbType to find.</param>
	/// <returns>DbType.</returns>
	public static DbType ToDbType(string name)
	{
		return Find(name).DbType;
	}

	/// <summary>Convert .Net type to TSQL data type</summary>
	/// <param name="type">The type to find.</param>
	/// <returns>SqlDbType.</returns>
	public static SqlDbType ToSqlDbType(Type type)
	{
		return Find(type).SqlDbType;
	}

	/// <summary>Convert DbType type to TSQL data type</summary>
	/// <param name="dbType">The DbType to find.</param>
	/// <returns>SqlDbType.</returns>
	public static SqlDbType ToSqlDbType(DbType dbType)
	{
		return Find(dbType).SqlDbType;
	}

	/// <summary>Convert DbType type to TSQL data type</summary>
	/// <param name="name">The name of the DbType to find.</param>
	/// <returns>SqlDbType.</returns>
	public static SqlDbType ToSqlDbType(string name)
	{
		return Find(name).SqlDbType;
	}

	private static DbTypeMapEntry Find(Type type)
	{
		var result = TypeMapEntries.FirstOrDefault(x => x.HasValue && (x.Value.Type == (Nullable.GetUnderlyingType(type) ?? type)));
		if (result == null)
			throw new ApplicationException("Referenced an unsupported Type");
		return result.Value;
	}

	private static DbTypeMapEntry Find(DbType dbType)
	{
		var result = TypeMapEntries.FirstOrDefault(x => x.HasValue && (x.Value.DbType == dbType));
		if (result == null)
			throw new ApplicationException("Referenced an unsupported Type");
		return result.Value;
	}

	private static DbTypeMapEntry Find(SqlDbType sqlDbType)
	{
		var result = TypeMapEntries.FirstOrDefault(x => x.HasValue && (x.Value.SqlDbType == sqlDbType));
		if (result == null)
			throw new ApplicationException("Referenced an unsupported Type");
		return result.Value;
	}

	private static DbTypeMapEntry Find(string name)
	{
		var result = TypeMapEntries.FirstOrDefault(x => x.HasValue && x.ToString().IndexOf(name, StringComparison.OrdinalIgnoreCase) > -1);
		if (result == null)
			throw new ApplicationException("Referenced an unsupported Type");
		return result.Value;
	}
	#endregion
}

Open in new window


-saige-
1
 

Author Closing Comment

by:Tim Word
ID: 41794317
Thanks to you both.  I will rework the code. Trying to do EF without using EF.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Recently while returning home from work my wife (another .NET developer) was murmuring something. On further poking she said that she has been assigned a task where she has to serialize and deserialize objects and she is afraid of serialization. Wha…
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now