Javascript's void in C#? - c#

Is there something like Javascript's void operator in C#?
Javascript's void, "evaluates an expression and discards the result, returning undefined". Thus, I'm looking for something built-in that "evaluates" and returns null, or maybe the type default. (So it should sort of be like the inverse of the null-coalescing ?? operator.)
Example use:
Person a;
public void main() {
var x = void(a = new Person());
// x should contain null
}
class Person { }
(Example does not compile due to illegitimate use of keyword "void", naturally.)
I currently use this—which works—but feels crufty:
protected object voided(object ob) {
return null;
}
Edit. Ok, so I definitely need to add some more details. I'm using the code in an inline DataBind expression in ASP.NET code. E.g.:
<asp:Repeater runat="server">
<ItemTemplate>
</tr><%# voided(globalPersonVariable = (Person)Container.DataItem)) %></tr>
</ItemTemplate>
</asp:Repeater>
Using default, unfortunately does not work here.
(I didn't include this additional information the first time, because I wanted to keep it a "pure" C#-question, not ASP.NET.)

Something like this you're looking for?
var x = default(Person) // null
var i = default(int) // 0

You could just make an extension method, Voided()
public static object Voided<TType>(this TType tThis)
{
return null;
}
Then you can call it like so:
(globalPersonVariable = (Person)Container.DataItem)).Voided()
If you want to combine this with the default stuff other people have mentioned, it would change to:
public static TType Voided<TType>(this TType tThis)
{
return default(TType);
}

Not sure what void function does in javascript, but to get a default value of a type, use default keyword:
protected T voided<T>(T obj) {
return default(T);
}

You could use the default keyword:
http://msdn.microsoft.com/en-us/library/xwth0h0d(v=vs.80).aspx

I just want to throw these two snippets into the mix.
Both work, but they still feel more verbose than necessary.
(globalPersonVariable = (Person)(Container.DataItem)) == null ? null : null
((Func<object,object>)(x => null))(globalPersonVariable = (Person)(Container.DataItem))
For databinding purposes, you can also emit the empty string:
(globalPersonVariable = (Person)(Container.DataItem)) == null ? "" : ""
The distinction might seem trivial, but this can save you from needing to cast
the nulls in certain situations.

Related

How to return a value of passed in property of generated object in c#

I have a function that returns a particular type. Ex. FaxFile. In that object there are several different formats to download ex: PDF, LargeJpg, SmallJpg, etc.
I can call the download a pdf like this.
public FaxFile DownloadFaxPDFById(int faxId)
{
return DownloadFaxById(faxId).Pdf;
}
What I am wanting to do is be able to pass in the property of the object ex. LargeJpg Format to download.
Sudo Code
public FaxFile DownloadFaxTypeById(int faxId, property)
{
return DownloadFaxById(faxId).property;
}
How do I do this?
you can use reflection.
var resultObj = DownloadFaxById(faxId);
var result = resultObj.GetType().GetProperty("<propertyName>").GetValue(resultObj);
please note that you need to cast result to appropriate object
You don't want to do this at the first place. Just use DownloadFaxById(faxId).Pdf/LargeJpg/...; in the call place or, if you don't want to expose class returned by DownloadFaxById either subclass or use aggregation and expose Pdf, LargeJpg, ... in this new class.
Another way of doing this besides those already posted as answers is to use lambda expressions. Not sure what's the type of the downloaded object, so replace DownloadedObjectType with your own.
public FaxFile DownloadFaxTypeById(int faxId, Expression<Func<DownloadedObjectType, FaxFile>> expression) {
if (!(expression.Body is MemberExpression)) {
throw new ArgumentException("Invalid expression");
}
return expression.Compile().Invoke(DownloadFaxById(faxId));
}
You then call it as
DownloadFaxTypeById(faxId, obj => obj.Pdf)
However looks much uglier than simply calling
DownloadFaxTypeById(faxId).Pdf
Except for maybe providing you some control over what properties can the caller retrieve, limiting them to that specific return type and only those that are actually available for that type. This way for a subset of possible errors (like referencing non-existing property) you get compile time errors rather than all runtime as in cases using reflection.
I would recommend to create an enum for this and pass it to your function.
Inside your function simple use switch.
This means more programming, but the usage of your function is much clearer.
This has also the benefit that you later can change the code how you obtain each format without taking care of the consumer of your function.
enum FaxFileType
{
PDF,
LargeJpg,
SmallJpg,
...
}
public FaxFile DownloadFaxById(int faxId, FaxFileType faxFileType)
{
switch (faxFileType)
{
case FaxFileType.PDF:
return DownloadFaxById(faxId).PDF;
case FaxFileType.LargeJpg:
return DownloadFaxById(faxId).LargeJpg;
case FaxFileType.SmallJpg:
return DownloadFaxById(faxId).SmallJpg;
...
default:
throw new NotSupportedException();
}
}
You should probably just use a switch statement for each format type you support from an enum. However if you really want to use reflection, you can so it as follows:
void Main()
{
var foo = new Foo();
foo.GetType().GetProperty("MyProp").SetValue(foo, "Test");
var val = foo.GetType().GetProperty("MyProp").GetValue(foo);
Console.WriteLine(val);
}
public class Foo
{
public String MyProp { get; set; }
}

Optimizing code structure C#

Here's code I write to check if properties in my viewmodel are null or not before attempting to update the database
var channel = _context.Channels.FirstOrDefault(x => x.Id == viewModel.Id);
if (!string.IsNullOrEmpty(viewModel.Part))
{
channel.Part = viewModel.Part;
}
if (!string.IsNullOrEmpty(viewModel.IndexName))
{
channel.IndexName = viewModel.IndexName;
}
if (viewModel.MeasurementId != null)
{
channel.MeasurementId = viewModel.MeasurementId;
}
if (!string.IsNullOrEmpty(viewModel.Direction))
{
channel.Direction = viewModel.Direction;
}
The code is working fine but I use alot of if statements here which for me doesn't look really effective. Can you suggest me changes like using other syntax or structures rather than if statement to make my code more concise and abit more "pro"?
As long as your channel object's properties do not have any side-effects other than changing a value (ie, firing events), you could do this:
string PickNonEmptyOrDefault(string value, string deflt)
{
return String.IsNullOrEmpty(value) ? deflt : value;
}
...
channel.Part = PickNonEmptyOrDefault(viewModel.Part, channel.Part);
channel.IndexName = PickNonEmptyOrDefault(viewModel.IndexName, channel.IndexName);
etc.
By the way, I wanted to know if there was a way this could be done without accidentally side effecting your property. The trick is to use reflection and to use a PropertyInfo object to do your work:
class Foo
{
public string Bar { get; set; }
public string Baz { get; set; }
public override string ToString()
{
return (Bar ?? "") + " " + (Baz ?? "");
}
}
delegate void propsetter(string prop, string value);
private static void SetOnNonEmpty(PropertyInfo pi, Object o, string value)
{
if (pi.PropertyType != typeof(string))
throw new ArgumentException("type mismatch on property");
if (!String.IsNullOrEmpty(value))
pi.SetValue(o, value);
}
static void Main(string[] args)
{
var myObj = new Foo();
myObj.Baz = "nothing";
PropertyInfo piBar = myObj.GetType().GetProperty("Bar");
PropertyInfo piBaz = myObj.GetType().GetProperty("Baz");
SetOnNonEmpty(piBar, myObj, "something");
SetOnNonEmpty(piBaz, myObj, null);
Console.WriteLine(myObj);
}
output something nothing
I honestly don't recommend doing this as it doesn't really add to the readability and feels pretty gross.
I'd be more inclined to write a chunk of code that reflects across the properties of your view model and calls a Func<string, string> to get the corresponding property name in your data model and then if that returns non-null and the property types match, call the getter on the view object and pass it to the setter on the data object.
And I would only do this if I was doing this a significant number of times.
If it's just the if that bothers you you could use the conditional operator:
channel.Part = string.IsNullOrEmpty(viewModel.Part) ?
channel.Part : viewModel.Part;
etc.
of course that always calls the set accessor for Part, which is fine unless there's logic in it (change tracking, etc.) that would be bad if it were called when the value doesn't really change.
You could also refactor the conditional operator to a method, but there's no other way to conditionally set the value without using an if.
Your code is fine. Even Jon Skeet uses if statements.
If you want the best performing code, keep it like this. If you want to make your code look pro, use any suggestion done by others here. My opinion: keep it as is.
There is absolutely nothing wrong with the code you have written.
If your objective is less lines of code, you can do this, however I think it will just add unnecessary complexity.
channel.Part = string.IsNullOrWhiteSpace(viewModel.Part) ? channel.Part : viewModel.Part;
channel.IndexName = string.IsNullOrWhiteSpace(viewModel.IndexName) ? channel.IndexName: viewModel.IndexName;
channel.MeasurementId = viewModel.MeasurementId == null ? channel.MeasurementId : viewModel.MeasurementId;
channel.Direction = string.IsNullOrWhiteSpace(viewModel.Direction) ? channel.Direction : viewModel.Direction;
Note I have switched your call from IsNullOrEmpty to IsNullOrWhiteSpace
A string with the value of " " (one or more whitespace) will get through a IsNullOrEmpty check which you probably dont want.
You can also use the coalesce operator for your nullable types (but not empty strings) like this...
channel.MeasurementId = viewModel.MeasurementId ?? channel.MeasurementId;
If those are fields and not properties, you can use something like this:
void ReplaceIfNotEmpty(ref string destination, string source)
{
if (!string.IsNullOrEmpty(source))
{
destination = source;
}
}
and then just
ReplaceIfNotEmpty(ref channel.Part, viewModel.Part);

Ambiguous call of method

I have the following code
class Program
{
static void Main()
{
A a = new A();
a.M(null);
}
}
class A
{
public void M(int? i)
{ }
public void M(string s)
{ }
}
And I have an error, because the call is ambiguous. I need to change the call of M method without adding any lines to Main method and accessing class A so that it became correct. Could someone please tell me how to do this?
You can use explicit cast:
A a = new A();
a.M((string)null);
or
a.M((int?)null);
to help the compiler of picking the right overload. Note that C# compiler can't determine what method overload to call based on null literal.
For advanced topic consider Eric's article What is the type of the null literal?
edit:
since your argument names are different, you can use named arguments, which are avaliable since C# 4.0:
a.M(i : null);
or
a.M(s : null);
You can use a cast, or the default keyword, or for int?, new int?() (which, due to how Nullable types work, is also the same as null). You could also use named parameters to disambiguate. Or, of course, if you were ok with adding another line, you could declare your value in a variable and pass that in.
// these call the int? overload
a.M(default(int?));
a.M((int?)null);
a.M(new int?());
a.M(i: null);
int? i = null;
a.M(i);
// these call the string overload
a.M(default(string));
a.M((string)null);
a.M(s: null);
string s = null;
a.M(s);
The answer is that you cannot overload the member M this way if you cannot alter existing call sites.
Presumably you are adding one of the two methods and can alter the call sites for calls to the new method. Change the name of the method for those new call sites to use.

How to get the string (of source-code) that generated a lambda-expression?

(for LISP hackers in short: I'm looking for the LISP-quote equivalent in C#)
I'm trying to write a meaningful ToString-method for a class which has a Func as member. Experiened API-users can set this member via setter-method like
myClassObject.SetFunction( (x) => x*x );
Now, when I use the ToString-method on the member it only returns
System.Func<double,double>
which is not very helpful. What would be helpful is
"(x) => x*X"
Is there any (preferable easy) way to do that?
Thanks for any help or comments.
Edit: corrected some typos
Expression<Func<double,double>> expr = x => x * x;
string s = expr.ToString(); // "x => (x * x)"
If you're willing to store your delegate as an expression, you can achieve what you want. The code would look something like this:
private Expression<Func<double, double>> myFunc;
private Func<double, double> cachedDelegate;
public void SetFunc(Expression<Func<double,double>> newFunc)
{
this.myFunc = newFunc;
this.cachedDelegate = null;
}
public double ExecFunc(double x)
{
if (this.myFunc != null)
{
if (this.cachedDelegate != null)
{
return this.cachedDelegate(x);
}
else
{
this.cachedDelegate = this.myFunc.Compile();
return this.cachedDelegate(x);
}
}
return 0.0;
}
public string GetFuncText()
{
if (this.myFunc != null)
{
return this.myFunc.ToString();
}
return "";
}
In order to actually use the lambda expression, you have to compile it first. Storing it in a delegate means you only take that hit once.
Also, this approach means that users have to use a lambda, since method groups aren't convertible to Expression<Func<>>. That's not a huge concern, though, since instead of passing MyMethod, a user could pass x => MyMethod(x).
The calling code would look something like this:
myObject.SetFunc(x => 2*x);
Console.WriteLine(myObject.GetFuncText());
One final note is that the above sample is not thread-safe, so if you expect to have the methods called from multiple threads, some sort of synchronization would be appropriate.
None that I know of since that string has never entered the system, only IL was somehow generated and stored with a reference... you would need to "decompile" the IL to some meaningful string...
With CodeExpression there is possibility to call GenerateCodeFromExpression via an instance of CodeDomProvider which has built-in implementations for C# / VB / JScript... but I would be surprised if that met your needs...
Another option: With Expression you could use ToString() - this works with LambdaExpression too since that is just a descendant.

C#: How can I use implicit cast operator during object to type conversion?

HI!
Here is my case: I have some value type which is wrapped into another type with appropriate implicit converters. If I cast wrapped type to an object and then try to get original value I can do that in two-step cast only.
If simplified my code is as follows:
public enum MyEnum : int
{
First,
Second
}
public class Test<T>
{
public Test(T val)
{
Value = val;
}
private T Value { get; set; }
public static implicit operator T(Test<T> m)
{
return m.Value;
}
public static implicit operator Test<T>(T m)
{
var res = new Test<T>(m);
return res;
}
}
static void Main()
{
object res = new Test<MyEnum>(MyEnum.First);
Console.WriteLine((MyEnum)(Test<MyEnum>)res);
Console.WriteLine((MyEnum)res);
}
First "Console.WriteLine" works OK. Second one fails.
Is there any way I can modify this behavior and get it working without double casting?
UPDATE 1
I must use object to value cast (in real application I have to cast ComboBox.SelectedItem property and I do not want to add extra property to ComboBox, because I'll have to change my UI interaction code everywhere).
UPDATE 2
Implicit conversions to and from System.Object are not allowed.
UPDATE 3
Updated my sample code to reflect the whole problem.
Don't use object that way. Write your first line like this instead:
Test res = new Test(1);
If you must have it in an object first, remember that all the compiler knows about it at this point is that it's an object, and nothing more. You, as the programmer, have additional information about what you expect this object to be, but for the compiler to take advantage of that information you have to put it into your code somewhere.
Update:
I'm glad I was able to find this again, because this almost-very-timely article by Eric Lippert, who works on the C# language design, went up this morning and explains the problem in depth:
http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx
If you want to simplify casting and not care performance effect, then create extension method.
public static T To<T>(this object obj) {
Type type = obj.GetType();
MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
MethodInfo method = methods.FirstOrDefault(mi => (mi.Name == "op_Implicit" || mi.Name == "op_Explicit") && mi.ReturnType == typeof(T));
if (method == null)
throw new ArgumentException();
return (T)method.Invoke(null, new[] { obj });
}
Usage
Console.WriteLine(res.To<MyEnum>());
Instead of adding implicit operators, consider implementing IConvertible. You only need to implement the ToInt32 method, the others are meaningless and you can throw the InvalidCastException in the other methods.
After that, you can use Convert.ToInt32() method to convert your object in one step.
or even
var res = new Test(1);
Your local variable res is always of type object; so the line that isn't working is trying to convert an object, that isn't an int, to an int, which can't be done. Same as this fails:
object d = 5.5d;
Console.WriteLine((int)d);
EDIT:
Perhaps a pattern that might help is something like this:
if (res.GetType() == typeof(Test))
{
Console.WriteLine((int)(Test)res);
}
else
{
Console.WriteLine((int)res);
}
It's a very localized solution to your problem, but perhaps it will work for you.
While the error is due to res being of type object, I would make the Test->int operator explicit...

Categories