I am trying to make a simple parser where I have key, value pairs that I would like to assign to variables. I want to map a String to a variable.
I think the below test class should express what I would like to do. But how can I store a variable so I can update it?
[TestClass]
public class StringObjectMapperTest
{
[TestMethod]
public void TestMethod1()
{
string string1 = "";
string string2 = "";
StringObjectMapper mapper = new StringObjectMapper();
mapper.Add("STRING1", ref string1);
mapper.Add("STRING2", ref string2);
mapper.Set("STRING1", "text1");
Assert.AreEqual("text1", string1); // FAILS as string1 is still ""
}
}
public class StringObjectMapper
{
private Dictionary<string, string> mapping = new Dictionary<string, string>();
public StringObjectMapper()
{
}
public void Set(string key, string value)
{
string obj = mapping[key];
obj = value;
}
internal void Add(string p, ref string string1)
{
mapping.Add(p, string1);
}
}
Update:
I am trying to use a Boxed String but this also seems to act like a immutable object, any idea why?
[TestClass]
public class StringObjectMapperTest
{
[TestMethod]
public void TestMethod1()
{
BoxedString string1 = "string1";
BoxedString string2 = "string2";
StringObjectMapper mapper = new StringObjectMapper();
mapper.Add("STRING1", ref string1);
mapper.Add("STRING2", ref string2);
mapper.Set("STRING1", "text1");
string s = string1;
Assert.AreEqual("text1", s); // Fails as s = "string1" ???
}
}
public struct BoxedString
{
private string _value;
public BoxedString(string value)
{
_value = value;
}
public void Set(string value)
{
_value = value;
}
static public implicit operator BoxedString(string value)
{
return new BoxedString(value);
}
static public implicit operator string(BoxedString boxedString)
{
return boxedString._value;
}
}
public class StringObjectMapper
{
private Dictionary<string, BoxedString> mapping = new Dictionary<string, BoxedString>();
public StringObjectMapper()
{
}
public void Set(string key, string value)
{
BoxedString obj = mapping[key];
obj.Set(value);
}
internal void Add(string p, ref BoxedString obj)
{
mapping.Add(p, obj);
}
}
You can't do this as strings are immutable. Changing a string returns a new string. Even though you pass the string by reference in Add, the string value stored in the dictionary is still immutable. Here's what happens in Set:
public void Set(string key, string value)
{
string obj = mapping[key]; // obj points to the string value at mapping[key]
obj = value; // obj points to the string value referenced by value - mapping[key] is unchanged.
}
To do what you want you'll need to "box" the string by using a true reference type - whether object or a class that wraps the string as the Dictionary's value type.
this is not what you want but this work... if you accept it :-)
use StringBuilder
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
StringBuilder string1 = new StringBuilder();
StringBuilder string2 = new StringBuilder();
StringObjectMapper mapper = new StringObjectMapper();
mapper.Add("STRING1", ref string1);
mapper.Add("STRING2", ref string2);
mapper.Set("STRING1", "text1");
Console.Write("text1" == string1.ToString());
Console.ReadKey();
}
}
public class StringObjectMapper
{
private Dictionary<string, StringBuilder> mapping = new Dictionary<string, StringBuilder>();
public StringObjectMapper()
{
}
public void Set(string key, string value)
{
StringBuilder obj = mapping[key];
obj.Clear();
obj.Append(value);
}
internal void Add(string p, ref StringBuilder string1)
{
mapping.Add(p, string1);
}
}
}
My first thought is that this isn't possible in C# without obtaining the pointer that ref string string1 represents. Unfortunately, .NET is garbage collected, which means the pointer can change unless you use a fixed block.
I think a better approach here is to use an interface that represents a way to set a string.
public interface IData
{
void Set(string data);
}
public class StringObjectMapper
{
private readonly Dictionary<string, IData> mapping = new Dictionary<string, IData>();
public void Set(string key, string value)
{
if (key == null)
{
throw new ArgumentNullException("key");
}
if (value == null)
{
throw new ArgumentNullException("value");
}
mapping[key].Set(value);
}
internal void Add(string key, IData data)
{
if (key == null)
{
throw new ArgumentNullException("key");
}
if (data == null)
{
throw new ArgumentNullException("data");
}
mapping.Add(key, data);
}
}
I guess the best way to solve this is by using delegates. Although the syntax is still a bit strange to me it seems the cleanest way to solve this. The below codes works:
[TestClass]
public class StringObjectMapperTest
{
private Dictionary<string, Setter> mapping = new Dictionary<string, Setter>();
public delegate void Setter(string v);
[TestMethod]
public void TestMethod1()
{
string string1 = "string1";
string string2 = "string2";
string text1 = "text1";
string text2 = "text2";
Add("STRING1", x => string1 = x);
Add("STRING2", x => string2 = x);
Assert.AreNotEqual(text1, string1);
Set("STRING1", text1);
Assert.AreEqual(text1, string1);
Assert.AreNotEqual(text2, string2);
Set("STRING2", text2);
Assert.AreEqual(text2, string2);
}
private void Set(string key, string value)
{
Setter set = mapping[key];
set(value);
}
private void Add(string p, Setter del)
{
mapping.Add(p, del);
}
}
Related
i have a Class like this.
public static class MyTestClass
{
[MyCustomAttribnute("MoreInformations")
public static string MyProperty => "Sample";
}
I can use the class like this.
public static void Main()
{
var myTest = MyTestClass.MyProperty;
}
Now i create a QuickInfoSource and i can get the text "MyTestClass.MyProperty" when i hover over "MyProperty". But i want do get the Type "MyTestClass" to get the customAttribute of "MyProperty".
anybody knows how to get the Type?
Here is my experimental Code of the "QuickInfoSource" class.
internal class TestQuickInfoSource : IAsyncQuickInfoSource
{
private TestQuickInfoSourceProvider m_provider;
private ITextBuffer m_subjectBuffer;
private Dictionary<string, string> m_dictionary;
public TestQuickInfoSource(TestQuickInfoSourceProvider provider, ITextBuffer subjectBuffer)
{
m_provider = provider;
m_subjectBuffer = subjectBuffer;
//these are the method names and their descriptions
m_dictionary = new Dictionary<string, string>();
m_dictionary.Add("add", "int add(int firstInt, int secondInt)\nAdds one integer to another.");
m_dictionary.Add("subtract", "int subtract(int firstInt, int secondInt)\nSubtracts one integer from another.");
m_dictionary.Add("multiply", "int multiply(int firstInt, int secondInt)\nMultiplies one integer by another.");
m_dictionary.Add("divide", "int divide(int firstInt, int secondInt)\nDivides one integer by another.");
}
public async Task<QuickInfoItem> GetQuickInfoItemAsync(IAsyncQuickInfoSession session, CancellationToken cancellationToken)
{
// Map the trigger point down to our buffer.
SnapshotPoint? subjectTriggerPoint = session.GetTriggerPoint(m_subjectBuffer.CurrentSnapshot);
if (!subjectTriggerPoint.HasValue)
{
return null;
}
ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot;
SnapshotSpan querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0);
//look for occurrences of our QuickInfo words in the span
ITextStructureNavigator navigator = m_provider.NavigatorService.GetTextStructureNavigator(m_subjectBuffer);
TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value);
SnapshotSpan span = navigator.GetSpanOfPreviousSibling(querySpan);
string searchText = extent.Span.GetText();
string searchText2 = span.GetText();
foreach (string key in m_dictionary.Keys)
{
int foundIndex = searchText.IndexOf(key, StringComparison.CurrentCultureIgnoreCase);
if (foundIndex > -1)
{
string value;
m_dictionary.TryGetValue(key, out value);
return new QuickInfoItem(session.ApplicableToSpan, value ?? string.Empty);
}
}
return null;
}
private bool m_isDisposed;
public void Dispose()
{
if (!m_isDisposed)
{
GC.SuppressFinalize(this);
m_isDisposed = true;
}
}
}
I have an abstract class like this:
public abstract class Records
{
public string Type;
public string Source;
public int Value;
protected Records(string type, string source, int value)
{
Type = type;
Source = source;
Value = value;
}
}
I would like to create many classes inheriting this class, and filling their Type field with a value coming from a static class like this:
public static class ContentTypesString
{
public static string DocumentNew { get { return "Document - New this Month"; }}
public static string HeadlinesNew { get { return "Headlines - New this Month"; }}
etc...
}
I would like to be able to create those child classes without having a test "if foo == "document" then type = ContentTypesString.DocumentNew" or an equivalent switch case (I really have a lot of cases)
Is there a design pattern that suits my needs?
EDIT : As several people pointed out, i should show how i create my instances.
private delegate SPListItemCollection Query(SPWeb web, DateTime startDate, DateTime endDate);
private readonly Query _queries;
#region Constructors
public QueryHandler(SPWeb web, DateTime startTimeSelectedDate, DateTime endTimeSelectedDate)
{
if (web == null) throw new ArgumentNullException("web");
_web = web;
_startTimeSelectedDate = startTimeSelectedDate;
_endTimeSelectedDate = endTimeSelectedDate;
RecordsList = new List<Records>();
// Query Invocation List
_queries = NumberPagePerMonthQuery.PreparedQuery;
_queries += NumberDocumentsPerMonthQuery.PreparedQuery;
_queries += NumberHeadlinesPerMonthQuery.PreparedQuery;
_queries += NumberLeaderboxPerMonthQuery.PreparedQuery;
_queries += NumberNewsPerMonthQuery.PreparedQuery;
_queries += NumberPagesModifiedPerMonthQuery.PreparedQuery;
_queries += NumberPicturesPerMonthQuery.PreparedQuery;
_queries += NumberTeasingPerMonthQuery.PreparedQuery;
}
#endregion Constructors
#region Public Methods
// what about NullReferenceException ? C#6 : item?.Foreach(item => {}); ?
/*** NO C#6 compiler in VS2012... ***/
public void Queries()
{
foreach (var del in _queries.GetInvocationList())
{
var queryresult =
(SPListItemCollection) del.DynamicInvoke(_web, _startTimeSelectedDate, _endTimeSelectedDate);
RecordsList.Add(new Records(del.Method.Name, _web.Title, queryresult.Count));
}
}
EDIT² :
The solution i chose
public List<IQuery> QueryList { get; } // no delegate anymore, and static classes became implementations of IQuery interface.
#region Constructors
public QueryHandler(SPWeb web, DateTime startTimeSelectedDate, DateTime endTimeSelectedDate)
{
if (web == null) throw new ArgumentNullException("web");
_web = web;
_startTimeSelectedDate = startTimeSelectedDate;
_endTimeSelectedDate = endTimeSelectedDate;
RecordsList = new List<Records>();
QueryList = new List<IQuery>
{
new NumberDocumentsPerMonthQuery(),
new NumberHeadlinesPerMonthQuery(),
new NumberLeaderboxPerMonthQuery(),
new NumberNewsPerMonthQuery(),
new NumberPagePerMonthQuery(),
new NumberPagesModifiedPerMonthQuery(),
new NumberPicturesPerMonthQuery(),
new NumberTeasingPerMonthQuery()
};
}
#endregion Constructors
#region Public Methods
// what about NullReferenceException ? C#6 : item?.Foreach(item => {}); ?
/*** NO C#6 compiler in VS2012... ***/
public void Queries()
{
foreach (var query in QueryList)
{
var queryresult = query.PreparedQuery(_web, _startTimeSelectedDate, _endTimeSelectedDate);
RecordsList.Add(query.CreateRecord(_web.Title, queryresult.Count));
}
}
Record class follow the implementation suggested by #dbraillon
Implementation of IQuery interface were added the method :
public Records CreateRecord(string source, int value)
{
return new ModifiedPagesPerMonthRecord(source, value); //or another child of Record class.
}
And voilĂ . Thank you all for the help.
You want to make collection of records, by string code of object type, and parameters.
One of many way to do it - use builder.
Firstly we need to configurate builder:
var builder = new RecordBuilder()
.RegisterBuilder("document", (source, value) => new Document(source, value))
.RegisterBuilder("headlines", (source, value) => new Headlines(source, value));
here we specify how to build record with code "document" and "headlines".
To build a record call:
builder.Build("document", "source", 1);
Builder code can by something like this
(here we look if we know how to build record of the passed type and make it):
public class RecordBuilder
{
public Records Build(string code, string source, int value)
{
Func<string, int, Records> buildAction;
if (recordBuilders.TryGetValue(code, out buildAction))
{
return buildAction(source, value);
}
return null;
}
public RecordBuilder RegisterBuilder(string code, Func<string, int, Records> buildAction)
{
recordBuilders.Add(code, buildAction);
return this;
}
private Dictionary<string, Func<string, int, Records>> recordBuilders = new Dictionary<string, Func<string, int, Records>> ();
}
public class Document : Records
{
public Document(string source, int value) : base(ContentTypesString.DocumentNew, source, value)
{
}
}
public class Headlines : Records
{
public Headlines(string source, int value) : base(ContentTypesString.HeadlinesNew, source, value)
{
}
}
Is that what you need ?
public abstract class Records
{
public string Type;
public string Source;
public int Value;
protected Records(string type, string source, int value)
{
Type = type;
Source = source;
Value = value;
}
}
public class DocumentRecords : Records
{
public DocumentRecords(string source, int value)
: base(ContentTypesString.DocumentNew, source, value) // use here
{
}
}
public class HeadlinesRecords : Records
{
public HeadlinesRecords(string source, int value)
: base(ContentTypesString.HeadlinesNew, source, value) // use here
{
}
}
public static class ContentTypesString
{
public static string DocumentNew { get { return "Document - New this Month"; } }
public static string HeadlinesNew { get { return "Headlines - New this Month"; } }
}
I use a 3rd party application for output. There are several int properties and I would like to handle the different properties' int values via enum.
Property1 could be 0,1,2
Property2 could be 0,1
Property3 could be 1,2
I think I should have enum inheritance which is not option in c#.
So I solved it by using classes (I'm using Tono Nam's answer from another topic to this end: https://stackoverflow.com/a/23430174/4273304).
public class MyEnum : IEquatable<MyEnum>
{
public static readonly MyEnum Undefined = new MyEnum(-1, "Undefined");
public int Value { get; private set; }
public string Name { get; private set; }
protected MyEnum(int value, string name)
{
this.Value = value;
this.Name = name;
}
public bool Equals(MyEnum b)
{
return this.Name == b.Name && this.Value == b.Value;
}
public override string ToString()
{
return this.Name;
}
public static T Parse<T>(int value)
{
object obj;
Type t_type = typeof(T);
var fiList = t_type.GetFields(BindingFlags.Public | BindingFlags.Static).Where(f => f.FieldType == typeof(T)).ToArray();
foreach(FieldInfo en in fiList)
{
object tmp = en.GetValue(null);
if (((MyEnum)tmp).Value == value)
return (T)tmp;
}
obj = MyEnum.Undefined;
return (T)obj;
}
}
public class MyEnumChild1 : MyEnum
{
public static readonly MyEnumChild1 A = new MyEnumChild1(0, "A");
public static readonly MyEnumChild1 B = new MyEnumChild1(1, "B");
private MyEnumChild1(int value, string name)
: base(value, name)
{
}
}
public class MyEnumChild2 : MyEnum
{
public static readonly MyEnumChild2 A = new MyEnumChild2(0, "A");
public static readonly MyEnumChild2 C = new MyEnumChild2(1, "C");
private MyEnumChild2(int value, string name)
: base(value, name)
{
}
}
public class MyEnumChild3 : MyEnum
{
public static readonly MyEnumChild3 D = new MyEnumChild3(0, "D");
public static readonly MyEnumChild3 E = new MyEnumChild3(1, "E");
private MyEnumChild3(int value, string name)
: base(value, name)
{
}
}
This solution serves my purposes, but I dont know how to cast an int to MyEnumChild1.
I created a parser method:
MyEnumChild1 MEC1 = MyEnum.Parse <MyEnumChild1>(1);
It seems to work fine, MEC1 is MyEnumChild1.B now, but I'm not sure of it.
How safe do you think my parser method is? Are there any mistakes in this code or can I use it safely?
Do you know any better, elegant or simpler solution for the cast?
First, your Parse method should put a constraint on T:
public static T Parse<T>(int value) where T : MyEnum
Second, you can make it protected instead and implement a casting operator in each of the derived enums this way:
public static explicit operator MyEnumChild1(int value)
{
return Parse<MyEnumChild1>(value);
}
And use it in a more classic way:
MyEnumChild1 mec1 = (MyEnumChild1)1
In our application we have some strings coming from translation that can contain variables. For example in Can i have a {beverage}? the {beverage} part should be replaced with a variable.
My current implementation works by having a Dictionary of the name and value of all variables, and just replacing the correct string. However i'd like to register the variables by reference, so that if the value is ever changed the resulting string is changed as well. Usually passing a parameter with the ref keyword would do the trick, but i'm unsure on how to store those in a Dictionary.
TranslationParser:
static class TranslationParser
{
private const string regex = "{([a-z]+)}";
private static Dictionary<string, object> variables = new Dictionary<string,object>();
public static void RegisterVariable(string name, object value)
{
if (variables.ContainsKey(name))
variables[name] = value;
else
variables.Add(name, value);
}
public static string ParseText(string text)
{
return Regex.Replace(text, regex, match =>
{
string varName = match.Groups[1].Value;
if (variables.ContainsKey(varName))
return variables[varName].ToString();
else
return match.Value;
});
}
}
main.cs
string bev = "cola";
TranslationParser.RegisterVariable("beverage", bev);
//Expected: "Can i have a cola?"
Console.WriteLine(TranslationParser.ParseText("Can i have a {beverage}?"));
bev = "fanta";
//Expected: "Can i have a fanta?"
Console.WriteLine(TranslationParser.ParseText("Can i have a {beverage}?"));
Is this possible at all, or am i just approaching the problem incorrectly? I fear that the only solution would involve unsafe code (pointers).
So in short, i'd like to store a variable in a Dictionary, change the original variable and get the changed value from the Dictionary. Like you would do with the ref keyword.
Another way to use wrappers. You can wrap your variables every time when you regiester them.
class ObjectWrapper
{
private object _value;
public ObjectWrapper(object value)
{
_value = value;
}
public override string ToString()
{
return _value.ToString();
}
}
static class TranslationParser
{
private const string regex = "{([a-z]+)}";
private static Dictionary<string, ObjectWrapper> variables = new Dictionary<string, ObjectWrapper>();
public static void RegisterVariable(string name, object value)
{
var wrapped = new ObjectWrapper(value);
if (variables.ContainsKey(name))
variables[name] = wrapped;
else
variables.Add(name, wrapped);
}
public static string ParseText(string text)
{
return Regex.Replace(text, regex, match =>
{
string varName = match.Groups[1].Value;
if (variables.ContainsKey(varName))
return variables[varName].ToString();
else
return match.Value;
});
}
}
Edit:
But actually, I think it's impossible without unsafe code to track variables in a way that you want to do. Value-types and references to reference-type stored in stack, and if you just replace reference, it will not affect to real object in heap (reference to that object you store in the dictionary). So that you need to have references (say pointers) to stack memory.
Edit again: I was wrong!
It is possible to track any varaible using expressions:
class Wrapper
{
private readonly Dictionary<string, MemberExpression> _registrations =
new Dictionary<string, MemberExpression>();
public void Register<T>(string name, Expression<Func<T>> expr)
{
_registrations[name] = (MemberExpression)expr.Body;
}
public object GetValue(string name)
{
var expr = _registrations[name];
var fieldInfo = (FieldInfo)expr.Member;
var obj = ((ConstantExpression)expr.Expression).Value;
return fieldInfo.GetValue(obj);
}
}
private static void Main(string[] args)
{
var wrapper = new Wrapper();
int x = 0;
storage.Register("x", () => x);
Console.WriteLine(wrapper.GetValue("x")); //0
x = 1;
Console.WriteLine(wrapper.GetValue("x")); //1
}
In the code provided I see
string bev = "cola";
TranslationParser.RegisterVariable("beverage", bev);
//Expected: "Can I have a cola?"
Console.WriteLine(TranslationParser.ParseText("Can I have a {beverage}?"));
bev = "fanta";
//Expected: "Can I have a fanta?"
that first you register the substitute of the {beverage} like a "cola", but after want to change it at runtime to another one: "fanta".
Thie leads me to think: why do not just a ParseText function to accept an optional parameter, which will "win" against saved one ?
Like this:
public static string ParseText(string text, string preferedValue=null)
{
return Regex.Replace(text, regex, match =>
{
string varName = match.Groups[1].Value;
if (variables.ContainsKey(varName))
{
if(!string.IsNullOrEmpty(preferedValue)) //IF THERE ISPREFERED VALUE
return preferedValue; //RETURN THAT ONE
return variables[varName].ToString();
}
else
return match.Value;
});
}
In order to explain my problem here is an example
namespace CheckAbstarct
{
class Program
{
static void Main(string[] args)
{
myAbstarctClass mac1 = ObjectFactory.ObjectCreator("aaa");
myAbstarctClass mac2 = ObjectFactory.ObjectCreator("bbb");
mac1.changeMyString();
mac2.changeMyString();
string myString = (string)mac2.returnMyObject();
DateTime myObject = (DateTime) mac1.returnMyObject();
object obj1 = mac1.returnMyObject();
object obj2 = mac2.returnMyObject();
myMethod(obj1); //---> This is not compiling
myMethod(obj2); //---> This is not compiling
myMethod(myString); //---> works fine
myMethod(myObject); //---> works fine
Console.ReadKey();
}
public static void myMethod(DateTime dt)
{
}
public static void myMethod(string st)
{
}
}
abstract class myAbstarctClass
{
protected string mMyString;
public myAbstarctClass()
{
mMyString = "myAbstarctClass ";
}
public abstract void changeMyString();
public abstract object returnMyObject();
}
class MyNewAbstractClass1 : myAbstarctClass
{
DateTime mObject;
public MyNewAbstractClass1(string myString)
{
mMyString = myString;
mObject = new DateTime().Date;
}
public override void changeMyString()
{
mMyString += " MyNewAbstractClass1";
Console.WriteLine(mMyString);
}
public override object returnMyObject()
{
return mObject;
}
}
class MyNewAbstractClass2 : myAbstarctClass
{
string mString;
public MyNewAbstractClass2(string myString)
{
mMyString = myString;
mString = mMyString;
}
public override void changeMyString()
{
mMyString += " MyNewAbstractClass2";
Console.WriteLine(mMyString);
}
public override object returnMyObject()
{
return mString;
}
}
static class ObjectFactory
{
public static myAbstarctClass ObjectCreator(string myString)
{
switch (myString)
{
case "aaa":
return new MyNewAbstractClass1(myString);
case "bbb":
return new MyNewAbstractClass2(myString);
default:
return null;
}
}
}
}
My problem is that in Main() I don't know what type the returnMyObject() method returns so I can't send it to MyMethod. Is there a way to cast the objects ??
Because in your design of returnMyObject() you went back to the most common object references, you will have to find out in runtime:
if (obj1 is string)
myMethod((string)obj1); //--->cast it
else if (obj1 is DateTime)
myMethod((DateTime) obj1);
You could check the object's type at runtime:
public static void myMethod(Object o)
{
if (o is DateTime)
myMethod((DateTime)o);
else if (o is string)
myMethod((string)o);
}
Although in your case, you might just as well pass a myAbstarctClass instance to myMethod, and then call returnMyObject() there.
You can either use dynamic feature from C# 4.0 or change design to utilize some kind of double dispatch technique
dynamic obj1 = mac1.returnMyObject();
dynamic obj2 = mac2.returnMyObject();
Use Polymorphism mechanisms so you don't need to know the type of object.
Make myMethod an abstract method of myAbstarctClass and provide implementations in both MyNewAbstractClass1 and MyNewAbstractClass2.
Modify myAbstractClass1.returnMyObject() to return myAbstarctClass (not object).
The test code in Main can then be written:
...
myAbstarctClass obj1 = mac1.returnMyObject();
myAbstarctClass obj2 = mac2.returnMyObject();
obj1.myMethod(); // calls MyNewAbstractClass1.myMethod()
// no if statement required!
obj2.myMethod(); // calls MyNewAbstractClass2.myMethod()
// no if statement required!
Console.ReadKey();
Edit: This can be further simplified, since the returnMyObject() methods are no longer necessary - they just return the object you already have. The test code is now simply:
mac1.myMethod();
mac2.myMethod();
// etc...
Console.ReadKey();
No, you have to either create switch with all possibilities, or something like Dictionary<Type, Delegate>
or you can just make myMethod(object obj)
it's called Multiple dispatch (http://en.wikipedia.org/wiki/Multiple_dispatch) and there are some libraries that can do it
Since you seem to be using your class as a container for a type (eg. DateTime, string), perhaps Generics would a be better choice than Inheritance:
namespace CheckAbstract
{
class Program
{
static void Main(string[] args)
{
myTemplateClass<DateTime> mac1 = new myTemplateClass<DateTime>(new DateTime().Date);
myTemplateClass<string> mac2 = new myTemplateClass<string>("cat dog");
mac1.changeMyString();
mac2.changeMyString();
string myString = (string)mac2.returnMyObject();
DateTime myObject = (DateTime) mac1.returnMyObject();
myMethod<string>(myString);
myMethod<DateTime>(myObject);
Console.ReadKey();
}
public static void myMethod<T>(T obj)
{
}
}
class myTemplateClass<T>
{
T mObject;
string mMyString;
public myTemplateClass(T init)
{
mMyString = init.ToString();
mObject = init;
}
public void changeMyString()
{
mMyString += " " + mObject.ToString();
Console.WriteLine(mMyString);
}
public T returnMyObject()
{
return mObject;
}
}
}