Dynamically change class call path? - c#

In the code below, is it possible to dynamically call MyFunction() by changing OtherClass1 with strings a and b?
string a = "OtherClass1", b = "OtherClass2";
myClass = new MyClass();
myClass.OtherClass1.MyFunction();
Something like this:
myClass.a.MyFunction();
Tried to dynamically change it but cant figure out how...

While this is possible to solve this with reflection, it is not something I would recommend, especially not for someone new to coding. You are opting out to all kinds of protections the compiler will give you, and greatly increase the risk of bugs. But if you absolutely want to shoot yourself in the foot you can check out Get property value from string using reflection and How to Invoke Method with parameters.
My recommendation would be to instead make the two classes share an interface, and use an enumerable to select one of them:
public enum MyClasses{
Class1,
Class2
}
public IMyClass GetClass(MyClasses obj){
return obj switch{
MyClasses.Class1 => OtherClass1,
MyClasses.Class2 => OtherClass2,
_ => throw new InvalidOperationException();
}
}
this can then be called with
myClass.GetClass(a).MyFunction();
It would be even better to avoid the problem in the first place, but this pattern can be useful in some cases. You could replace the enum with strings, but that would again increase the chance of mistakes and bugs. It is better to parse the string to an enum in some input layer, that lets you do all the data validation in one place, making the rest of the code more reliable.

Related

How to attach functions together in C#?

I am having a hard time understanding this piece of code:
public IObservable<SomeInfo> OriginalFunction() => FirstFunction().SecondFunction(argument1).ThirdFunction(argument2);
First, I don't understand what that IObservable<CarsInfo> means. Does this function return an observable?
Then, what does the lambda => do?
And finally, how are the three functions attached to each other using dots?
public IObservable<SomeInfo> OriginalFunction() => FirstFunction().SecondFunction(argument1).ThirdFunction(argument2);
is equivalent to
public IObservable<SomeInfo> OriginalFunction()
{
var firstResult = FirstFunction();
var secondResult = firstResult.SecondFunction(argument1)
return secondResult.ThirdFunction(argument2); // mind the 'return' here!
}
which by the way expect argument1 and argument2 as class fields or properties, which some people would consider "not so clean"*.
* I should elaborate on that: While clean code advocates for having as small number of arguments as possible, using class fields or properties here does make the function harder to test. I personally would consider this a kind of side-effect which should be avoided. What do I mean by side-effect? Two calls of this function may return different results depending on the value of class fields. This could be reasonable or not. Depends on the actual semantics of the code which is not at all clear from the example.
So, TL;DR: Consider if it is reasonable to use class fields or if it is more reasonable to to use two arguments or use an "Options-Pattern" argument. Take into account: Is it clear what result to expect ("do not surprise clients")? Is the function testable? And some more...
EDIT:
=> is a feature added in C# 6.0 : Expression-bodied function members
Many members that you write are single statements that could be single expressions. Write an expression-bodied member instead. It works for methods and read-only properties. For example, an override of ToString() is often a great candidate:
public override string ToString() => $"{LastName}, {FirstName}";

Is it possible to create an extension method for all classes excluding primitives in C#?

I would like to create an extension method that will work for classes only.
I can write an extension method for type object, like this:
public static void SomeMethod(this object obj)
{
// some code
}
However this will work for primitives too, I would like to disable to do something like this:
int number = 2;
number.SomeMethod();
Any ideas how can I do this, if it's possible at all?
I think you need something like this, but I will not recommend you do that only if it's not for serialization or something like that.
public static void SomeMethod<T>(this T obj) where T : class
{
}
You are going to be fighting boxing behaviour here...
Essentially you limit your type that it must be an object, but C# adds some sugar and says, thats a primitive, I can box it into an object for you and treat it like an object too!
If you have some level of subclass you can target, that might stop the behaviour you are after (as in don't target all objects but perhaps something that is IObservable, IEnumerable etc.)
The other way to defensively code this is to add an explicit type check and exception throw on your method
if (myobject.GetTypeCode != TypeCode.Object) { throw new ArgumentException() }
Don't do it. If you have a method you want to call on a whole variety of objects, then centralize it in a function somewhere. That way some poor programmer who comes along 10 years after you will not be wondering where that weird method is located.

Performance Hit? list of anonymous type to achieve something like this List<int, string, ...> (a multi-dimensional list of multiple types) in c#)

I am wondering about whether or not creating a list of an anonymous type is the best way to effectively create a list of multiple types as well as its effect on general performance and efficiency. Mainly I just want to know if there is a more standard way of doing List?
Situation
I every now and then find myself with a need to create a list that has multiple values each of a different type, List. Normally i would just resolve this with a Dictionary, but then there are the cases where i don't care about duplicated key values or need a 3rd (or rarely 4th) value. Usually this is for temporary list that just track something contained in a method like logging thrown errors and an associated value so that at the end of the method i can string together the messages for a log file or something.
What i have so far is this:
var list = new[] { new { RowNumber = 1, Message = "" } }.ToList();
list.Clear();//clears out the example used to create the anonymous type
list.Add(new { RowNumber = 10, Message = "bla bla" }); //adding to the list
I am debating on doing something like an extension or something to make this easier, but if the performance sucks or there is a better way, i would like to know.
I prefer to make a class. The IL just makes an anonymous class in native that gets called the same way as a normal class, so there is no performance hit associated with it. If you ever debug anonymous types, you'll notice the name has a long name like AnonymousTypes.Program+f__1
Creating a class improves the readability of your code IMO.
public class RowMessage
{
public int RowNumber { get; set; }
public string Message { get; set; }
}
You can also use Tuples, but even this is still unclear:
public void MyMethod()
{
Tuple<int, string> myTuple = new Tuple<int, string>(1, "hi");
List<Tuple<int, string>> myTupList = new List<Tuple<int, string>>();
myTupList.Add(myTuple);
}
I just experimented a little. Here's what I found:
Anonymous types are as good as anything else. I can't really say "anything," since I didn't try everything. But I can tell you that they're as good as Tuple<> and concrete types. This is logical, because underneath the covers, the compiler actually builds types for anonymous types. In essence, at runtime, they are just concrete types.
Your ToList call is redundant. This part's important. It's not super relevant to your immediate question, but looking at your example, you do new [] { ... }.ToList(). This forces a loop through the array after it's created. You'd be much better off using list initialization: new List<dynamic> { ... };. That's what I used in my examples.
I ran tests 10,000 times each for:
Anonymous type with array initializer (00:00:00.0050338 total)
Anonymous type with list initializer (00:00:00.0035599 total)
Tuple with list initializer (00:00:00.0025857 total)
Concrete type with list initializer (00:00:00.0041538 total)
Running them again would just mix it up. The only consistent result was that arrays were, unsurprisingly, slower than going directly to a list.
If you're going to make an extension method, you'll probably want to go with one of the latter two options. Anonymous types don't travel well outside of their scope, as I'm sure you know. The choice is yours between concrete types and tuples. I'd go with concrete if you're using it a lot and/or outside of the original method, and a tuple if it just needs to exist somewhere. That's really a design choice that I can't make for you.
Since you are talking about enriching Exceptioninformation it is worth to mention that the Exceptionclass implements a property called Data which is of type IDictionary and can be used to append additional information.
try
{
throw new FileNotFoundException{ Data ={ { "TEST", "Hello World" } } };
}
catch (Exception e)
{
Console.WriteLine(e.Data["TEST"]);
...
e.Data.Add("Whatever", DateTime.Now);
}
If you find yourself adding the same information lots of times, consider some HelperMethods that add certain information to a giving exception. This could also take care for duplicated keys which use some sort of numeric postfix that increments like fileName_1 and so on, you get the idea.
You can also create a standartized method of outputting those Information you provided yourself.
If you want a more Complex approach you can just simply use List but make the consumer of this list handle each kind of type. Which is basically the idea behind the DebuggerTypeProxy-Atrribute
So you can for example use some pattern like this:
foreach(var typeGroup in additionalInformation.GroupBy(item => item.GetType())
{
ITypedLogHandler handler = GetHandlerFor(typeGroup.Key);
handler.WriteLog(typeGroup);
}
In general the only reason I can think of this whole idea to beeing valid is some convenient debuggint/loggin approach. Anything else should really use strong typing.

Dynamically create or set the return type of a function in the function

I am attempting to create a function where the return type is determined at run-time. I know I could just return an object or dynamic, however my aim is to have the typed object returned, and be recognized by the compiler and InteliSense.
I know I could cast my object after it has been returned and that would be the easiest thing to do to implement this, but that is just not the programming spirit.
Here is an example of what I'm trying to create
Note: I do not actually want Buttons and Grids... that is just for this example.
Type T;
public T Question(bool aBool)
{
if (aBool)
{
T = typeof(Button);
return new Button();
}
else
{
T = typeof(Grid);
return new Grid();
}
}
Now, this obviously doesn't work and I understand why. But I want to know if anyone has a way that does work, or if this is not possible with the current state of C#.
Edit: A response to comments... I understand this would seem like "magic", and I do understand that the compiler will have to figure out what my result is for this to work. The compiler/Intellisense/Visual Studio already does this for many other things. While these things are can simple like detecting unreachable code, or drawing visual previews. I am curious if this is an implemented feature.
The only possible way for the consumer of such a method to actually rely on the fact that the return type is dynamic is if, at least for that one method call, the return type is statically known at compile time.
There is a specific feature for a method that has some type unknown at the time the method is written, but fixed when a particular call to that method is make. That feature is called "generics".
public T Foo<T>()
where T : new()
{
return new T();
}
That's really the only available option for a truly dynamic return type that has much potential for really being useful.
If that's not what you want, or that is not a workable option for you, then odds are pretty high your method shouldn't have a dynamically changing return type. Instead it should have a fixed return type of some more generalized type that can have multiple implementations. Generally this would mean an interface, to which you can return one of any number of possible implementations. This should be done if the caller doesn't need to really know or care what the implementation is, but rather all they need to know is that they are given some implementation of an interface that exposes all of what they need. In your case, perhaps something like Control would be workable, if the caller only need to know that they are given some type of control, and to which the API of Control provides everything that they need to do with it.
You can use Dynamic keyword in this case
eg:
public dynamic CreatObj(string caller)
{
if (caller.equals("x"))
return x;
else
return y;
}
You can use a type if it has a parameterless constructor and you mark your generic with the new constraint. If you want to do more than that it get more difficult you need to use refection or activator.

why C# does not provide internal helper for passing property as reference?

This is issue about LANGUAGE DESIGN.
Please do not answer to the question until you read entire post! Thank you.
With all helpers existing in C# (like lambdas, or automatic properties) it is very odd for me that I cannot pass property by a reference. Let's say I would like to do that:
foo(ref my_class.prop);
I get error so I write instead:
{
var tmp = my_class.prop;
foo(tmp);
my_class.prop = tmp;
}
And now it works. But please notice two things:
it is general template, I didn't put anywhere type, only "var", so it applies for all types and number of properties I have to pass
I have to do it over and over again, with no benefit -- it is mechanical work
The existing problem actually kills such useful functions as Swap. Swap is normally 3 lines long, but since it takes 2 references, calling it takes 5 lines. Of course it is nonsense and I simply write "swap" by hand each time I would like to call it. But this shows C# prevents reusable code, bad.
THE QUESTION
So -- what bad could happen if compiler automatically create temporary variables (as I do by hand), call the function, and assign the values back to properties? Is this any danger in it? I don't see it so I am curious what do you think why the design of this issue looks like it looks now.
Cheers,
EDIT As 280Z28 gave great examples for beating idea of automatically wrapping ref for properties I still think wrapping properties with temporary variables would be useful. Maybe something like this:
Swap(inout my_class.prop1,inout my_class.prop2);
Otherwise no real Swap for C# :-(
There are a lot of assumptions you can make about the meaning and behavior of a ref parameter. For example,
Case 1:
int x;
Interlocked.Increment(ref x);
If you could pass a property by ref to this method, the call would be the same but it would completely defeat the semantics of the method.
Case 2:
void WaitForCompletion(ref bool trigger)
{
while (!trigger)
Thread.Sleep(1000);
}
Summary: A by-ref parameter passes the address of a memory location to the function. An implementation creating a temporary variable in order to "pass a property by reference" would be semantically equivalent to passing by value, which is precisely the behavior that you're disallowing when you make the parameter a ref one.
Your proposal is called "copy in - copy out" reference semantics. Copy-in-copy-out semantics are subtly different from what we might call "ref to variable" semantics; different enough to be confusing and wrong in many situations. Others have already given you some examples; there are plenty more. For example:
void M() { F(ref this.p); }
void F(ref int x) { x = 123; B(); }
void B() { Console.WriteLine(this.p); }
If "this.p" is a property, with your proposal, this prints the old value of the property. If it is a field then it prints the new value.
Now imagine that you refactor a field to be a property. In the real language, that causes errors if you were passing a field by ref; the problem is brought to your attention. With your proposal, there is no error; instead, behaviour changes silently and subtly. That makes for bugs.
Consistency is important in C#, particularly in parts of the language that people find confusing, like reference semantics. I would want either references to always be copy-in-copy-out or never copy-in-copy-out. Doing it one way sometimes and another way other times seems like really bad design for C#, a language which values consistency over brevity.
Because a property is a method. It is a language construct responding to a pattern of encapsulating the setting and retrieval of a private field through a set of methods. It is functionally equivalent to this:
class Foo
{
private int _bar;
public int GetBar( ) { return _bar; }
public void SetBar( ) { _bar = value; }
}
With a ref argument, changes to the underlying variable will be observed by the method, this won't happen in your case. In other words, it is not exactly the same.
var t = obj.prop;
foo(ref t);
obj.prop = t;
Here, side effects of getter and setter are only visible once each, regardless of how many times the "by-ref" parameter got assigned to.
Imagine a dynamically computed property. Its value might change at any time. With this construct, foo is not kept up to date even though the code suggests this ("I'm passing the property to the method")
So -- what bad could happen if
compiler automatically create
temporary variables (as I do by hand),
call the function, and assign the
values back to properties? Is this any
danger in it?
The danger is that the compiler is doing something you don't know. Making the code confusing because properties are methods, not variables.
I'll provide just one simple example where it would cause confusion. Assume it was possible (as is in VB):
class Weird {
public int Prop { get; set; }
}
static void Test(ref int x) {
x = 42;
throw new Exception();
}
static void Main() {
int v = 10;
try {
Test(ref v);
} catch {}
Console.WriteLine(v); // prints 42
var c = new Weird();
c.Prop = 10;
try {
Test(ref c.Prop);
} catch {}
Console.WriteLine(c.Prop); // prints 10!!!
}
Nice. Isn't it?
Because, as Eric Lippert is fond of pointing out, every language feature must be understood, designed, specified, implemented, tested and documented. And it's obviously not a common scenario/pain point.

Categories