What is equivalent to Microsoft.VisualBasic.Collection in c#? - c#

I have a method which takes a stored procedure name and a Microsoft.VisualBasic.Collection? I am referencing a vb project in which I have to pass in a collection to this method, but the current project I am in is in c#, so I am unclear what I can pass into the method?
Here is the vb call:
public void CallStoredProc(string spName, Microsoft.VisualBasic.Collection params);
In my c# app, I need to call this an pass in the appropriate c# object to params.

One option is to simply use the Collection type directly from C#. This is a standard type in the Microsoft.VisualBasic.dll assembly and can be used from any .Net language.
The closest collection in the standard BCL though is Hashtable. Converting between Hashtable and Collection should be fairly straight forward
For example
using VBCollection = Microsoft.VisualBasic.Collection;
...
public static VBCollection ToVBCollection(this Hashtable table) {
var collection = new VBCollection();
foreach (var pair in table) {
// Note: The Add method in collection takes value then key.
collection.Add(pair.Value, pair.Key);
}
return collection;
}
Note: This is not a direct mapping though. The Collection type supports a number of operations which Hashtable does not like: before and after values, index by number or key, etc ... My approach would be to use one type consistently throughout the application and change either the C# or VB project appropriately

Unless you can change the method, so that it takes ICollection, IEnumerable or their generic variants, you have to pass an instance of Microsoft.VisualBasic.Collection to that method.
From the point of view of C#, Microsoft.VisualBasic.Collection is just a class and you can work with it as with any other class, i.e. instance it:
new Microsoft.VisualBasic.Collection()
Of course, you have to reference the assembly Microsoft.VisualBasic.dll in your project.

There is no such thing as a "C# object", or a "VisualBasic.net object" - it is all .net, so you can simply include a reference to Microsoft.VisualBasic.dll and use that Microsoft.VisualBasic.Collection.
C# devs often frown upon Microsoft.VisualBasic.dll because of the name, but you won't be eaten by Velociraptors if you use it since .net is properly and fully language-independent.

Related

Why you cannot declare a field and property as having an anonymous type?

I ran into a problem while doing my job, which is porting software from flash AS3 to .NET/Mono. In AS3 code base I can find many Object declarations that are initialized like this:
private const MAPPING:Object =
{
ssdungf:'flydung',
ssdungt:'flydung',
superfutter:'superfeed'
}
The best option for me would be in C# using anonymous type like this:
var MAPPING = new
{
ssdungf = "flydung",
ssdungt = "flydung",
superfutter = "superfeed"
};
The problem is... well let me quote MSDN (source):
You cannot declare a field, a property, an event, or the return type of a method as having an anonymous type
But they don't say why.
So the question remains: why you cannot declare a field and property as having an anonymous type? Why .NET creators stripped it from that option?
I am getting warning here from SO that my question appears subjective, but I think it is not at all - there need to be objective reason for that.
As for me, I don't see any obstacles for that but somehow it is not supported. As compiler can easily generate the type for field or property of class, in a same manner as it does for local variables.
The option for me was to use dynamic type but unfortunately Mono engine I am using is stripped from that.
Also the option for me is to use object type and using later reflection to find these fields:
private static readonly object MAPPING = new
{
ssdungf = "flydung",
ssdungt = "flydung",
superfutter = "superfeed"
};
But using reflection is this situation is dirty I would say.
I tried to find answer, but I really didn't find any. Here are some SO answers to similar questions, but they don't answer why:
Can a class property/field be of anonymous type in C# 4.0?
Declaring a LIST variable of an anonymous type in C#
How do you declare a Func with an anonymous return type?
Why you cannot declare a field and property as having an anonymous type?
Because C# is statically typed, so any memory location has to be given a type, and declaration does so. With locals we can infer from context if its initialised at the same time as declaration with var but that is a shorthand for a type that is usable even when the type hasn't got a name.
What would a field with an anonymous type, that is to say a statically-bound but indescribable type, mean?
dynamic would indeed be the closest analogy to the code you are porting, but since that isn't available to you, you might consider using an IDictionary<string, object> (which incidentally is how ExpandoObject, which is often used with dynamic to have objects that behave more like javascrpt objects, works behind the scenes). This would be slower and less type-safe than if you created a class for the object needed, but can work.
The problem on an anoynmous property is: how do you get/set it?
Suppose it would work:
class MyClass
{
public MyField = new { TheValue = "Hello World" };
}
Now in your consuming code you´d write code to read the code:
MyClass m = new MyClass();
m.MyField.TheValue = "newValue";
How was this different from having a type for MyField? All you´d get is that you can omit two or three lines of code whilst gaining nothing. But I think you might produce many problems as no-one knows what he can assign to/expect from that member.
Furthermore you can´t do much with an anonymous object, basically you can just set it and read it. There are no methods (except Equalsand GetHashCode inherited from object) that you can call so the opportunities are quite low.
Last but not least an anonymous object is usually used as temporaryily, for example within a Select-statement. When you use it you say: this type is going to be used only within the current specific scope and can be ignored by the entire world as internal implementation-detail. Creating a property of an anonymous type will expose such a detail to the outside. Of course you could argue that the designers could at least allow them for private members, but I guess doing so would bypass the complete concept of accessability for nothing.

How can I use list that created using reflection as normally create list

I created a list using method from this post
Create list of variable type
Assembly assembly = Assembly.Load("ConsoleApplication4");
Type mytype = assembly.GetType("ConsoleApplication4.TestClass");
Type genericList = typeof(List<>).MakeGenericType(mytype);
var mylist = Activator.CreateInstance(genericList);
my question is,after I create the list, how can I use the list in a function like following:
public void TestFunction<T>(List<T> mylist)
{
//do something here
}
You'd lose static type analysis and compile-time checking (then again, given that you're working with reflection that's already happened), so you could just re-write your TestFunction as:
public void TestFunction(dynamic myList)
{
// do something here
}
you could simply change the last line where you instantiate the list
dynamic mylist = Activator.CreateInstance(genericList);
That way the compiler won't try to infer the (runtime) type of myList but will defer this task to the DLR which in your case will be happy to tell you that it is some List<mytype>
If you at some point know the concrete type of mylist you can of course also use a simple cast
TestFunction((List<knownType>)mylist);
which one to prefer is mainly a matter of taste, there might be performance differences between the two but compared to the reflection based instantiation that difference is probably not going to be the bottleneck but if performance is of main concern use a profiler.
The reason why I suggest using dynamic at the instantiation site instead of in the method signature is to make most of the code statically typed so that the compiler can check most of the code. By using dynamic in the method signature you will make all calls of that method into dynamic calls whereas if you make the mylist dynamically typed you are only make the statements using mylist into dynamic calls.
You can not use the instance of mylist in the way you want, because the Compiler can not infer the closed type of List. You can only work with further reflection methods or inspect it with open generic types.

C# alternative to tuple

I have a dbf file (dBase) that I want to read, put each row into a single list (since a row represents data about one shapefile object), and then be able to modify the list (e.g., convert fields which represent the name to a string). This means that the datatype need to be able to hold both Ints, strings, bool and so on, and add items to, it. In python I could do this with lists, but since sets cant be modified, I cant use them.
This sounds like a (exact) duplicate to Alternative to Tuples,
but it isn't. These questions are based on the assumption that you know which objects you want beforehand; I don't.
I'm on .NET 4.5, btw.
Use dynamic - it is a perfect use case for it:
Visual C# 2010 introduces a new type, dynamic. The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object. At compile time, an element that is typed as dynamic is assumed to support any operation. Therefore, you do not have to be concerned about whether the object gets its value from a COM API, from a dynamic language such as IronPython, from the HTML Document Object Model (DOM), from reflection, or from somewhere else in the program. However, if the code is not valid, errors are caught at run time.
If you want to be able to easily add properties at runtime and change their types, you can use ExpandoObject with dynamic, for example:
dynamic expando = new ExpandoObject();
expando.SomeProperty = "1234";
Console.WriteLine(expando.SomeProperty);
Console.WriteLine(expando.SomeProperty.GetType().FullName); // string
expando.SomeProperty = int.Parse(expando.SomeProperty);
Console.WriteLine(expando.SomeProperty);
Console.WriteLine(expando.SomeProperty.GetType().FullName); // int
Have you tried using the dynamic type?

Find all static references to a class by code c#

I search for a way to display all static occurances of classes (similiar to the Visual Studio functionality: find all references).
It should only be by code and not manually.
I want to
Only list classes with a specific attribute
List all classes which have static references to it (find table bindings to data classes)
My first step is to list all Types which i'm interested in:
var result = from t in assembly.GetTypes()
where t.IsDefined(typeof(TAttribute), inherit)
select t;
return result.ToList();
I'm having problems with the second step.
I know how to find Properties... from a class. But how is it possible to go the other way round, and find all usages of a class?
You can not find static references using reflection, it's something that AST may know about. For this you may want to use: Roslyn (Compiler as a Service), that let's you compile, and investigate AST.
You can't find references in method bodies using reflection but you can find fields, properties and methods parameters/return values.
You already know how to list all types, now for each type:
Type.GetProperties returns an array of PropertyInfo, you can check if `PropertyInfo.ProeprtType' is in the list of types you care about.
Same goes for fields with Type.GetFields
For methods you call Type.GetMethods, this returns an array of MethodInfo objects, to get the return type you check MethodInfo.ReturnType and for the parameters call MethodInfo.GetParameters and ParameterInfo.ParameterType
That's only leaves local variables defined inside method bodies and those cannot be accessed with reflections

Declaring a LIST variable of an anonymous type in C#

I'm working with LINQ to SQL with ASP.NET 4 and C#. I've created a LINQ query that results in a new LIST (ie. ToList()). The returned LIST is of an ANONYMOUS type, because it's being created dynamically by the query. I want to be able to declare a variable at the page level in the code behind so I can use it in other functions and also on the front page using '<%= %>'.
Visual Studio tells me that the result is of an anonymous type, but gives me the classes names, for example: {CLASS1, CLASS2}.
How can I declare the variable of this anonymous type?
Anonymous types, by their very nature, can't be explicitly "declared". They're anonymous, unknown; you don't have a type to declare. As such, anonymous types, whether directly or as a generic type parameter, cannot be specified as parameters, used as a return type, or stored to any explicitly typed variable. You must use var to assign them, and that means you're pretty much limited to using the type in local scope.
Your only option, basically, is to convert your anonymous type into a collected type that can be explicitly declared (i.e. you must declare the type itself). Just create a simple DTO class, and before calling ToList, run the anonymous type through a Select() Linq node that uses the anonymous type to initialize your strong class.
If you are using .NET 4.0, you COULD go dynamic. The dynamic keyword, and any object that's been passed through a parameter or return type declared dynamic, basically tells the compiler not to try to verify any operation performed on it; you can try to use any operator, call any method, etc. HOWEVER, if the operator, member, or whatever other operation you are performing isn't valid for what the object actually is behind the scenes, you'll get runtime exceptions which you must handle very robustly. For this reason, the dynamic feature of .NET 4.0 is not to be used lightly.
The only other thing you can do, as Kratz said, is return an ArrayList, or an Object[] array, and use reflection to discover the anonymous type's structure. It's a no-no pretty much any way you slice it; you lose the strong typing of the collection, your code bloats considerably as you need several lines of code to perform even the simplest get or set operations, and reflection, again by its nature, can be up to 100x slower than the equivalent operation on a known static type.
You'll have to declare a type for the result, since there is no way I know of to outright declare an instance of an anonymous type. Even if you store it in a value, you would not be able to use it outside the scope where it was created.
You possible could use reflection to get at the values and just declare the variable as type IList, but that would be much more work than just creating a new type.
You could do a List<Object> and in your code you can test the type like :
if(myList[index].GetType() == typeof(Class1))
{
//put your code for class1
}
else if(myList[index].GetType() == typeof(Class2))
{
//put your code for class2
}

Categories

Resources