calling constructor with generic parameter instead of explicit - c#

I assume this question is duplicated.
But I could not find this question on SO
I want to instantiate a generic class. But if there is a constructor with a
explicit parameter And the generic constructor also has that parameter due to the given type, the constructor with the explicit parameter is used.
Example
class Program
{
static void Main(string[] args)
{
Example<string> test = new Example<string>("test");
test.Print();//Prints test2
}
}
class Example<T>
{
private object Value;
public Example(T value1)
{
this.Value = value1 + "1";
}
public Example(string value2)
{
this.Value = value2 + "2";
}
public void Print()
{
Console.WriteLine(Value as string);
}
}
Is there a way to call the generic constructor?

You can use syntax like below with named parameters:
Example<string> test = new Example<string>(value1: "test");
The important trick here is to have different parameter names as you currently have, so it will map the right constructor from the parameter name and the code will look like this:
using System;
public class Program
{
public static void Main()
{
Example<string> test = new Example<string>(value1: "test");
test.Print();//Prints test1
}
class Example<T>
{
private object Value;
public Example(T value1)
{
this.Value = value1 + "1";
}
public Example(string value2)
{
this.Value = value2 + "2";
}
public void Print()
{
Console.WriteLine(Value as string);
}
}
}
You can find here documentation on named parameters as well.

Related

Generic class for enumerations - casting issue

I want to write a generic class that accepts enumerations. Since this class is intended to implement some interfaces, the main aim is to be able to treat enumerations as other objects implementing those interfaces(e.g. for list extensions, etc). Hence, for a sample enum
public enum QEnum : int
{
xlNoValue = 0,
xlSomeValue = 1
}
public static class QEnumExtensions
{
public static string toString(this QEnum xThis)
{
...
}
public static QEnum toEnum(this string xThis)
{
...
}
}
I would like to declare a generic class such as
public class QEnumHolder<T> where T : struct, IConvertible
{
private T mxVal = default(T);
public QEnumHolder()
{
if (!typeof(T).IsEnum) throw new NotSupportedException();
}
public QEnumHolder(T xVal)
{
if (!typeof(T).IsEnum) throw new NotSupportedException();
mxVal = xVal;
}
static public implicit operator QEnumHolder<T>(T xVal)
{
return new QEnumHolder<T>(xVal);
}
static public implicit operator T(QEnumHolder<T> xVal)
{
return (T)xVal.mxVal;
}
public string toString()
{
if (mxVal is QEnum) return ((QEnum)Convert.ToInt32(mxVal)).toString();
...
}
public void fromString(string xString)
{
if (mxVal is QEnum)
mxVal = (???)xString.toEnum(); // problem
}
}
All of the enumerations that we use implement
toString() function which returns a "nice" string that can go into comboBoxes, etc
conversion of string to enumeration, as above
hence the structure of toString/toEnum is pretty much given. The problem is with the last code line marked "problem". I have no idea how to tell the compiler that in this branch, the return type of toEnum() and T will be the same.
I tried to circumvent the problem by declaring mxVal as int and using Convert.ToInt32 everywhere. However, then I run into problem in the operator T where the compiler has objections against converting int to a T (the compiler can't know that T will be enum, hence I can't use none of the "int to enum conversion" discussions here on SO).
A better design would be to use some naming convention, put all your enum extension methods in one and the same static class, and bind these functions inside your holder class static constructor. Something like this:
public static partial class MyEnumExtensions
{
public static MyEnumHolder<T> ToHolder<T>(this T source)
where T : struct, IConvertible
{
return new MyEnumHolder<T>(source);
}
}
public class MyEnumHolder<T> where T : struct, IConvertible
{
static readonly Func<T, string> toStringFunc;
static readonly Func<string, T> toEnumFunc;
static MyEnumHolder()
{
if (!typeof(T).IsEnum) throw new NotSupportedException();
// Use your naming conventions
var name = typeof(T).Name;
toStringFunc = (Func<T, string>)Delegate.CreateDelegate(typeof(Func<T, string>),
typeof(MyEnumExtensions).GetMethod("toString", new[] { typeof(T) }));
toEnumFunc = (Func<string, T>)Delegate.CreateDelegate(typeof(Func<string, T>),
typeof(MyEnumExtensions).GetMethod("to" + name, new[] { typeof(string) }));
}
private T value;
public MyEnumHolder() { value = default(T); }
public MyEnumHolder(T value) { this.value = value; }
static public implicit operator MyEnumHolder<T>(T x) { return new MyEnumHolder<T>(x); }
static public implicit operator T(MyEnumHolder<T> x) { return x.value; }
public string toString()
{
return toStringFunc(value);
}
public void fromString(string xString)
{
value = toEnumFunc(xString);
}
}
Sample enum definitions (could be in separate files, but must be inside the same project):
public enum MyEnumA { A1, A2, A3 }
partial class MyEnumExtensions
{
public static string toString(this MyEnumA x)
{
//...
return x.ToString();
}
public static MyEnumA toMyEnumA(this string x)
{
//...
return (MyEnumA)Enum.Parse(typeof(MyEnumA), x);
}
}
and
public enum MyEnumB { B1, B2, B3 }
partial class MyEnumExtensions
{
public static string toString(this MyEnumB x)
{
//...
return x.ToString();
}
public static MyEnumB toMyEnumB(this string x)
{
//...
return (MyEnumB)Enum.Parse(typeof(MyEnumB), x);
}
}
test:
var a = MyEnumA.A1.ToHolder();
var sA = a.toString();
a.fromString("A2");
var b = MyEnumB.B2.ToHolder();
var sB = b.toString();
b.fromString("B1");
mxVal = (T)(object)xString.toEnum();

Ambiguous constructor call error

I have a class called Test which has a constructor to accept Action<T> and the other one accepts Func<T,T>. Please see the below snippet.
public class Test<T>
{
//constructors
public Test() { }
public Test(Action<T> action) { }
public Test(Func<T, T> action) { }
//methods with same signature of constructor
public void MyMethod1(Action<T> action) { }
public void MyMethod2(Func<T, T> action) { }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Test<string> t1 = new Test<string>(this.MyMethod1);
Test<string> t2 = new Test<string>(this.MyMethod2);
Test<string> t = new Test<string>();
t.MyMethod1(MyMethod1);
t.MyMethod2(MyMethod2);
}
public void MyMethod1(string value) { }
public string MyMethod2(string value) { return string.Empty; }
}
But below lines throws an ambiguous call error
Test<string> t1 = new Test<string>(this.MyMethod1);
Test<string> t2 = new Test<string>(this.MyMethod2);
and the interesting point is, I have two methods with the same signature of my Test class constructor which not throwing any ambiguous error
Test<string> t = new Test<string>();
t.MyMethod1(MyMethod1);
t.MyMethod2(MyMethod2);
Could anyone please help me to identify and fix the issue.
The return value of a method is not part of its signature. Only the parameters are considered. Hence, the compiler cannot distinguish between Action<T> and Func<T,T>. A detailed explanation and workarounds can be found in this StackOverflow question
You can try renaming the parameters for each of your constructors like so:
public class Test<T>
{
public Test() { }
public Test(Action<T> action) { }
public Test(Func<T,T> function) { }
}
So when you instantiate your class you can specify the name of the parameter like so:
var objectWithAction = new Test<string>(action: Method1);
var objectWithFunction = new Test<string>(function: Method2);
Fact
method / constructor overloading can recognize the correct method by the parameter types but does not include the return type.
Reason
And since in both of the mentioned constructor calls in the question the parameter is of type MethodGroup so the compiler is unable to determine the correct overload. secondly calls to the method are successful as that in not an overloading scenario.
Resolution
here are the possible options to solve the issue
wrapping the method call into an anonymous method call and let the implicit conversion to distinguish themselves.
Test<string> t1 = new Test<string>(s => this.MyMethod1(s));
Test<string> t2 = new Test<string>(s => { return this.MyMethod2(s); });
result
Alternate approach
other option is to explicitly cast the method group
Test<string> t1 = new Test<string>((Action<string>)this.MyMethod1);
Test<string> t2 = new Test<string>((Func<string, string>)this.MyMethod2);
this is bit longer then the first approach if parameters are less
here a working console application sample
class Program
{
static void Main(string[] args)
{
Test<string> t1 = new Test<string>(action: MyMethod1);
Test<string> t2 = new Test<string>(function: MyMethod2);
Test<string> t = new Test<string>();
t.MyMethod1(MyMethod1);
t.MyMethod2(MyMethod2);
}
public static void MyMethod1(string value)
{
Console.WriteLine("my method1 {0}", value);
}
public static string MyMethod2(string value)
{
Console.WriteLine("my method2 {0}", value);
return string.Empty;
}
}
public class Test<T>
{
//constructors
public Test() { }
public Test(Action<T> action)
{
object args = "action";
action.Invoke((T)args); // here you should invoke the method in order to execute it
}
public Test(Func<T, T> function)
{
object args = "function";
function.Invoke((T)args);
}
//methods with same signature of constructor
public void MyMethod1(Action<T> action)
{
object args = "Method 3";
action.Invoke((T)args);
}
public void MyMethod2(Func<T, T> action)
{
object args = "Method 4";
action.Invoke((T)args);
}
}
hope it will help you
regards

Delegates to generic operations where the generic type is unknown. How to create something like that?

Suppose I have the following code.
static class Store<T> {
public static T A;
public static T B;
public static T C;
}
public static class Store {
public static Value A = new Value(<T>(v) => Store<T>.A = v); //just an example of what I want
public static Value B = new Value(<T>(v) => Store<T>.B = v); //just an example of what I want
public static Value C = new Value(SetC<T>); //just an example of what I want
public static void SetA<T>(T value) { Store<T>.A = value; }
public static void SetB<T>(T value) { Store<T>.B = value; }
public static void SetC<T>(T value) { Store<T>.C = value; }
}
public class Value {
Action<T><T> _valueChanger; //just an example of what I want
public Value(Action<T><T> valueChanger) { //just an example of what I want
_valueChanger = valueChanger;
}
public void SetValue<T> (T value) {
_valueChanger<T>(value); //just an example of what I want
}
}
I want to write Store.A.SetValue(42) so that the value is saved to Store<int>.A. What can I write instead of the lines marked by "just an example of what I want" to make that happen? (I want to explore a solution that doesn't involve dictionaries or something similar)
Rephrasing the question:
I want to modify class Value (define some fields, write a constructor and write the method Value.SetValue(T value) ), then construct three different variables of type Value (A, B, C) in such a way that when I call Store.A.SetValue(42) the value Store<int>.A is changed to 42.
Another variation of the classes:
static class Holder<T> {
T Value { get; set; }
}
static class Store2<T> {
public static Holder<T> A = new Holder<T>();
public static Holder<T> B = new Holder<T>();
public static Holder<T> C = new Holder<T>();
}
public static class Store2 {
public static Value A = new Value2(Store2<>.A); //just an example of what I want
public static Value B = new Value2(Store2<>.B); //passing non-specific generic expression
public static Value C = new Value3({TFree}() => Store2<TFree>.C); //just an example of what I want
}
public class Value2 { //Non-generic class!
Holder{TFree}<TFree> _holder; //just an example of what I want
public Value(Holder{TFree}<TFree> holder) { //just an example of what I want
_holder = holder;
}
public void SetValue<T> (T value) {
_holder{T}.Value = value; //just an example of what I want
}
}
public class Value3 { //Non-generic class! (Another variation)
Func{TFree}<Holder<TFree>> _holderFactory; //just an example of what I want
public Value(Func{TFree}<Holder<TFree>> holderFactory) { //just an example of what I want
_holderFactory = holderFactory;
}
public void SetValue<T> (T value) {
Holder<T> holder = _holderFactory{T}(); //just an example of what I want
holder.Value = value;
}
}
Solution:
An easy reflection-free and collection-free solution was found using the answers to another question ( Emulating delegates with free generic type parameters in C# and Emulating delegates with free generic type parameters in C#). The solution is Delegates to generic operations where the generic type is unknown. How to create something like that?.
Use an array to store the values and access them through a property using an index
public static class Store<T>
{
public static readonly T[] Values = new T[3];
public static T A { get { return Values[0]; } set { Values[0] = value; } }
public static T B { get { return Values[1]; } set { Values[1] = value; } }
public static T C { get { return Values[2]; } set { Values[2] = value; } }
}
public static class Store
{
public static readonly Value A = new Value(0);
public static readonly Value B = new Value(1);
public static readonly Value C = new Value(2);
}
public class Value
{
private int _index;
public Value(int index)
{
_index = index;
}
public void SetValue<T>(T value)
{
Store<T>.Values[_index] = value;
}
public T GetValue<T>()
{
return Store<T>.Values[_index];
}
}
Since the constructor of Value is not aware of any generic type parameter, you cannot have any reference to a specific Store<T>.
UPDATE
Be aware of the fact that a copy of Store<T> will be created for every distinct type argument that you supplied for T. See this example
Store.A.SetValue(42);
Store.A.SetValue("Douglas Adams");
Store.A.SetValue(new DirectoryInfo(#"C:\"));
Store.A.SetValue(new List<int>());
var x1 = Store.A.GetValue<int>(); // --> 42
var x2 = Store.A.GetValue<string>(); // --> "Douglas Adams"
var x3 = Store.A.GetValue<DirectoryInfo>(); // --> DirectoryInfo{ C:\ }
var x4 = Store.A.GetValue<List<int>>(); // --> List<int>{ Count = 0 }
By using the debugger, you will see that four different values are stored in A at the same time! Of cause these are four differents A's that exist in four diffferent Store<T>.
The problem turned out to be solvable. Mike-z gave me a nearly right solution for the delegate-to-generic-method problem ( Emulating delegates with free generic type parameters in C#) which I modified to be a full solution: ( Emulating delegates with free generic type parameters in C#).
The solution this question becomes easy too. Interfaces can contain generic methods and we can use the interface-valued variables to store links to generic methods without specifying concrete type arguments. The following code utilizes the Store<T> class without modifications and uses the ISetter interface and ASetter/BSetter/CSetter "closures" to hold references to different generic members. The Value class stores the references in a ISetter-typed variable and uses the generic member which the _setter links to once the type argument T becomes available.
public interface ISetter {
void SetValue<T>(T value);
}
public static class Store {
public static Value A = new Value(new ASetter());
public static Value B = new Value(new BSetter());
public static Value C = new Value(new CSetter());
class ASetter : ISetter {
public void SetValue<T>(T value) { Store<T>.A = value; }
}
class BSetter : ISetter {
public void SetValue<T>(T value) { Store<T>.B = value; }
}
class CSetter : ISetter {
public void SetValue<T>(T value) { Store<T>.C = value; }
}
}
public class Value {
ISetter _setter;
public Value(ISetter setter) {
_setter = setter;
}
public void SetValue<T> (T value) {
_setter.SetValue<T>(value);
}
}

How to convert chained static class names and a property value to a string?

Context:
Suppose one has the following class structure:
public static class SomeStaticClass
{
public static class SomeInnerStaticClass
{
public static readonly string SomeProperty = "someStringValue";
}
}
Question:
Is there an easy way to convert the reference SomeStaticClass.SomeInnerStaticClass.SomeProperty to string value of "SomeStaticClass.SomeInnerStaticClass.someStringValue"?
the first thing I posted was wrong because they were static types I wrote a little code and this works.
public static class A
{
public static class B
{
public static string c
{
get
{
return "hi";
}
}
}
}
class Program
{
static void Main( string[] args )
{
Console.WriteLine(typeof(A.B).FullName.Replace("+",".") + "." + A.B.c ) ;
}
}
Don't you just want:
public static class SClass
{
public static class SInner
{
public static string Property =
(typeof(SInner)).DeclaringType.Name+ "."
+ typeof(SInner).Name + "."
+ "value";
}
}
Which would output SClass.SInner.Property.value
If you wanted to automated it, you could put it in a while loop and exit once the parent type propertyIsNested is false.
You could use an expression:
namespace ConsoleApplication2
{
using System;
using System.Linq.Expressions;
class Program
{
static void Main(string[] args)
{
string fullName = GetExpression(() => SomeClass.SomeProperty);
Console.WriteLine(fullName);
}
public static string GetExpression<TProperty>(Expression<Func<TProperty>> expr)
{
string name = expr.Body.ToString();
string value = expr.Compile().Invoke().ToString();
name = name.Substring(0, name.LastIndexOf(".") + 1) + value;
return name;
}
}
public static class SomeClass
{
public static string SomeProperty = "Hello";
}
}
Here's one more elaborate solution. The method accepts a lambda expression denoting a property or a field. It the computes the value of the property or field and prepends it with names of all encapsulating classes.
I guess you want to have a type-safe method of producing some kind of structured / hierarchical identifiers encoded as a hierarchy of classes and properties or fields. I've been using this approach for a few years and it helps prevent many hard-to-catch bugs caused by simple typos.
Code:
public string GetStructuredName(Expression<Func<object>> nameObject)
{
if (nameObject == null) throw new ArgumentNullException("nameObject");
// find the expression denoting a property or a field
MemberExpression member = null;
switch (nameObject.Body.NodeType)
{
case ExpressionType.MemberAccess:
member = (MemberExpression)nameObject.Body;
break;
case ExpressionType.Convert:
case ExpressionType.ConvertChecked:
member = ((UnaryExpression)nameObject.Body).Operand as MemberExpression;
break;
}
if (member == null) throw new ArgumentNullException("nameObject");
StringBuilder sb = new StringBuilder();
// use the value of the member as the final component of the resulting name
sb.Append(nameObject.Compile().DynamicInvoke());
// use short names of embedded type names as components of the resulting name
Type type = member.Member.DeclaringType;
while (type != null && type != typeof(Object))
{
sb.Insert(0, ".");
sb.Insert(0, type.Name);
type = type.DeclaringType;
}
return sb.ToString();
}
Example:
public class OuterContainer
{
public class InnerContainer
{
public static string Property
{
get { return "value"; }
}
public static int Field = 10;
}
}
GetStructuredName(() => OuterContainer.InnerContainer.Property)
GetStructuredName(() => OuterContainer.InnerContainer.Field)
The output will be:
"OuterContainer.InnerContainer.value"
"OuterContainer.InnerContainer.10"
I don't know about the nature of your input format, but you can do this with System.Linq.Expressions:
Expression<Func<string>> expr = () =>
SomeStaticClass.SomeInnerStaticClass.SomeProperty;
var myResult = String.Concat(expr.Body, ".", expr.Compile().Invoke());

Polymorphism and casting problem

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;
}
}
}

Categories

Resources